mroz@eplrx7.uucp (Peter Mroz) (08/16/90)
I'm having a problem with popen sending back buffered output. I am in the process of writing a program to display vmstat output using curses. However, when I issue the command vin = popen("vmstat 2","r"); I can't read anything with fgets until some internal buffer is filled. I tried running the same program on a Sun and it works just fine. Any suggestions would be appreciated. On the IBM RS/6000 the following program doesn't send back any vmstat output until 30 seconds have passed. On the Sun it sends output back every second, like I thought it would. /* testp.c */ #include <stdio.h> #include <signal.h> char *progname; /* program name for error messages */ main (argc, argv) int argc; char *argv[]; { FILE *vin, *popen(); char *vmstat_cmd = "vmstat 1 30"; char input_line[BUFSIZ]; progname = argv[0]; if ((vin = popen(vmstat_cmd, "r")) == NULL) { fprintf(stderr, "%s: can't run %s\n", progname, vmstat_cmd); exit(1); } printf("\nOK. Pipe initialized \n"); fgets(input_line, sizeof input_line, vin); printf("%s", input_line); while (fgets(input_line, sizeof input_line, vin) != NULL) { printf("%s", input_line); } } -- Peter Mroz | E.I. Du Pont de Nemours & Co. eplrx7!mroz@uunet.uu.net | Consultant, Scicon mrozpa%wmvx@dupont.com | DuPont Building, D4078 | Wilmington, DE 19898 -- The UUCP Mailer
dcm@toysrus.uucp (dcm) (08/16/90)
In article <1990Aug15.203239.8832@eplrx7.uucp> mroz@eplrx7.uucp (Peter Mroz) writes: >I'm having a problem with popen sending back buffered output. I am in the >process of writing a program to display vmstat output using curses. However, >when I issue the command > > vin = popen("vmstat 2","r"); > >I can't read anything with fgets until some internal buffer is filled. I >tried running the same program on a Sun and it works just fine. Any suggestions >would be appreciated. Actually, vmstat is not fflush'ing after each iteration. "To be fixed in a future update". (luckily enough, I'm working on another vmstat bug right now, so I'll just sneak the fflush back in where Berkeley had it originally) Thanks... Craig Miller, AIXV3 Change Team, Austin -------- Craig Miller, contractor @ IBM AWD, Austin UUCP: ..!uunet!cs.utexas.edu!ibmaus!auschs!toysrus.austin.ibm.com!dcm "Just because it works doesn't means it's right, stupid!" "You should never install code you do not understand." "If you knowningly install broken code, you should be shot. Period." "Programmers have to be accountable for their code."
madd@world.std.com (jim frost) (08/23/90)
mroz@eplrx7.uucp (Peter Mroz) writes: >I'm having a problem with popen sending back buffered output. There is a general problem with many utilities when their output is piped or redirected where output will be buffered unexpectedly. For kicks sometime, try redirecting a make that contains multiple files with errors to a file. You'll get all the errors from cc, followed by all the "cc" lines from make. Make appears to buffer its output until termination. This also happens when piping to a pager. The problem with this is that xlc doesn't emit information about which file it's compiling so it's impossible to deterimine which files the errors came from unless the cc lines are emitted before the errors. The only way I could work around this problem was to use "script" (which, thank God, does exist on the rios) to record make output. This problem exists under 9021F. I haven't tried it with the 3001 update applied. A note to whomever in IBM does compiler output: the default error output of the compiler is the worst I've ever seen. It's usually ambiguous as to which file generated the error. Try the following: -- foo.h -- /* header file that contains an error */ int i j; -- foo.c -- #include "foo.h" main() { int i j; } -- end -- It's largely guesswork to find which file the error came from since there is no obvious indication of where foo.h's errors stop and foo.c's begin. Another fun one: -- cut here -- % touch foo.h % cat >foo.c #include foo.h main() { printf("hello world\n"); } ^D % cc foo.c -- cut here -- Cc will tell you that an include file is empty but it shows the line from foo.c, which is blank. It took me awhile to figure out exactly what it was talking about since when I ran across this one the include file was within another include file and (as I said before) it's hard to tell which file generated any particular error. The error reporting done by xlc is fine if you're perusing a compiler listing (eg using -qsource) but: * generating the source listing isn't the default * nobody wants to look through the entire source of their 160,000 line program to find their errors. Those kinds of error messages were exceptable when you were dealing with a 5,000 line RPG program, but we're in the real world now with real world sized projects. I don't have the time to look through more than a quarter million lines of compiler output to find my errors, and the default output is next to useless. The cute little character pointers under the source line are only mildly useful. What I really want is to be able to easily tell which file and line my error was on. A simple "file.c, line 9: syntax error" is much less ambiguous! Someone please take heed and fix this problem or at least give the option to produce more-or-less standard cc error messages that can be parsed by human beings reliably. Right now it's virtually useless. jim frost saber software jimf@saber.com
markus@cernvax.UUCP (markus baertschi) (08/23/90)
In <1990Aug23.133020.11170@world.std.com> madd@world.std.com (jim frost) writes: >There is a general problem with many utilities when their output is >piped or redirected where output will be buffered unexpectedly. >For kicks sometime, try redirecting a make that contains multiple >files with errors to a file. You'll get all the errors from cc, >followed by all the "cc" lines from make. Make appears to buffer its >output until termination. This also happens when piping to a pager. Jim, The solution for your redirection problem is quite easy. I suspect you used a construct like make >logfile 2>logfile which behaves exactly like you said. If you change it slightly to make >logfile 2>&1 suddenly the contents of the file will look like the output to the console with error & stdout output mixed. Why ? '2>&1' just redirects stderr to the same file as stdout (before buffering is done). Markus -- Markus Baertschi | markus@cernvm.cern.ch CERN (European Particle Research Center) Geneva, Switzerland