digitalmars.D.learn - non-block reading from pipe stdout
- Oleg B (8/8) Oct 02 2017 Hello. I run program through std.process.pipeShell and want to
- kdevel (8/9) Oct 03 2017 You get EAGAIN because there is no data available at the time of
Hello. I run program through std.process.pipeShell and want to read from it stdout in loop. How do this non-blocking? I try int fd = p.stdout.fileno; int flags = fcntl(fd, F_GETFL, 0); flags |= O_NONBLOCK; fcntl(fd, F_SETFL, flags); but get error "Resource temporarily unavailable".
Oct 02 2017
On Tuesday, 3 October 2017 at 00:22:28 UTC, Oleg B wrote:but get error "Resource temporarily unavailable".You get EAGAIN because there is no data available at the time of reading. From the manpage of read: ERRORS EAGAIN Non-blocking I/O has been selected using O_NONBLOCK and no data was immediately available for reading.
Oct 03 2017
On Tuesday, 3 October 2017 at 10:45:21 UTC, kdevel wrote:On Tuesday, 3 October 2017 at 00:22:28 UTC, Oleg B wrote:And I can't check this without using exception handling?but get error "Resource temporarily unavailable".You get EAGAIN because there is no data available at the time of reading. From the manpage of read: ERRORS EAGAIN Non-blocking I/O has been selected using O_NONBLOCK and no data was immediately available for reading.
Oct 03 2017
On Tuesday, 3 October 2017 at 11:36:28 UTC, Oleg B wrote:Your programm shall not read before data is available. Use core.sys.posix.sys.select to check if read would block on a blocking socket.EAGAIN Non-blocking I/O has been selected using O_NONBLOCK and no data was immediately available for reading.And I can't check this without using exception handling?
Oct 03 2017
On Tuesday, 3 October 2017 at 10:45:21 UTC, kdevel wrote:On Tuesday, 3 October 2017 at 00:22:28 UTC, Oleg B wrote:I found only one way: C-style auto pp = pipeShell(updaterScriptCommand, Redirect.all, null, Config.none, workDir); import core.sys.posix.unistd : read; import core.stdc.errno; import core.sys.posix.fcntl; int fd = pp.stdout.fileno; int flags = fcntl(fd, F_GETFL, 0); flags |= O_NONBLOCK; fcntl(fd, F_SETFL, flags); // C-style setting file config char[256] buf; while (!tryWait(pp.pid).terminated) { auto cnt = read(fd, buf.ptr, buf.length); // C-style reading if (cnt == -1 && errno == EAGAIN) // C-style error checking yield(); else if (cnt > 0) { doSomething(buf[0..cnt]); yield(); } }but get error "Resource temporarily unavailable".You get EAGAIN because there is no data available at the time of reading. From the manpage of read: ERRORS EAGAIN Non-blocking I/O has been selected using O_NONBLOCK and no data was immediately available for reading.
Oct 03 2017
On Tuesday, 3 October 2017 at 12:20:09 UTC, Oleg B wrote:while (!tryWait(pp.pid).terminated) { auto cnt = read(fd, buf.ptr, buf.length); // C-style reading if (cnt == -1 && errno == EAGAIN) // C-style error checking yield(); else if (cnt > 0) { doSomething(buf[0..cnt]); yield(); } }IMHO a program should sleep (consume 0 CPU time and 0 energy) if there is nothing to process. This is best accomplished by not polling on a file descriptor in order to check if data has arrived. If your program must yield() there's probably something wrong with the design. I would suggest you put all the filedescriptors into a fd_set an then select(3) on the set.
Oct 03 2017
On Tuesday, 3 October 2017 at 12:32:43 UTC, kdevel wrote:IMHO a program should sleep (consume 0 CPU time and 0 energy) if there is nothing to process. This is best accomplished by not polling on a file descriptor in order to check if data has arrived. If your program must yield() there's probably something wrong with the design. I would suggest you put all the filedescriptors into a fd_set an then select(3) on the set.Programs based on fibers can't sleep while wait data and it's not a design problem.
Oct 03 2017