Skip to content

Commit 112b92b

Browse files
author
Hood
committed
Fix duplication syscalls so that they handle pipes correctly
1 parent d35de0b commit 112b92b

File tree

2 files changed

+46
-11
lines changed

2 files changed

+46
-11
lines changed

Diff for: src/library_syscall.js

+13-10
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,13 @@ var SyscallsLibrary = {
137137
}
138138
return 0;
139139
},
140-
doDup: function(path, flags, suggestFD) {
141-
var suggest = FS.getStream(suggestFD);
142-
if (suggest) FS.close(suggest);
143-
return FS.open(path, flags, 0, suggestFD, suggestFD).fd;
140+
doDup: function(stream, minFD, maxFD) {
141+
if(stream.path.startsWith("pipe[")){
142+
// A pipe
143+
stream.node.pipe.refcnt++;
144+
return FS.createStream(stream, minFD, maxFD).fd;
145+
}
146+
return FS.open(stream.path, stream.flags, 0, minFD, maxFD).fd;
144147
},
145148
doReadv: function(stream, iov, iovcnt, offset) {
146149
var ret = 0;
@@ -374,7 +377,7 @@ var SyscallsLibrary = {
374377
},
375378
__sys_dup: function(fd) {
376379
var old = SYSCALLS.getStreamFromFD(fd);
377-
return FS.open(old.path, old.flags, 0).fd;
380+
return SYSCALLS.doDup(old);
378381
},
379382
__sys_pipe__deps: ['$PIPEFS'],
380383
__sys_pipe: function(fdPtr) {
@@ -461,7 +464,8 @@ var SyscallsLibrary = {
461464
__sys_dup2: function(oldfd, suggestFD) {
462465
var old = SYSCALLS.getStreamFromFD(oldfd);
463466
if (old.fd === suggestFD) return suggestFD;
464-
return SYSCALLS.doDup(old.path, old.flags, suggestFD);
467+
FS.closeStream(suggestFD);
468+
return SYSCALLS.doDup(old, suggestFD, suggestFD);
465469
},
466470
__sys_getppid__nothrow: true,
467471
__sys_getppid__proxy: false,
@@ -1107,9 +1111,7 @@ var SyscallsLibrary = {
11071111
if (arg < 0) {
11081112
return -{{{ cDefine('EINVAL') }}};
11091113
}
1110-
var newStream;
1111-
newStream = FS.open(stream.path, stream.flags, 0, arg);
1112-
return newStream.fd;
1114+
return SYSCALLS.doDup(stream, arg);
11131115
}
11141116
case {{{ cDefine('F_GETFD') }}}:
11151117
case {{{ cDefine('F_SETFD') }}}:
@@ -1329,7 +1331,8 @@ var SyscallsLibrary = {
13291331
assert(!flags);
13301332
#endif
13311333
if (old.fd === suggestFD) return -{{{ cDefine('EINVAL') }}};
1332-
return SYSCALLS.doDup(old.path, old.flags, suggestFD);
1334+
FS.closeStream(suggestFD);
1335+
return SYSCALLS.doDup(old, suggestFD, suggestFD);
13331336
},
13341337

13351338
__sys_prlimit64: function(pid, resource, new_limit, old_limit) {

Diff for: tests/unistd/pipe.c

+33-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <assert.h>
1414
#include <string.h>
1515
#include <stdio.h>
16+
#include "emscripten.h"
1617

1718
unsigned char buf[1 << 16];
1819

@@ -136,9 +137,10 @@ int main()
136137
test_read (fd[0], &rchar, 10);
137138
test_poll(fd, FALSE);
138139

140+
// Test closing pipes.
141+
139142
// Clear buffer
140143
memset(buf, 0, sizeof(buf));
141-
// Test closing pipes.
142144
// Write to pipe
143145
assert(write(fd[1], "XXXX", 4) == 4);
144146
// Close write end
@@ -160,6 +162,36 @@ int main()
160162
// The error number is EBADF
161163
assert(errno == EBADF);
162164

165+
166+
// Test copying pipes.
167+
// Clear buffer
168+
memset(buf, 0, sizeof(buf));
169+
// We closed last pipe so make new one
170+
assert(pipe(fd) == 0);
171+
int fdr = dup(fd[0]);
172+
int fdw = fcntl(fd[1], F_DUPFD, 7);
173+
// Write to pipe
174+
assert(write(fd[1], "XXXX", 4) == 4);
175+
// close write end
176+
assert(close(fd[1]) == 0);
177+
// This write should fail
178+
assert(write(fd[1], "YYYY", 4) == -1);
179+
// The error number is EBADF
180+
assert(errno == EBADF);
181+
// Read from duped read end
182+
assert(read(fdr, buf, 5) == 4);
183+
assert(memcmp(buf, "XXXX", 4) == 0);
184+
assert(close(fdr) == 0);
185+
assert(write(fdw, "YYYY", 4) == 4);
186+
assert(close(fdw) == 0);
187+
// This write should fail
188+
assert(write(fdw, "YYYY", 4) == -1);
189+
// The error number is EBADF
190+
assert(errno == EBADF);
191+
assert(read(fd[0], buf, 5) == 4);
192+
assert(memcmp(buf, "YYYY", 5) == 0);
193+
assert(close(fd[0]) == 0);
194+
163195
puts("success");
164196

165197
return 0;

0 commit comments

Comments
 (0)