Discussion:
[nodejs] writing to child subprocess
Tapasweni Pathak
2018-06-16 06:59:19 UTC
Permalink
**Version**: v8.10.0
**Platform**: Darwin Tapaswenis-MBP 16.7.0 Darwin Kernel Version 16.7.0:;
root:xnu-3789.73.8~1/RELEASE_X86_64 x86_64


Hi node!

I'm trying to add a string to a child subprocess standard output. I want
this code to work without editing the existing test case of main process.

```js
const child = async (command, options, logger) =>
new Promise((resolve, reject) => {
const start = Date.now();

const child = child_process
.spawn(command, options)
.on('error', (err) => reject(err))
.on('exit', (code, signal) => {
const duration = Date.now() - start;
resolve({ code, signal, duration });
});

child.stdin.write('[some_string]');
child.stdout.pipe(logger.stream());
child.stderr.pipe(logger.stream());
});
```

I started with trying `child.stdout.write`, with
`child.stdout.write('some_string')` **I was able to log some_string** in
the child subprocess output, **but** my test failed with

```bash
events.js:183
throw er; // Unhandled 'error' event
^
Error: write EPIPE
at _errnoException (util.js:992:11)
at WriteWrap.afterWrite [as oncomplete] (net.js:864:14)
```

Now to find out why it is failing I checked if the `EPIPE` is closed for
writing with something like, it wasn't.

```js
process.stdout.on('error', function( err ) {
if (err.code == "EPIPE") {
process.exit(0);
}
});
```

I then logged the properties of `child.stdout` turned out `writable is
false`. Same with `stderr.write` for a child subprocess. Another option to
write to a child subprocess is using `child.stdin`, I logged its properties
but it gave `null`. Fine, but I was able to log the string with it.


`child.stdout` properties, I can pipe but can't write as `writable` is
false? I didn't find any info about this
[here](https://nodejs.org/api/child_process.html#child_process_subprocess_stdout).

<details>

```bash
Socket {
connecting: false,
_hadError: false,
_handle:
Pipe {
writeQueueSize: 0,
owner: [Circular],
onread: [Function: onread],
reading: true },
_parent: null,
_host: null,
_readableState:
ReadableState {
objectMode: false,
highWaterMark: 16384,
buffer: BufferList { head: null, tail: null, length: 0 },
length: 0,
pipes: null,
pipesCount: 0,
flowing: null,
ended: false,
endEmitted: false,
reading: true,
sync: false,
needReadable: true,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
destroyed: false,
defaultEncoding: 'utf8',
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: true,
domain: null,
_events:
{ end: { [Function: bound onceWrapper] listener: [Function: onend] },
finish: [Function: onSocketFinish],
_socketEnd: [Function: onSocketEnd],
close: [Function] },
_eventsCount: 4,
_maxListeners: undefined,
_writableState:
WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: false,
needDrain: false,
ending: false,
ended: false,
finished: false,
destroyed: false,
decodeStrings: false,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: false,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 1,
prefinished: false,
errorEmitted: false,
bufferedRequestCount: 0,
corkedRequestsFree:
{ next: null,
entry: null,
finish: [Function: bound onCorkedFinish] } },
writable: false,
allowHalfOpen: false,
_bytesDispatched: 8,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: null,
_server: null,
[Symbol(asyncId)]: 34495,
[Symbol(bytesRead)]: 0 }
```
</details>
Now, after adding child.stdin, in my test for the main process I do
something like

```js
const env = process.env;

process.env = { fake: 'environment' };



sinon.spy(child_process, 'spawn');

sinon.spy(process.stdout, 'write');



try {

await main_process.waitFor();

} catch (err) {

assert.ifError(err, 'failed');

}



const process_data = process.stdout.write.args[0][0];

process.stdout.write.restore();



assert.equal(

process_data,

'[Fri, 09 Feb 2018 21:57:55 GMT] [another_string]
[895ab607-3767-4bbb-bd45-2a3b341cbc46] something\n',
'abcd'
);


```

this `process_data` is the main process data that I get(basically before
adding `.stdin` was able to get the main process logged data. Now for some
reason this has become undefined. Basically when I logged properties of
`process.stdout.write`, args is blank, so it is not fetching the args.

Why writing to `.stdin` on a child subprocess is affecting the
`process.stdout.write` args of main process? What am I missing here? would
appreciate any pointers or even a link if I'm missing something here.

This project I'm working on is open source, can share the whole code if
that helps.
--
Job board: http://jobs.nodejs.org/
New group rules: https://gist.github.com/othiym23/9886289#file-moderation-policy-md
Old group rules: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
---
You received this message because you are subscribed to the Google Groups "nodejs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nodejs+***@googlegroups.com.
To post to this group, send email to ***@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nodejs/0e124e37-7164-4d27-a924-0a65090a04d0%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...