Path: utzoo!attcan!uunet!ns-mx!ceres!deimos.cis.ksu.edu!rutgers!ucsd!ucbvax!bloom-beacon!ITSTD.SRI.COM!wohler From: wohler@ITSTD.SRI.COM (Bill Wohler) Newsgroups: comp.windows.x Subject: Re: redirecting stderr; passing arg lists Message-ID: <8911281121.AA07183@milkfs.itstd.sri.com> Date: 28 Nov 89 11:21:13 GMT References: <8911081827.AA12003@turnpike.sun.com> Sender: root@athena.mit.edu (Wizard A. Root) Organization: SRI International, Heidelberg, W. Germany Lines: 68 dan, thanks to you and ted nolan for helping me with my problem. the reason i didn't reply sooner is that i had to do a bit of hacking to your solution. to snarf stderr, i piped and dupped as you said. i also found that things worked better to make the pipes unbuffered since a newline was not always in the error messages. to check if there was any input to read in stderr, you suggested: ioctl(stderr_pipe[0], FIONREAD, &stuff_to_read); If (stuff_to_read == 0), then return. NOTE: you should do that in the callback routine specified in XtAddInput anyway! This is what Xt should be doing before it decides to call your callback routine (which is why it's "broken"). this works great on my sun. however, the x folks would not want to put this in their toolkit since the FIONREAD is documented not to support pipes in hpux and it is also documented not to be implemented at all on the 300 series (woe is me!) alternatively, i tried select, except that select still said that there was stuff in the input buffer after my read! so that was of no use (unless someone can explain why this was so). my final solution was to use a non-blocking read. appears to work great. how inefficient or ugly is this? here are the code fragments that work on both my sun (os 3.4) and hp (hp9000s300, os 6.2). dan, guess i still owe you a couple of bottles of weizen or so. ;-) static dbat_errinit() { int stderr_pipe[2]; /* maybe needs to be static? */ extern int dbat_errdisp(); (void)pipe(stderr_pipe); (void)dup2(stderr_pipe[1], fileno(stderr)); (void)fcntl(stderr_pipe[0], F_SETFL, O_NDELAY); setbuf(stderr, NULL); XtAddTimeOut(ERRDISP_UPDATE*MSECPERSEC, dbat_errdisp, stderr_pipe[0]); } static dbat_errdisp(client_data, id) caddr_t client_data; XtIntervalId *id; { int fd = (int)client_data; register int chrs; char buf[BUFSIZ]; extern int dbat_errdisp(); buf[0] = '\0'; chrs = read(fd, buf, sizeof(buf)); if (buf[0]) { buf[chrs] = '\0'; XwTextInsert(Errors, buf); } XtAddTimeOut(ERRDISP_UPDATE*MSECPERSEC, dbat_errdisp, fd); }