简体   繁体   中英

Writing a typed array to a subprocess stdin isn't working correctly

I'm sending some data to a subprocess's stdin. The data comes from a typed array. If the Data from the typed array is changed, sending to the subprocess is truncated. I've a small example showing this problem.

The Subprocess is a simple C++ App. Reading all Data from stdin and output the number of read bytes to stdout. (C++ App is compiled with x86_64-w64-mingw32-g++ test.cpp) Code Of the Subprocess in c++:

#include <iostream>
#include <limits>

int main(int argc, char **args) {
  std::cin.ignore(std::numeric_limits<std::streamsize>::max());
  std::cout << std::cin.gcount() << std::flush;
  return 0;
}

The nodejs App will call cyclic the exe. Passes 128 Bytes of Data to the stdin and checks if the response (from stdout of the childprocess) is the String "128". Code of the nodejs App:

const execFile = require('child_process').execFile;

var data = new Float64Array(16);

var generateError = true;
generateError && setInterval(_ => {
  for (var i = 0; i < 16; i++) {
    data[i] = Math.random();
  }
}, 1);

setInterval(_ => {
  var subproc = execFile('a.exe', [ '-c' ], (error, stdout, stderr) => {
    if (stdout.trim() !== '128' || error) {
      console.log('ERR: ' + stdout);
    } else {
      console.log('OK');
    }
  });
  subproc.stdin.write(Buffer.from(data.buffer)) || console.log('Use drain'); // Write Binary Data (128Byte)
  subproc.stdin.end();
}, 100);

This gives me some output like:

OK
OK
OK
OK
OK
OK
ERR: 69
ERR: 114
OK
OK
OK
ERR: 41

What makes me crazy:

  • When I set the generateError to false, everything works as expected.
  • When I use " wc.exe -c " (Word/Bytecount Tool from cgywin) everything works as expected, even when generateError is set to true.

So the Question: Whats wrong? C++ Code? Node Code? Is it not allowed to change the buffer after passing it to subproc.stdin.write ? If not allowed: Why works the variant with wc.exe?

Under Windows there are different type of streams: binary streams and some sorts of text streams. Changing the input stream of the c++ App to a binary stream will solve the problem. (I guess that wc.exe will use the input stream as a binary stream. This would explain why the variant with wc.exe is working):

#include <iostream>
#include <limits>

#include <fcntl.h>
#include <io.h>
int main(int argc, char **args) {
  _setmode(_fileno(stdin), _O_BINARY);

  std::cin.ignore(std::numeric_limits<std::streamsize>::max());
  std::cout << std::cin.gcount() << std::flush;
  return 0;
}

See also Read binary data from std::cin

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