signals and stat()
Script started on Thu May 01 14:36:30 1997
sh-2.00$
sh-2.00$ cat track.c
/* track.c
When SIGUSR1 is received by this program, it determines
whether atime has changed for any of its arguments. This
includes determining if the file cannot be stat'ed. Should
run in the background.
*/
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
time_t get_atime(char *);
void restat(int);
time_t * atimes; /* array to hold old atimes from previous round. */
int nargs; /* Make argc and argv visible to interrupt handler. */
char ** argvcopy;
int main(int argc, char ** argv)
{
int i;
/* Turn off signal of interest until we set up. */
signal( SIGUSR1, SIG_IGN);
/* Simple argument check */
if( argc < 2 )
{
fprintf(stderr, "Usage: track file1 file2 ...\n");
exit(1);
}
/* Let interrupt handler be able to see both argc and argv. */
nargs = argc;
argvcopy = argv;
/* Do initial stats of the files */
atimes = (time_t *) malloc ( (argc - 1)* sizeof(time_t) );
for ( i = 0; i < argc - 1; i++ )
atimes[i] = get_atime(argv[i+1]);
/* Now set to trap signal. */
signal( SIGUSR1, restat );
/* Just wait for signal. */
while( 1 )
pause();
}
time_t get_atime(char * file)
{
/* Return is -1 if we cannot stat the argument, st_atime otherwise. */
struct stat buffer;
return ( stat(file, &buffer) < 0) ? (time_t) -1 : buffer.st_atime;
}
void restat(int sig)
{
int i;
time_t newtime;
/* If atime has changed, or we could stat the file before but
can't now, report it and change atime[] entry for this file.
*/
for (i = 0; i < nargs - 1; i++ )
if( (newtime = get_atime(argvcopy[i+1])) != atimes[i] )
{
if( newtime == -1 )
printf("No stat for %s\n", argvcopy[i+1]);
else
printf("New atime for %s\n", argvcopy[i+1]);
atimes[i] = newtime;
}
/* In-class exercise: what's wrong with this? */
}
sh-2.00$ track foo junk &
[1] 20453
sh-2.00$ kill -SIGUSR1 20453
sh-2.00$ cat foo
sh-2.00$ kill -SIGUSR1 20453
New atime for foo
sh-2.00$ touch foo junk
sh-2.00$ kill -SIGUSR1 20453
New atime for foo
New atime for junk
sh-2.00$ rm foo
sh-2.00$ kill -SIGUSR1 20453
No stat for foo
sh-2.00$ kill 20453
[1]+ Terminated track foo junk
sh-2.00$ exit
exit
script done on Thu May 01 14:40:09 1997