Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

Commit

Permalink
change spawn() api to allow using existing streams for stdio
Browse files Browse the repository at this point in the history
This commit also adds support for this api on Unix.
  • Loading branch information
indutny authored and piscisaureus committed Jun 1, 2012
1 parent 528123a commit f5b5127
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 33 deletions.
18 changes: 10 additions & 8 deletions include/uv.h
Expand Up @@ -1165,15 +1165,17 @@ UV_EXTERN void uv_freeaddrinfo(struct addrinfo* ai);

/* uv_spawn() options */
typedef enum {
UV_IGNORE = 0x00,
UV_CREATE_PIPE = 0x01,
/*
* UV_READABLE_PIPE and UV_WRITABLE_PIPE flags are set from
* the child process perspective.
UV_IGNORE = 0x00,
UV_CREATE_PIPE = 0x01,
UV_INHERIT_FD = 0x02,
UV_INHERIT_STREAM = 0x04,

/* When UV_CREATE_PIPE is specified, UV_READABLE_PIPE and UV_WRITABLE_PIPE
* determine the direction of flow, from the child process' perspective. Both
* flags may be specified to create a duplex data stream.
*/
UV_READABLE_PIPE = 0x02,
UV_WRITABLE_PIPE = 0x04,
UV_RAW_FD = 0x08
UV_READABLE_PIPE = 0x10,
UV_WRITABLE_PIPE = 0x20,
} uv_stdio_flags;

typedef struct uv_stdio_container_s {
Expand Down
52 changes: 29 additions & 23 deletions src/unix/process.c
Expand Up @@ -140,33 +140,39 @@ int uv__make_pipe(int fds[2], int flags) {
*/
static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2],
int writable) {
if (container->flags == UV_IGNORE) {
return 0;
} else if (container->flags & UV_CREATE_PIPE) {
assert(container->data.stream != NULL);
int fd = -1;
switch (container->flags & (UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD |
UV_INHERIT_STREAM)) {
case UV_IGNORE:
return 0;
case UV_CREATE_PIPE:
assert(container->data.stream != NULL);

if (container->data.stream->type != UV_NAMED_PIPE) {
errno = EINVAL;
return -1;
}

if (container->data.stream->type != UV_NAMED_PIPE) {
errno = EINVAL;
return -1;
}
return uv__make_socketpair(fds, 0);
case UV_INHERIT_FD:
case UV_INHERIT_STREAM:
if (container->flags & UV_INHERIT_FD) {
fd = container->data.fd;
} else {
fd = container->data.stream->fd;
}

return uv__make_socketpair(fds, 0);
} else if (container->flags & UV_RAW_FD) {
if (container->data.fd == -1) {
errno = EINVAL;
return -1;
}
if (fd == -1) {
errno = EINVAL;
return -1;
}

if (writable) {
fds[1] = container->data.fd;
} else {
fds[0] = container->data.fd;
}
fds[writable ? 1 : 0] = fd;

return 0;
} else {
assert(0 && "Unexpected flags");
return -1;
return 0;
default:
assert(0 && "Unexpected flags");
return -1;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/win/process.c
Expand Up @@ -947,7 +947,7 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
continue;
}

if (options.stdio[i].flags & UV_RAW_FD) {
if (options.stdio[i].flags & UV_INHERIT_FD) {
err = duplicate_fd(loop, options.stdio[i].data.fd, &child_stdio[i]);
} else if (options.stdio[i].data.stream->type == UV_NAMED_PIPE) {
pipe = (uv_pipe_t*)options.stdio[i].data.stream;
Expand Down
2 changes: 1 addition & 1 deletion test/test-spawn.c
Expand Up @@ -221,7 +221,7 @@ TEST_IMPL(spawn_stdout_to_file) {

options.stdio = stdio;
options.stdio[0].flags = UV_IGNORE;
options.stdio[1].flags = UV_RAW_FD;
options.stdio[1].flags = UV_INHERIT_FD;
options.stdio[1].data.fd = file;
options.stdio_count = 2;

Expand Down

0 comments on commit f5b5127

Please sign in to comment.