joe@athena.mit.edu (Joseph C Wang) (06/13/91)
I'd like to use XtAddInput to communicate to and from a separate process.
The code which I use to do this is (in c++) is below.
This works unless the child process starts up a process of it's own.
Then the whole thing blocks until I kill the grandchild process.
So what am I doing wrong.
------- Code follows
{
// sock1[1] is to write to child, sock2[1] is to read from child
int sock1[2], sock2[2];
// open socket pairs
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sock1) < 0 ||
socketpair(AF_UNIX, SOCK_STREAM, 0, sock2) < 0) {
Error("Unable to open sockets.");
return;
}
// fork
if ((child_pid = vfork()) == -1) {
Error("Unable to start child process.");
return;
}
// this is the parent process (i.e. CDS)
else if (child_pid > 0) {
// close child sockets
close(sock1[0]); close(sock2[0]);
stream_write = fdopen(sock1[1], "w");
stream_read = fdopen(sock2[1], "r");
input_id =
XtAddInput(sock2[1], XtInputReadMask, CmModelReceiveInput, this);
}
// this is the child process
// this code follows the popen() code, in the Unix programmers
// manual, except it establishes two-way communication.
else {
// close parent sockets
// close(sock1[1]); close(sock2[1]);
// duplicate stdin and stdout into child sockets
// dup2 closes the old sockets automatically
dup2(sock1[0], fileno(stdin));
dup2(sock2[0], fileno(stdout));
int n = getdtablesize();
for (int i=3; i<n; i++)
(void) close(i);
execl("/bin/sh", "sh", "-c", command.Chars(), 0); // outta here...
_exit(1);
}
}
--
-------------------------------------------------------------------------------
Joseph Wang (joe@athena.mit.edu) Wake Up! Wake Up!
450 Memorial Drive C-111 All who wish not to be slaves.
Cambridge, MA 02139