From: jan@swi.psy.uva.nl (Jan Wielemaker) Subject: Controlling terminal Date: Wed, 7 Apr 1993 12:45:45 GMT
Hi,
Nearly everything works! Just this. I'm trying to get a sub-process
hanging off a pty. The control terminal of the sub-process should be
the pty. I've got the code tested on SunOS, Ultrix and AIX, but it
refuses to switch the controlling tty on Linux. A bug?
Roughly, the program
1) Finds and opens a pty
2) Fork()'s
3) the child discards it's /dev/tty using TIOCNOTTY ioctl()
4) the child opens /dev/pty? and closes it again to make this
pty the new /dev/tty
5) the child dup2()'s stdin etc.
6) the child exec()'s
Here is the source of the interesting peace:
.....
if ( (name = getPTty(p, &master, &slave)) == NULL )
fail;
if ( (pid = fork()) == 0 ) /* child process */
{ int fd, i, argc;
char **argv;
if ( notDefault(p->directory) )
cdDirectory(p->directory);
initEnvironment(p);
if ( fd = open("/dev/tty", 2) ) /* detach from controlling tty */
{ ioctl(fd, TIOCNOTTY, NULL);
close(fd);
}
if ( (fd = open(name, 0)) >= 0 ) /* attach to tty-p */
close(fd);
close(master); /* connect to tty-p */
dup2(slave, 0);
dup2(slave, 1);
dup2(slave, 2);
close(slave);
argv = alloca(sizeof(char *) * (valInt(p->arguments->size) + 2));
argc = valInt(p->arguments->size);
argv[0] = p->name->text;
for(i=0; i<argc; i++)
argv[i+1] = toCharp(p->arguments->elements[i]);
argv[i+1] = NULL;
if ( execvp(p->name->text, argv) )
{ errorPce(p, NAME_cannotStart, OsError());
exit(1);
}
} else /* parent process */
{ close(slave);
assign(p, tty, CtoName(name));
pidProcess(p, toInt(pid));
p->rdfd = p->wrfd = master;
p->rdstream = NULL;
assign(p, status, NAME_running);
}
Thanks!
--- Jan