title: How to send to stdin and receive from stdout of C program from Node.js?
body: <p>A colleague and I need to interface his C program and my Node.js script. I'm attempting to prove the concept of using stdio to pass messages between the two and so far, the concept isn't proven! The node script starts the executable as a child process on initialisation but then fails to send or receive data. </p>
  
  <p>I have written a very simple C program that echos to stdout whatever it receives on stdin. I'm not a C programmer so hopefully I haven't done anything too shocking in 16 lines :p :</p>
  
  <p><strong>stream_echo.c:</strong></p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;stdlib.h&gt;
  
  #define BUFFER_SIZE 255
  
  int main(void) {
  
      char * buffer = calloc(BUFFER_SIZE, 1);
  
      while(fgets(buffer, BUFFER_SIZE, stdin) != NULL) {
  
          //Echo back on stdout:
          fprintf(stdout, "echo: %s", buffer);
      }
  }
  </code></pre>
  
  <p>And testing in the console shows it working as expected:
  <a href="https://i.stack.imgur.com/8RAGw.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/8RAGw.png" alt="stream_echo.c running in terminal window"></a></p>
  
  <p>The node.js script that calls this executable is as follows:</p>
  
  <p><strong>child_stdio.js</strong></p>
  
  <pre><code>(function() {
      "use strict";
  
      var jcp = require("child_process").spawn("./stream_echo", [], {
              detached: false,
              stdio: "pipe"
          }),
  
          counter = 0,
  
          timer,
  
          sendData = function() {
              console.log("In sendData. Connected: " + jcp.connected);
  
              counter += 1;
              jcp.stdin.write("This is data " + counter + "\r\n");
  
              timer = setTimeout(sendData, 2000);
          };
  
  
      //******** STDIN ********
      jcp.stdin.on("close", (data) =&gt; {
          console.log("stdin closed.");
          if (timer) {
              clearTimeout(timer);
          }
      });
  
  
      //******** STDOUT ********
      jcp.stdout.on("data", (data) =&gt; {
          console.log("stdout: " + data);
      });
  
      jcp.stdout.on("close", (data) =&gt; {
          console.log("stdout closed.");
      });
  
  
      //******** STDERR ********
      jcp.stderr.on("data", (data) =&gt; {
          console.log("stderr: " + data);
      });
  
      jcp.stderr.on("close", (data) =&gt; {
          console.log("stderr closed.");
      });
  
  
      //******** PROCESS ********
      jcp.on("close", (code, signal) =&gt; {
          console.log("Child process closed.\nCode: " + code + "\nSignal: " + signal);
      });
  
      jcp.on("exit", (code, signal) =&gt; {
          console.log("Child process exited.\nCode: " + code + "\nSignal: " + signal);
      });
  
      jcp.on("disconnect", () =&gt; {
          console.log("Child process disconnected.");
      });
  
      console.log("jcp.pid: " + jcp.pid);
      console.log("Connected: " + jcp.connected);
      console.log("Calling sendData for the first time....");
      sendData();
  
  }());
  </code></pre>
  
  <p>When I run this script, multiple attempts to send data to the child process are made and no errors are reported (despite the <code>connected</code> property of the process being false) but no messages are received back either. When I kill the child process, the stream close events and process close events are triggered and the script gracefully terminates.</p>
  
  <p><a href="https://i.stack.imgur.com/sNgOp.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/sNgOp.png" alt="Execution of child_stdio.js"></a></p>
  
  <p>I don't understand why <code>connected</code> is false but the close events trigger. I feel this is a major clue.</p>
  
  <p>Can anyone tell me what many hours trawling the Internet cannot?</p>