简体   繁体   中英

Node.js Stream and child process - Strange Behavior

I have got ac program,which reads integer values from stdin. I wrote a nodejs program to execute the c file, and the nodejs program will read a text file(containg numbers in multiple lines) and pipe this data to stdin of the child process.

The problem is, if the no of inputs in the txt file is less than the expected number then the child process will be supplied with value 0. I want the child process to wait until the data is received.

c program

 #include<stdio.h>
 int main(){
     int a;
     printf("hekllowworls");

     scanf("%d",&a);
     printf("%d",a);

     scanf("%d",&a);
     printf("%d",a);    

     scanf("%d",&a);
     printf("%d",a);
 }

Node JS Program

var fs = require('fs'),
cp = require('child_process');

stream = fs.createReadStream('myfile.txt');
var obj = cp.spawn('/home/arju/Desktop/exec/a.out'); 

stream.pipe(obj.stdin);

obj.stdout.on('data',function(data){
    console.log(data.toString());
});

obj.on('error',function(err){
    console.log(err);
});

TextFile - Myfile.txt

10
20

According to man scanf

   The  value  EOF  is returned if the end of input is reached before either
   the first successful conversion or a matching  failure  occurs.   EOF  is
   also  returned  if a read error occurs, in which case the error indicator
   for the stream (see ferror(3)) is set, and  errno  is  set  indicate  the
   error.

I feel that you should use something like that:

r = scanf("%d",&a);
if (r != EOF) { ...

Logically, simple wait for data could look like this:

while(r = scanf("%d",&a)) {
    if (r == EOF) continue;
    printf("%d",a);
}

EDIT

As i understand, you should use unbuffered IO operations, like read/write syscals. Try this:

int main(){

    int n;
    char buf[255];

    while(1) {

        while((n = read(0,buf,sizeof(buf))) != 0){
            write(1,buf,n);
        }

    }
}

Get the info from: write() to stdout and printf output not interleaved? , good answer, check it out.

Your C program reads value from buffer. In my first example it awaits data to fill the output buffer, so i had no output.

EDIT 2: How to turn the buffer off

With small modifications of code, you can use fflush(stdout) after each printf call.

If you can't edit the code, take a look at this answer from unix.stackexchange: https://unix.stackexchange.com/questions/25372/turn-off-buffering-in-pipe , there are two good solutions. (i'd prefer the second, because it is from coreutils).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM