ramon@skye.mit.edu (Ramon F Herrera) (07/31/90)
This is in response to a request by myself, for a method to have a long-running program send intermediate results (upon reception of an interrupt signal), to the terminal of its user, even between logouts. Since a process has no way of knowing the procedence of an interrupt, the approach taken was to look in the /etc/utmp file to check if the user is logged in, and in what terminal(s). The output is sent to the terminal which has been accessed most recently. If the program is being run in the foreground, the interrupt is generated with a ^C, and if it is in the background, by 'kill -INT <pid>'. Thanks very much to Guy Harris, Dan Bernstein and Jeffrey DeLeo for their suggestions. #include <stdio.h> #include <pwd.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/file.h> #include <utmp.h> #include <signal.h> #define TRUE 1 WeInterruptThisProgram() { char theboss[9]; char thetty[13], recent[13]; struct utmp user[64]; struct stat fileinfo; int fd, nread; int this, entries; long maximum = -1; strcpy(theboss, getpwuid(getuid())->pw_name); strcpy(thetty, "/dev/"); strcpy(recent, "none"); stat("/etc/utmp", &fileinfo); entries = fileinfo.st_size / sizeof(struct utmp); fd = open("/etc/utmp", O_RDONLY); nread = read(fd, user, fileinfo.st_size); close(fd); for (this = 0; this < entries; this++) if (strcmp(user[this].ut_name, theboss) == 0) { strcpy(&thetty[5], user[this].ut_line); stat(thetty, &fileinfo); if (fileinfo.st_atime > maximum) { maximum = fileinfo.st_atime; strcpy(recent, thetty); } } if (strcmp(recent, "none") != 0) { fd = open(recent, O_WRONLY); write(fd, recent, 10); close(fd); } else system("touch NoTerminal"); } main() { signal(SIGINT, WeInterruptThisProgram); while (TRUE) /* crunch, cruch, etc. */; } -- Ramon F. Herrera Research Laboratory of Electronics Massachusetts Institute of Technology ramon@iona.mit.edu