PTY: let closed master cause EOF on slave
This puts PTY on par with e.g. rs232 as well as behavior documented for other OSes. It is not a fix for an issue in userland, though. - add a (minimal) test case to test77; - fix a few other minor issues in test77. Change-Id: I89c000921ee69dd9f5713665349c1ab1ad1dc2cc
This commit is contained in:
parent
3b4688844f
commit
673c4e01a5
2 changed files with 29 additions and 9 deletions
|
@ -126,6 +126,7 @@ static int pty_master_close(devminor_t minor)
|
||||||
pp->state = 0;
|
pp->state = 0;
|
||||||
} else {
|
} else {
|
||||||
pp->state |= PTY_CLOSED;
|
pp->state |= PTY_CLOSED;
|
||||||
|
tp->tty_termios.c_ospeed = B0; /* cause EOF on slave side */
|
||||||
sigchar(tp, SIGHUP, 1);
|
sigchar(tp, SIGHUP, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ static int sighups; /* number of SIGHUP signals received */
|
||||||
/*
|
/*
|
||||||
* Signal handler for SIGHUP and SIGUSR1.
|
* Signal handler for SIGHUP and SIGUSR1.
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
signal_handler(int sig)
|
signal_handler(int sig)
|
||||||
{
|
{
|
||||||
if (sig == SIGHUP)
|
if (sig == SIGHUP)
|
||||||
|
@ -311,9 +311,28 @@ test77c(void)
|
||||||
if (write(slavefd, &c, sizeof(c)) >= 0) e(18);
|
if (write(slavefd, &c, sizeof(c)) >= 0) e(18);
|
||||||
if (errno != EIO) e(19);
|
if (errno != EIO) e(19);
|
||||||
|
|
||||||
if (close(slavefd) < 0) e(20);
|
/* Reads from the slave should return EOF if the master is gone. */
|
||||||
|
if (read(slavefd, &c, sizeof(c)) != 0) e(20);
|
||||||
|
|
||||||
if (sigaction(SIGHUP, &oact, NULL) < 0) e(21);
|
if (close(slavefd) < 0) e(21);
|
||||||
|
|
||||||
|
if (sigaction(SIGHUP, &oact, NULL) < 0) e(22);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait for a child process to terminate. Return 0 if the child exited without
|
||||||
|
* errors, -1 otherwise.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
waitchild(void)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if (wait(&status) <= 0) return -1;
|
||||||
|
if (!WIFEXITED(status)) return -1;
|
||||||
|
if (WEXITSTATUS(status) != 0) return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -348,14 +367,14 @@ test77d(void)
|
||||||
if (open("/dev/tty", O_RDWR) >= 0) e(4);
|
if (open("/dev/tty", O_RDWR) >= 0) e(4);
|
||||||
if (errno != ENXIO) e(5);
|
if (errno != ENXIO) e(5);
|
||||||
|
|
||||||
exit(0);
|
exit(errct);
|
||||||
case -1:
|
case -1:
|
||||||
e(6);
|
e(6);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wait(NULL) <= 0) e(7);
|
if (waitchild() < 0) e(7);
|
||||||
|
|
||||||
if (close(masterfd) < 0) e(8);
|
if (close(masterfd) < 0) e(8);
|
||||||
|
|
||||||
|
@ -373,14 +392,14 @@ test77d(void)
|
||||||
|
|
||||||
if (open("/dev/tty", O_RDWR) < 0) e(12);
|
if (open("/dev/tty", O_RDWR) < 0) e(12);
|
||||||
|
|
||||||
exit(0);
|
exit(errct);
|
||||||
case -1:
|
case -1:
|
||||||
e(13);
|
e(13);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wait(NULL) <= 0) e(14);
|
if (waitchild() < 0) e(14);
|
||||||
|
|
||||||
if (close(masterfd) < 0) e(15);
|
if (close(masterfd) < 0) e(15);
|
||||||
}
|
}
|
||||||
|
@ -441,7 +460,7 @@ test77e(void)
|
||||||
|
|
||||||
if (sighups != 1) e(9);
|
if (sighups != 1) e(9);
|
||||||
|
|
||||||
exit(0);
|
exit(errct);
|
||||||
case -1:
|
case -1:
|
||||||
e(10);
|
e(10);
|
||||||
default:
|
default:
|
||||||
|
@ -455,7 +474,7 @@ test77e(void)
|
||||||
/* Closing the master should now raise a SIGHUP signal in the child. */
|
/* Closing the master should now raise a SIGHUP signal in the child. */
|
||||||
if (close(masterfd) < 0) e(12);
|
if (close(masterfd) < 0) e(12);
|
||||||
|
|
||||||
if (wait(NULL) <= 0) e(13);
|
if (waitchild() < 0) e(13);
|
||||||
|
|
||||||
if (sigprocmask(SIG_SETMASK, &oset, NULL) < 0) e(14);
|
if (sigprocmask(SIG_SETMASK, &oset, NULL) < 0) e(14);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue