mrabin@ADS.COM (Marla Rabin) (03/07/91)
I'd like to be able to capture the stdout and stderr of some system calls that I use (fork and exec), and print this output in my main scrolling text window. Douglas Young has an example of something like this in his The X Window System Programming and Applications with Xt, OSF/MOTIF edition. (The xbc example, pages 156-166 in my edition). However, when I make a few changes to his routines, they don't work for me. The fork and exec runs the system call, but the stdout output goes into never-never land. (I've put off redirecting stderr for now for debugging purposes). Also, the routine that is supposed to be called when anything appears in stdin (get_from_input below) never seems to get called (I think this because inside that routine I write something to stderr, and I never see that output when I run the program). I'm hoping someone out there can spot my error(s) and help me solve this! Any help or suggestions would be greatly appreciated! I'm using Motif 1.1, X11R4, Sparcstation 1, SunOS Release 4.1.1 Code details: In main, before realizing and main-looping I have the line: XtAddInput(fileno(stdin), XtInputReadMask, get_from_input, mainText); where get_from_input is: void get_from_input(w, fid, id) Widget w; int *fid; XtInputId *id; { char buf[BUFSIZ]; int nbytes, i; extern void printToMain(); fprintf(stderr, "in get\n"); nbytes = read(*fid, buf, BUFSIZ); if (nbytes) { buf[nbytes] = '\0'; printToMain(buf); } } The function that I'm using to run the system command is: void runCmd(cmd) char *cmd; { int to_parent[2]; int pid, status; pipe(to_parent); if (pid = fork(), pid == 0) { /* in the child */ const char *shell = (char *) getenv("SHELL"); if (shell == NULL) shell = "/bin/sh"; close(1); dup(to_parent[1]); /* redirect stdout */ close(to_parent[0]); close(to_parent[1]); execl(shell, shell, "-c", cmd, NULL); exit(1); } else if (pid > 0) { /* in the parent */ close(0); dup(to_parent[0]); /* redirect stdin */ close(to_parent[0]); close(to_parent[1]); wait(&status); } else { /* error! */ fprintf(stderr, "Couldn't fork process %s\n", cmd); exit(1); } } Thanks in advance, --marla mrabin@ads.com
dbrooks@osf.org (03/07/91)
mrabin@ADS.COM (Marla Rabin) writes: |> In main, before realizing and main-looping I have the line: |> XtAddInput(fileno(stdin), XtInputReadMask, get_from_input, mainText); |> |> where get_from_input is: |> |> void |> get_from_input(w, fid, id) |> Widget w; |> int *fid; |> XtInputId *id; |> { |> char buf[BUFSIZ]; |> int nbytes, i; |> |> extern void printToMain(); |> |> fprintf(stderr, "in get\n"); |> nbytes = read(*fid, buf, BUFSIZ); ^^^^^^ Assuming the writer hasn't closed the pipe, this will block until enough data is shoved across. You'll have to do whatever SunOS offers to perform a nonblocking read. (Anyway, that's what occurred to me straight away. I haven't looked too closely at the mess of dup and close calls...) -- David Brooks dbrooks@osf.org Systems Engineering, OSF uunet!osf.org!dbrooks "It's not easy, but it is simple."