From: Tom Yu Date: Tue, 4 Feb 2003 03:48:55 +0000 (+0000) Subject: * login.c (dofork): Don't dissociate from controlling tty in the X-Git-Tag: krb5-1.3-alpha1~129 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=a1e2fbd400429e48ff313980be66b3e73f17134a;p=krb5.git * 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. ticket: 608 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@15148 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/appl/bsd/ChangeLog b/src/appl/bsd/ChangeLog index 41f3e70bb..f91cd0ff9 100644 --- a/src/appl/bsd/ChangeLog +++ b/src/appl/bsd/ChangeLog @@ -1,3 +1,11 @@ +2003-02-03 Tom Yu + + * 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 * 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 bc63924aa..246441fd8 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);