Created
April 3, 2012 17:43
-
-
Save isaacs/2294039 to your computer and use it in GitHub Desktop.
Revisions
-
isaacs revised this gist
Apr 6, 2012 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -24,7 +24,7 @@ index corresponds to a fd in the child. The value is one of the following: Setting this option enables the ChildProcess.send() method. If the child writes JSON messages to this file descriptor, then this will trigger ChildProcess.on('message'). If the child is a Node.js program, then the presence of an IPC channel will enable process.send() and process.on('message') 5. positive integer - call tty_wrap.guessHandleType. Create the appropriate pipe_wrap type of thing for this. Note that this will generally not -
isaacs revised this gist
Apr 6, 2012 . No changes.There are no files selected for viewing
-
isaacs revised this gist
Apr 6, 2012 . 1 changed file with 17 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -70,6 +70,7 @@ child_process.js: * `ipc` {Boolean} Default=false * `readable` {Boolean} Default=true * `writable` {Boolean} Default=true * return: Pipe stream object By default, all created pipes are duplex. The readable/writable aspect is only set at the JavaScript layer to help prevent doing the wrong sort of @@ -78,7 +79,22 @@ stream.pipe(). At the low-level, there is no special half-duplex behavior. IPC is only enabled if explicitly requested, usually by setting 'ipc' as one of the stdio FD options. The return object is a Stream object. It has a "remote" member which is an opaque object representing the other end of the pipe pair, and is actually used by spawn. Example: ```javascript var p = createPipe() var c = spawn(cmd, args, { stdio: [ p ] }) p === c.stdin p.on('data', function (chunk) { console.error('c.stdin emitted data', chunk) }) ``` ## Exposure on the ChildProcess object. The stdin/stdout/stderr members will be set to a Stream object if set to `pipe`, or null otherwise. -
isaacs revised this gist
Apr 5, 2012 . 1 changed file with 14 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -64,7 +64,7 @@ child_process.js: * createPipe() should be blessed as a public API so that users can create arbitrary duplex streams for stdio. ## createPipe([options]) * `options` {Object} * `ipc` {Boolean} Default=false @@ -78,6 +78,19 @@ stream.pipe(). At the low-level, there is no special half-duplex behavior. IPC is only enabled if explicitly requested, usually by setting 'ipc' as one of the stdio FD options. ## Exposure on the ChildProcess object.b The stdin/stdout/stderr members will be set to a Stream object if set to `pipe`, or null otherwise. If an `ipc` channel was requested, then the ChildProcess object will have a `send(msg)` method, and will perhaps `emit('message', obj)` if the child writes JSON to that channel. Other stdio fds will be exposed on the `stdio` member. ChildProcess.stdio is an Array corresponding to the file descriptors opened in the child. child.stdio[0] === child.stdin, child.stdio[2] === child.stderr, etc. */ // Examples -
isaacs revised this gist
Apr 5, 2012 . 1 changed file with 49 additions and 17 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -15,41 +15,69 @@ The 'stdio' option to child_process.spawn() is an array where each index corresponds to a fd in the child. The value is one of the following: 1. `null` or `undefined` - Use the default value. For 0,1,2, this is the same as 'pipe'. For any higher value, 'ignore' 2. 'ignore' - Open the fd in the child, and /dev/null it 3. 'pipe' - Create a new dup2 pipe, and expose a stream object to JS. 4. 'ipc' - The same as 'pipe', but set up to send/receive IPC messages and pass server/socket/FD handles for use with cluster. Note: A ChildProcess may have at most *one* IPC stdio file descriptor. Setting this option enables the ChildProcess.send() method. If the child writes JSON messages to this file descriptor, then this will trigger ChildProcess.on('message'). If the child is a Node.js program, then the presents of an IPC channel will enable process.send() and process.on('message') 5. positive integer - call tty_wrap.guessHandleType. Create the appropriate pipe_wrap type of thing for this. Note that this will generally not be a portable way to share a socket with the child process as a stdio fd. 6. Any HandleWrap object - If the object is a HandleWrap object, then the underlying TCP, Pipe, or File handle is shared with the child process. 7. Any {handle:<instanceof HandleWrap>} object - If the object has a `handle` member which is a HandleWrap object of some sort, then treat this as #5. 8. Any {fd:<positive integer>} object - If the object has an ingeter `fd` member, then treat this as #4. 9. Any negative integer: The same as 'pipe' (Backwards compatibility with customFds.) 10. Anything else: throw. As a shorthand, the `stdio` argument may also be one of the following strings, rather than an array: * `ignore` --> ['ignore', 'ignore', 'ignore'] * `pipe` --> ['pipe', 'pipe', 'pipe'] == [-1,-1,-1] * `inherit` --> [process.stdin, process.stdout, process.stderr] == [0,1,2] Defaults: * `spawn`, `exec`, `execFile` --> ['pipe', 'pipe', 'pipe'] * `fork` --> ['ipc', 'pipe', 'pipe'] or ['ipc', 'ignore', 'ignore'] if { silent: true } Since cluster just uses child_process.fork, it'll use the same defaults. This will require a bit of refactoring in other parts of node besides child_process.js: * TCP and TTY sockets have a "handle" member added and exposed explicitly. * createPipe() should be blessed as a public API so that users can create arbitrary duplex streams for stdio. function createPipe([options]) * `options` {Object} * `ipc` {Boolean} Default=false * `readable` {Boolean} Default=true * `writable` {Boolean} Default=true By default, all created pipes are duplex. The readable/writable aspect is only set at the JavaScript layer to help prevent doing the wrong sort of stream.pipe(). At the low-level, there is no special half-duplex behavior. IPC is only enabled if explicitly requested, usually by setting 'ipc' as one of the stdio FD options. */ // Examples @@ -58,15 +86,15 @@ child_process.js: spawn(cmd, args, { stdio: 'inherit' }) // 2. spawn a child, sharing only stderr spawn(cmd, args, { stdio: ['pipe', 'pipe', process.stderr] }) // 3. since integer FDs will be inspected and set up appropriately, // customFds-style will continue to work without modification spawn(cmd, args, { stdio: [-1, -1, 2] }) // 4. Open an extra fd=4, to interact with programs present a // startd-style interface. spawn(cmd, args, { stdio: ['pipe', 'ignore', 'ignore', null, 'pipe'] }) // 5. Provide a socket as the stdin and stdio to a child, // to interact with programs that present a cgi-style interface @@ -83,20 +111,24 @@ fs.open('error.log', function (er, fd) { }) // 7. like child_process.fork() spawn(cmd, args, { stdio: [ 'ipc', 1, 2 ] }) // 7a. like child_process.fork(..., {silent: true}) spawn(cmd, args, { stdio: [ 'ipc', 'ignore', 'ignore' ] }) // 8. interact with some silly unix utility that uses a bunch of weird // stdio stuff. // // * stdin is a pipe // * stdout is a JS stream object // * stderr is mapped to the parent's stdout // * fd=3 is a JS stream object // * fd=4 is ignored // * fd=5 is the parent's stdin (eg, for the user to type in a pass phrase) // * fd=6 writes to an error log // * fd=7 can receive file descriptors and handles. var rw = createPipe() var ipc = createPipe({ipc: true}) fs.open("log.txt", function (er, fd) { if (er) throw er spawn(cmd, args, { stdio: [ rw, 'pipe', process.stdout, 'pipe', null, 0, fd, ipc ] }) }) -
isaacs created this gist
Apr 3, 2012 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,102 @@ /* In a child process, each of the stdio streams may be set to one of the following: 1. A new file descriptor in the child, dup2'ed to the parent and exposed to JS as a Stream object. 2. A copy of a file descriptor from the parent, with no other added magical stuff. 3. A black hole - no pipe created. The trouble with using raw file descriptor integers for this is that they are not portable to Windows. The 'stdio' option to child_process.spawn() is an array where each index corresponds to a fd in the child. The value is one of the following: 1. `null` or `undefined` - Use the default value. For 0,1,2, this is the same as 'stream'. For any higher value, 'ignore' 2. 'ignore' - Open the fd in the child, and /dev/null it 3. 'stream' - Create a new dup2 pipe, and expose a stream object to JS. The read/write-ability of the stream will be set based on the FD. 0=read-only, 1,2=write-only, >2=read/write. If a different read/write setting is desired, then open a HandleWrap object explicitly. 4. positive integer - call tty_wrap.guessHandleType. Create the appropriate pipe_wrap type of thing for this. Note that this will generally not be a portable way to share a socket with the child process as a stdio fd. 5. Any HandleWrap object - If the object is a HandleWrap object, then the underlying TCP, Pipe, or File handle is shared with the child process. 6. Any {handle:<instanceof HandleWrap>} object - If the object has a `handle` member which is a HandleWrap object of some sort, then treat this as #5. 7. Any {fd:<positive integer>} object - If the object has an ingeter `fd` member, then treat this as #4. 8. Any negative integer: The same as 'stream' (Backwards compatibility with customFds.) As a shorthand, the `stdio` argument may also be one of the following strings, rather than an array: * `ignore` --> ['ignore', 'ignore', 'ignore'] * `stream` --> ['stream', 'stream', 'stream'] == [-1,-1,-1] * `inherit` --> [process.stdin, process.stdout, process.stderr] == [0,1,2] This will require a bit of refactoring in other parts of node besides child_process.js: * TCP and TTY sockets have a "handle" member added and exposed explicitly. * createPipe() should be blessed as a public API so that users can create arbitrary duplex streams for stdio. */ // Examples // 1. spawn a child, taking over the parent's terminal. spawn(cmd, args, { stdio: 'inherit' }) // 2. spawn a child, sharing only stderr spawn(cmd, args, { stdio: ['stream', 'stream', process.stderr] }) // 3. since integer FDs will be inspected and set up appropriately, // customFds-style will continue to work without modification spawn(cmd, args, { stdio: [-1, -1, 2] }) // 4. Open an extra fd=4, to interact with programs present a // startd-style interface. spawn(cmd, args, { stdio: ['stream', 'ignore', 'ignore', null, 'stream'] }) // 5. Provide a socket as the stdin and stdio to a child, // to interact with programs that present a cgi-style interface net.createServer(function (conn) { spawn(cmd, args, { stdio: [ conn, conn, process.stderr ] }) }).listen(80) // 6. Same as #5, but log stderr to a file: fs.open('error.log', function (er, fd) { if (er) throw er net.createServer(function (conn) { spawn(cmd, args, { stdio: [ conn, conn, fd ] }) }).listen(80) }) // 7. like child_process.fork() spawn(cmd, args, { stdio: [ 'stream', 1, 2, 'stream' ] }) // 8. interact with some silly unix utility that uses a bunch of weird // stdio stuff. // // * stdin is readable and writable // * stdout is a JS stream object // * stderr is mapped to the parent's stdout // * fd=3 is a JS stream object // * fd=4 is ignored // * fd=5 is the parent's stdin (eg, for the user to type in a pass phrase) // * fd=6 is a error log var rw = createPipe() fs.open("log.txt", function (er, fd) { if (er) throw er spawn(cmd, args, { stdio: [ rw, 'stream', process.stdout, 'stream', null, 0, fd ] }) })