/* The user must be able to write to the new TTY. Normally grantpt() would
* do this for us, but we don't trust the user and thus don't want to pass
* the pty_master to a process running under that uid. */
- // TODO: is this a problem?
if (chown(slave_path, uid, (gid_t)-1) != 0) {
die("chown slave tty");
}
while (*pid_to_wait_for != 0) {
/*
* If a signal happens here _and_ the child hasn't closed pty_slave,
- * we will hang in poll(); therefore ppoll() is requred.
+ * we would hang in poll(); therefore ppoll() is necessary.
*/
nfds_t nfds = sizeof(fds)/sizeof(*fds);
if (ppoll(fds, nfds, NULL /* no timeout */, &sigset_old) == -1) {
break;
}
- /* Handle errors first. */
+ /* Handle errors first. (Data available before the error occurred
+ * might be skipped, but shouldn't matter here.) */
if (fds[0].revents & (POLLERR | POLLNVAL)) {
fprintf(stderr, "poll: error on master: %d\n", fds[0].revents);
break;
break;
}
- /* Then read data if available. */
+ /* Read data if available. */
if (fds[0].revents & POLLIN) {
if (!read_from_write_to(pty_master, ctty)) {
perror("read from master write to ctty");
}
-/* Not sig_atomic_t but I don't know how to do that any other way. */
+/*
+ * Not sig_atomic_t (as required by POSIX) but I don't know how to do that any
+ * other way.
+ */
static volatile pid_t pid_to_wait_for;
static int pid_to_wait_for_status;
if (pid == -1) {
die("fork parent");
} else if (pid == 0) {
+ /* child, will become a session leader */
+
if (sigprocmask(SIG_SETMASK, &sigset_old, NULL) != 0) {
die("sigprocmask setmask child");
}
close_or_die(STDOUT_FILENO);
close_or_die(STDERR_FILENO);
- // TODO: EINTR?
+ /* TODO: EINTR? */
int status;
if (waitpid(pid, &status, 0) <= 0) {
die("waitpid child");
die("tcgetattr");
}
term = old_term;
- /* From man 3 cfmakeraw which is non-standard. */
+ /* From man 3 cfmakeraw; cfmakeraw is non-standard so set it manually. */
term.c_iflag &= ~(tcflag_t)(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
term.c_oflag &= ~(tcflag_t)(OPOST);
term.c_lflag &= ~(tcflag_t)(ECHO | ECHONL | ICANON | ISIG | IEXTEN);