www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - non-block reading from pipe stdout

reply Oleg B <code.viator gmail.com> writes:
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
parent reply kdevel <kdevel vogtner.de> writes:
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
next sibling parent reply Oleg B <code.viator gmail.com> writes:
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:
 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.
And I can't check this without using exception handling?
Oct 03 2017
parent kdevel <kdevel vogtner.de> writes:
On Tuesday, 3 October 2017 at 11:36:28 UTC, Oleg B wrote:
        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?
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.
Oct 03 2017
prev sibling parent reply Oleg B <code.viator gmail.com> writes:
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:
 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.
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(); } }
Oct 03 2017
parent reply kdevel <kdevel vogtner.de> writes:
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
parent Oleg B <code.viator gmail.com> writes:
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