Friday 29 October 2021

NodeJS child_process stdout, if process is waiting for stdin

I'm working on an application, which allows to compile and execute code given over an api.

The binary I want to execute is saved as input_c and should print a text, asking the user for his name and print out another text after the input is received.

It correctly works using the code below: first text - input (on terminal) - second text.

const {spawn} = require('child_process');
let cmd = spawn('input_c', [], {stdio: [process.stdin, process.stdout, process.stderr]});

Output:

$ node test.js
Hello, what is your name? Heinz
Hi Heinz, nice to meet you!

I like to handle stdout, stderr and stdin seperately and not write it to the terminal. The following code was my attempt to achieve the same behaviour as above:

const {spawn} = require('child_process');

let cmd = spawn('input_c');

cmd.stdout.on('data', data => {
    console.log(data.toString());
});

cmd.stderr.on('data', data => {
    console.log(data.toString());
});

cmd.on('error', data => {
    console.log(data.toString());
});

// simulating user input
setTimeout(function() {
    console.log('Heinz');
    cmd.stdin.write('Heinz\n');
}, 3000);

Output:

$ node test.js
Heinz
Hello, what is your name? Hi Heinz, nice to meet you!

To simulate user input I'm writing to stdin after 3000ms. But here I'm not receiving the first data in stdout directly on run, it seems to wait for stdin and outputs everything at once.

How can I achieve the same behaviour for my second case?

The following C-Code was used to compile the binary, but any application waiting for user input can be used for this:

#include <stdio.h>

int main() {
    char name[32];
    printf("Hello, what is your name? ");
    scanf("%s", name);
    printf("Hi %s, nice to meet you!", name);
    return 0;
}


from NodeJS child_process stdout, if process is waiting for stdin

No comments:

Post a Comment