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.comdbrooks@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."