Catching a signal and sending output to correct terminal
Ramon F Herrera
ramon at skye.mit.edu
Tue Jul 31 12:15:28 AEST 1990
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 at iona.mit.edu
More information about the Comp.unix.questions
mailing list