--- sh.c +++ sh.c 25 Feb 2009 22:53:47 -0000 @@ -1103,17 +1103,7 @@ } #endif /* NeXT */ #ifdef BSDJOBS /* if we have tty job control */ - retry: - if ((tpgrp = tcgetpgrp(f)) != -1) { - if (tpgrp != shpgrp) { - struct sigaction old; - - sigaction(SIGTTIN, NULL, &old); - signal(SIGTTIN, SIG_DFL); - (void) kill(0, SIGTTIN); - sigaction(SIGTTIN, &old, NULL); - goto retry; - } + if (grabpgrp(f, shpgrp) != -1) { /* * Thanks to Matt Day for the POSIX references, and to * Paul Close for the SGI clarification. @@ -2356,3 +2346,28 @@ rechist(NULL, adrof(STRsavehist) != NULL); } } + +/* + * Grab the tty repeatedly, and give up if we are not in the correct + * tty process group. + */ +int +grabpgrp(int fd, pid_t desired) +{ + struct sigaction old; + pid_t pgrp; + size_t i; + + for (i = 0; i < 100; i++) { + if ((pgrp = tcgetpgrp(fd)) == -1) + return -1; + if (pgrp == desired) + return 0; + (void)sigaction(SIGTTIN, NULL, &old); + (void)signal(SIGTTIN, SIG_DFL); + (void)kill(0, SIGTTIN); + (void)sigaction(SIGTTIN, &old, NULL); + } + errno = EPERM; + return -1; +} --- sh.decls.h +++ sh.decls.h 25 Feb 2009 22:53:47 -0000 @@ -52,6 +52,7 @@ #else extern void xexit (int); #endif +extern int grabpgrp (int, pid_t); /* * sh.dir.c --- sh.func.c +++ sh.func.c 25 Feb 2009 22:53:47 -0000 @@ -2272,10 +2272,9 @@ dosuspend(Char **v, struct command *c) { #ifdef BSDJOBS - int ctpgrp; struct sigaction old; #endif /* BSDJOBS */ - + USE(c); USE(v); @@ -2295,17 +2294,8 @@ #ifdef BSDJOBS if (tpgrp != -1) { -retry: - ctpgrp = tcgetpgrp(FSHTTY); - if (ctpgrp == -1) + if (grabpgrp(FSHTTY, opgrp) == -1) stderror(ERR_SYSTEM, "tcgetpgrp", strerror(errno)); - if (ctpgrp != opgrp) { - sigaction(SIGTTIN, NULL, &old); - signal(SIGTTIN, SIG_DFL); - (void) kill(0, SIGTTIN); - sigaction(SIGTTIN, &old, NULL); - goto retry; - } (void) setpgid(0, shpgrp); (void) tcsetpgrp(FSHTTY, shpgrp); }