change spawn() api to allow using existing streams for stdio

This commit also adds support for this api on Unix.
This commit is contained in:
Fedor Indutny 2012-05-31 17:50:28 +04:00 committed by Bert Belder
parent 528123ad9a
commit f5b5127db0
4 changed files with 43 additions and 35 deletions

View File

@ -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 {

View File

@ -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;
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;
}
if (fd == -1) {
errno = EINVAL;
return -1;
}
fds[writable ? 1 : 0] = fd;
return 0;
default:
assert(0 && "Unexpected flags");
return -1;
}
return uv__make_socketpair(fds, 0);
} else if (container->flags & UV_RAW_FD) {
if (container->data.fd == -1) {
errno = EINVAL;
return -1;
}
if (writable) {
fds[1] = container->data.fd;
} else {
fds[0] = container->data.fd;
}
return 0;
} else {
assert(0 && "Unexpected flags");
return -1;
}
}

View File

@ -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;

View File

@ -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;