{
char buf[8192], ptyname[16], *username, *logfile;
struct utmp utmp;
+ struct sigaction act;
+ sigset_t set;
int mfd, sfd;
ssize_t n;
- int i;
if (argc != 3)
usage();
username = argv[1];
logfile = argv[2];
+ sigemptyset(&set);
+ sigaddset(&set, SIGTERM);
+ sigaddset(&set, SIGIO);
+ if (sigprocmask(SIG_BLOCK, &set, NULL) == -1)
+ err(1, "sigprocmask block init");
+
if ((lg = fopen(logfile, "w")) == NULL)
err(1, "fopen %s", logfile);
if (setlinebuf(lg) != 0)
err(1, "setlinebuf");
- if (signal(SIGTERM, terminate) == SIG_ERR)
- err(1, "signal SIGTERM");
- if (signal(SIGINT, terminate) == SIG_ERR)
- err(1, "signal SIGINT");
+ memset(&act, 0, sizeof(act));
+ act.sa_mask = set;
+ act.sa_flags = SA_RESTART;
+ act.sa_handler = terminate;
+ if (sigaction(SIGTERM, &act, NULL) == -1)
+ err(1, "sigaction SIGTERM");
+ if (sigaction(SIGINT, &act, NULL) == -1)
+ err(1, "sigaction SIGINT");
if (openpty(&mfd, &sfd, ptyname, NULL, NULL) == -1)
err(1, "openpty");
login(&utmp);
fprintf(lg, "login %s %s\n", username, tty);
- if (signal(SIGIO, iostdin) == SIG_ERR)
- err(1, "signal SIGIO");
+ act.sa_handler = iostdin;
+ if (sigaction(SIGIO, &act, NULL) == -1)
+ err(1, "sigaction SIGIO");
if (setpgid(0, 0) == -1)
err(1, "setpgid");
- i = getpid();
- if (fcntl(0, F_SETOWN, i) == -1 &&
- ioctl(0, SIOCSPGRP, &i) == -1) /* pipe(2) with F_SETOWN broken */
- err(1, "fcntl F_SETOWN, ioctl SIOCSPGRP");
+ if (fcntl(0, F_SETOWN, getpid()) == -1)
+ err(1, "fcntl F_SETOWN");
if (fcntl(0, F_SETFL, O_ASYNC) == -1)
err(1, "fcntl O_ASYNC");
- if (signal(SIGALRM, timeout) == SIG_ERR)
- err(1, "signal SIGALRM");
+ act.sa_handler = timeout;
+ if (sigaction(SIGALRM, &act, NULL) == -1)
+ err(1, "sigaction SIGALRM");
if (alarm(30) == (unsigned int)-1)
err(1, "alarm");
fprintf(lg, "%s: started\n", getprogname());
+ if (sigprocmask(SIG_UNBLOCK, &set, NULL) == -1)
+ err(1, "sigprocmask unblock init");
+
+ /* do not block signals during read, it has to be interrupted */
while ((n = read(mfd, buf, sizeof(buf))) > 0) {
+ if (sigprocmask(SIG_BLOCK, &set, NULL) == -1)
+ err(1, "sigprocmask block write");
fprintf(lg, ">>> ");
if (fwrite(buf, 1, n, lg) != (size_t)n)
err(1, "fwrite %s", logfile);
if (buf[n-1] != '\n')
fprintf(lg, "\n");
+ if (sigprocmask(SIG_UNBLOCK, &set, NULL) == -1)
+ err(1, "sigprocmask unblock write");
}
+ if (sigprocmask(SIG_BLOCK, &set, NULL) == -1)
+ err(1, "sigprocmask block exit");
if (n < 0)
err(1, "read %s", ptyname);
fprintf(lg, "EOF %s\n", ptyname);