c++ - piping stockfish misbehaves in fedora -
somewhere in project use fork , pipe execute process , pipe i/o communicate (i'm writing in c++). there no problem when compile in ubuntu 14.04, work fine, compiled in fedora on wmware virtual machine , strange things began happen. if run binary in terminal, there no error nothing written in pipe (but getting streams of characters work). tried debug code in fedora, put break point in code, broken pipe signal given when process tried read pipe (there no signals when executing in terminal). so, have of encountered such problems before? there difference in piping between debian , red hat linux? or because i'm running fedora on virtual machine?
code:
int mfd_p2c [2]; int mfd_c2p [2]; int menginepid; if (pipe(mfd_p2c) != 0 || pipe(mfd_c2p) != 0) { cout << "failed pipe"; exit(1); } menginepid = fork(); if (menginepid < 0) { cout << "fork failed"; exit(-1); } else if (menginepid == 0) { if (dup2(mfd_p2c[0], 0) != 0 || close(mfd_p2c[0]) != 0 || close(mfd_p2c[1]) != 0) { cout << "child: failed set standard input"; exit(1); } if (dup2(mfd_c2p[1], 1) != 1 || close(mfd_c2p[1]) != 0 || close(mfd_c2p[0]) != 0) { cout << "child: failed set standard output"; exit(1); } string engine = "stockfish"; execlp(engine.c_str(), (char *) 0); cout << "failed execute " << engine; exit(1); } else { close(mfd_p2c[0]); close(mfd_c2p[1]); string str = "uci"; int nbytes = str.length(); if (write(mfd_p2c[1], str.c_str(), nbytes) != nbytes) { cout << "parent: short write child"; exit(1); } cout << "the following string has been written engine:\n" << string(1, '\t') << str; char readbuffer[2]; string output = ""; while (1) { int bytes_read = read(mfd_c2p[0], readbuffer, sizeof(char)); if (readbuffer[0] == '\n') break; readbuffer[bytes_read] = '\0'; output += readbuffer; } cout << "got: " << output; }
i see you're using stockfish. have experienced behavior stockfish. problem lies within how handles output. defined in misc.h
:
#define sync_cout std::cout << io_lock
and looking @ code again we'll see io_lock
enum used in overloaded friend operator cout:
std::ostream& operator<<(std::ostream& os, synccout sc) { static mutex m; if (sc == io_lock) m.lock(); if (sc == io_unlock) m.unlock(); return os; }
what see here during using cout, mutex locked. don't know how affects cout's output in pipe instead of stdout, i'm positive cause problem. can check removing lock functionality.
edit: forgot mention pipe behavior not different in linux based systems mentioned before, there might slight differences between distributions handling mutexes used pipes.
Comments
Post a Comment