summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/appl/bsd/ChangeLog8
-rw-r--r--src/appl/bsd/login.c60
2 files changed, 36 insertions, 32 deletions
diff --git a/src/appl/bsd/ChangeLog b/src/appl/bsd/ChangeLog
index 41f3e70bba..f91cd0ff95 100644
--- a/src/appl/bsd/ChangeLog
+++ b/src/appl/bsd/ChangeLog
@@ -1,3 +1,11 @@
+2003-02-03 Tom Yu <tlyu@mit.edu>
+
+ * login.c (dofork): Don't dissociate from controlling tty in the
+ parent, since the parent needs to remain the session leader so it
+ can tell when the tty gets hung up. Make the child wait for the
+ parent to set up a SIGHUP handler to ensure that cleanup happens
+ properly.
+
2003-01-31 Tom Yu <tlyu@mit.edu>
* kcmd.c (v4_des_write): Apply patch from ghudson to fix
diff --git a/src/appl/bsd/login.c b/src/appl/bsd/login.c
index bc63924aae..246441fd89 100644
--- a/src/appl/bsd/login.c
+++ b/src/appl/bsd/login.c
@@ -2371,52 +2371,48 @@ dofork()
{
int child,pid;
handler sa;
+ int syncpipe[2];
+ char c;
+ int n;
#ifdef _IBMR2
update_ref_count(1);
#endif
- if (!(child=fork()))
- return; /* Child process returns */
-
- /* The parent continues here */
-
- /* Try and get rid of our controlling tty. On SunOS, this may or may
- not work depending on if our parent did a setsid before exec-ing
- us. */
-#ifndef __linux__
- /* On linux, TIOCNOTTY causes us to die on a
- SIGHUP, so don't even try it. */
-#ifdef TIOCNOTTY
- {
- int fd;
-
- if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
- ioctl(fd, TIOCNOTTY, 0);
- close(fd);
+ if (pipe(syncpipe) < 0) {
+ perror("login: dofork: setting up syncpipe");
+ exit(1);
+ }
+ if (!(child=fork())) {
+ close(syncpipe[1]);
+ while ((n = read(syncpipe[0], &c, 1)) < 0) {
+ if (errno != EINTR) {
+ perror("login: dofork: waiting for sync from parent");
+ exit(1);
+ }
+ }
+ if (n == 0) {
+ fprintf(stderr, "login: dofork: unexpected EOF waiting for sync\n");
+ exit(1);
}
+ close(syncpipe[0]);
+ return; /* Child process returns */
}
-#endif
-#endif /* __linux__ */
-#ifdef HAVE_SETSID
- (void)setsid();
-#endif
+ /* The parent continues here */
-#ifdef SETPGRP_TWOARG
- (void)setpgrp(0, 0);
-#else
- (void)setpgrp();
-#endif
+ /* On receipt of SIGHUP, pass that along to child's process group. */
+ handler_init (sa, sighup);
+ handler_set (SIGHUP, sa);
+ /* Tell child we're ready. */
+ close(syncpipe[0]);
+ write(syncpipe[1], "", 1);
+ close(syncpipe[1]);
/* Setup stuff? This would be things we could do in parallel with login */
(void) chdir("/"); /* Let's not keep the fs busy... */
/* If we're the parent, watch the child until it dies */
- /* On receipt of SIGHUP, pass that along to child's process group. */
- handler_init (sa, sighup);
- handler_set (SIGHUP, sa);
-
while (1) {
#ifdef HAVE_WAITPID
pid = waitpid(child, 0, 0);