#define _GNU_SOURCE
#include <fcntl.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
int fd=0;
char *dir=NULL;
char *slashPtr=NULL;
struct stat statBuf;
struct sigaction action;
int directorychanged=0;
char splitFilename[128];
char filechecked[127];
time_t modifiedTime;
int isrunning=0;
int filechanged=0;
void EventHandlerFunc( int sig )
{
// printf("This is the event Handler when the ./ directory is modified \n" /* , filechecked */ );
directorychanged = 1;
}
void DelayedActionToFileChange()
{
printf("Delayed action after a modification to %s \n", filechecked);
filechanged = 0;
}
int InitDetectChange( int argc, char *argv[] )
{
/* Find directory the file is in, or assume the current directory */
strncpy( splitFilename, argv[1], 127 );
strncpy( filechecked, argv[1], 127 );
if( (slashPtr = rindex( splitFilename, '/' )) == NULL )
{
dir = ".";
}
else
{
*slashPtr = 0;
dir = splitFilename;
}
/* Set up the signal handler */
action.sa_handler = EventHandlerFunc;
sigemptyset( &action.sa_mask );
action.sa_flags = SA_RESTART;
sigaction( SIGRTMIN, &action, NULL );
/* Open the directory the file is in */
if( (fd = open( dir, O_RDONLY )) < 0 )
{
printf( "Cannot open %s for reading : %s\n", dir, strerror(errno) );
exit( -1 );
}
/* Choose the signal I want to receive when the directory content changes */
if( fcntl( fd, F_SETSIG, SIGRTMIN) < 0 )
{
printf( "Cannot set signal : %s\n", strerror(errno) );
exit( -1 );
}
/* Ask for notification when a modification is made in the directory */
if( fcntl( fd, F_NOTIFY, DN_MODIFY|DN_MULTISHOT ) < 0 )
{
printf( "Cannot fcntl %s : %s\n", dir, strerror(errno) );
exit( -1 );
}
if( lstat( filechecked, &statBuf ) < 0 )
{
printf( "Cannot lstat %s : %s\n", filechecked, strerror(errno) );
exit( -1 );
}
modifiedTime = statBuf.st_mtime;
return fd;
}
int DetectChange(char *filename)
{
if( lstat( filename, &statBuf ) < 0 )
{
printf( "Cannot lstat %s : %s\n", filename, strerror(errno) );
exit( -1 );
}
// If the modification time has changed, the file has been altered
if( modifiedTime != statBuf.st_mtime )
{
directorychanged = 1;
filechanged = 1;
modifiedTime = statBuf.st_mtime;
// printf( "File %s has really been modified since the lastest call\n", filename );
}else{
// directorychanged = 0;
filechanged = 0;
// printf( "File %s hasn\'t been modified since the later call\n", filename );
}
return filechanged;
}
void PrintUsage(int argc, char **argv)
{
if( argc != 2 )
{
printf( "Usage: %s filename", argv[0] );
exit( -1 );
}
if( lstat( argv[1], &statBuf ) < 0 )
{
printf( "Cannot lstat %s : %s\n", argv[1], strerror(errno) );
exit( -1 );
}
if( ! S_ISREG( statBuf.st_mode ) )
{
printf( "%s is not a regular file\n", argv[1] );
exit( -1 );
}
}
int main( int argc, char *argv[] )
{
PrintUsage(argc, argv);
isrunning = InitDetectChange(argc, argv);
while( isrunning )
{
/* This demo has nothing to do, so just wait for a signal */
sleep(10);
/* Check the flag which indicates the right signal has been received */
if( directorychanged )
{
if( DetectChange(argv[1]) )
{
sleep(1);
DelayedActionToFileChange();
}
}
}
return 0;
}