Commits

amitksaha  committed 17301db

Source code for Inotify article: LFY, April, 2011

  • Participants

Comments (0)

Files changed (3)

File inotify_article/auto_compile.c

+/* auto_compile.c*/
+
+/* Automatic compilation of C code using Inotify
+ * Assumptions:
+ * argv[1]: where the source codes are stored
+ * bin/ sub-directory: in which the binaries will be stored
+ * 
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/inotify.h>
+#include <limits.h>
+
+#define MAX_EVENTS 1024 /*Max. number of events to process at one go*/
+#define LEN_NAME 16 /*Assuming that the length of the filename won't exceed 16 bytes*/
+#define EVENT_SIZE  ( sizeof (struct inotify_event) ) /*size of one event*/
+#define BUF_LEN     ( MAX_EVENTS * ( EVENT_SIZE + LEN_NAME )) /*buffer to store the data of events*/
+
+int main( int argc, char **argv ) 
+{
+  int length, i = 0, wd;
+  int fd;
+  char buffer[BUF_LEN],cur_dir[BUF_LEN];
+
+  char command[100],copy_cmd[100];
+  strcpy(command,"gcc -o ");
+
+  /* Initialize Inotify*/
+  fd = inotify_init();
+  if ( fd < 0 ) {
+    perror( "Couldn't initialize inotify");
+  }
+
+  /* add watch to starting directory */
+  wd = inotify_add_watch(fd, argv[1], IN_CREATE | IN_MODIFY); 
+
+  if (wd == -1)
+    {
+      printf("Couldn't add watch to %s\n",argv[1]);
+    }
+  else
+    {
+      printf("Watching:: %s\n",argv[1]);
+    }
+
+  /* do it forever*/
+  while(1)
+    {
+      i = 0;
+      length = read( fd, buffer, BUF_LEN );  
+
+      if ( length < 0 ) {
+	perror( "read" );
+      }  
+
+      while ( i < length ) {
+	struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
+	if ( event->len ) {
+	  if ( event->mask & IN_CREATE) {
+	    if (event->mask & IN_ISDIR)
+	      printf( "The directory %s was Created.\n", event->name );       
+	    else
+	      {
+		printf( "Compiling::  %s \n", event->name);       
+
+		/*save the current dir*/
+		getcwd(cur_dir,BUF_LEN);
+		chdir(argv[1]);
+
+		/* form string for gcc*/
+		strcat(command,"bin/"); 
+		strcat(command,event->name);
+		strcat(command,".out ");
+		strcat(command,event->name);
+
+		/* execute gcc*/
+		system(command);
+
+		/*change back to dir*/
+		chdir(cur_dir);
+		strcpy(command,"gcc -o ");
+	      }
+		
+	  }
+	  
+	  if ( event->mask & IN_MODIFY) {
+	    if (event->mask & IN_ISDIR)
+	      printf( "The directory %s was modified.\n", event->name );       
+	    else
+	      {
+		printf( "Compiling:: %s \n", event->name);       
+
+		/*save the current dir*/
+		getcwd(cur_dir,BUF_LEN);
+		chdir(argv[1]);
+
+		/* form string for gcc*/
+		strcat(command,"bin/");
+		strcat(command,event->name);
+		strcat(command,".out ");
+		strcat(command,event->name);
+
+		/* execute gcc*/
+		system(command);
+
+		/*change back to dir*/
+		chdir(cur_dir);
+		strcpy(command,"gcc -o ");
+	      }
+
+	  }	  
+	  i += EVENT_SIZE + event->len;
+	}
+      }
+    }
+
+  /* Clean up*/
+  inotify_rm_watch( fd, wd );
+  close( fd );
+  
+  return 0;
+}

File inotify_article/listing1.c

+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/inotify.h>
+#include <limits.h>
+
+#define MAX_EVENTS 1024 /*Max. number of events to process at one go*/
+#define LEN_NAME 16 /*Assuming that the length of the filename won't exceed 16 bytes*/
+#define EVENT_SIZE  ( sizeof (struct inotify_event) ) /*size of one event*/
+#define BUF_LEN     ( MAX_EVENTS * ( EVENT_SIZE + LEN_NAME )) /*buffer to store the data of events*/
+
+int main( int argc, char **argv ) 
+{
+  int length, i = 0, wd;
+  int fd;
+  char buffer[BUF_LEN];
+
+  /* Initialize Inotify*/
+  fd = inotify_init();
+  if ( fd < 0 ) {
+    perror( "Couldn't initialize inotify");
+  }
+
+  /* add watch to starting directory */
+  wd = inotify_add_watch(fd, argv[1], IN_CREATE | IN_MODIFY | IN_DELETE); 
+
+  if (wd == -1)
+    {
+      printf("Couldn't add watch to %s\n",argv[1]);
+    }
+  else
+    {
+      printf("Watching:: %s\n",argv[1]);
+    }
+
+  /* do it forever*/
+  while(1)
+    {
+      i = 0;
+      length = read( fd, buffer, BUF_LEN );  
+
+      if ( length < 0 ) {
+	perror( "read" );
+      }  
+
+      while ( i < length ) {
+	struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
+	if ( event->len ) {
+	  if ( event->mask & IN_CREATE) {
+	    if (event->mask & IN_ISDIR)
+	      printf( "The directory %s was Created.\n", event->name );       
+	    else
+	      printf( "The file %s was Created with WD %d\n", event->name, event->wd );       
+	  }
+	  
+	  if ( event->mask & IN_MODIFY) {
+	    if (event->mask & IN_ISDIR)
+	      printf( "The directory %s was modified.\n", event->name );       
+	    else
+	      printf( "The file %s was modified with WD %d\n", event->name, event->wd );       
+	  }
+	  
+	  if ( event->mask & IN_DELETE) {
+	    if (event->mask & IN_ISDIR)
+	      printf( "The directory %s was deleted.\n", event->name );       
+	    else
+	      printf( "The file %s was deleted with WD %d\n", event->name, event->wd );       
+	  }  
+
+
+	  i += EVENT_SIZE + event->len;
+	}
+      }
+    }
+
+  /* Clean up*/
+  inotify_rm_watch( fd, wd );
+  close( fd );
+  
+  return 0;
+}

File inotify_article/listing2.c

+/* Using Inotify to monitor the sub-dirs under the specifiied dir*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/inotify.h>
+#include <dirent.h>
+#include <limits.h>
+
+#define MAX_LEN 1024 /*Path length for a directory*/
+#define MAX_EVENTS 1024 /*Max. number of events to process at one go*/
+#define LEN_NAME 16 /*Assuming that the length of the filename won't exceed 16 bytes*/
+#define EVENT_SIZE  ( sizeof (struct inotify_event) ) /*size of one event*/
+#define BUF_LEN     ( MAX_EVENTS * ( EVENT_SIZE + LEN_NAME )) /*buffer to store the data of events*/
+
+
+/* Log file*/
+FILE *fp_log;
+ 
+
+/* Add inotify watches to directories immediately under root
+ * in addition to itself */
+
+void add_watches(int fd, char *root)
+{
+  int wd;
+  char *abs_dir;
+  struct dirent *entry;
+  DIR *dp;
+
+  dp = opendir(root);
+  if (dp == NULL)
+    {
+      perror("Error opening the starting directory");
+      exit(0);
+    }
+
+  /* add watch to starting directory */
+  wd = inotify_add_watch(fd, root, IN_CREATE | IN_MODIFY | IN_DELETE); 
+  if (wd == -1)
+    {
+      fprintf(fp_log,"Couldn't add watch to %s\n",root);
+    }
+  else
+    {
+      printf("Watching:: %s\n",root);
+    }
+
+  /* Add watches to the Level 1 sub-dirs*/
+  abs_dir = (char *)malloc(MAX_LEN);
+  while((entry = readdir(dp)))
+    { 
+      /* if its a directory, add a watch*/
+      if (entry->d_type == DT_DIR)
+	{
+	  strcpy(abs_dir,root);
+	  strcat(abs_dir,entry->d_name);
+	  
+	  wd = inotify_add_watch(fd, abs_dir, IN_CREATE | IN_MODIFY | IN_DELETE); 
+	  if (wd == -1)
+	      printf("Couldn't add watch to the directory %s\n",abs_dir);
+	  else
+	    printf("Watching:: %s\n",abs_dir);
+	}
+    }
+  
+  closedir(dp);
+  free(abs_dir);
+}
+
+/* Main routine*/
+int main( int argc, char **argv ) 
+{
+  int length, i = 0;
+  int fd;
+  char buffer[BUF_LEN], root[MAX_LEN];
+
+
+  /*Check for supplied path to monitor*/
+  switch(argc)
+    {
+    case 1: printf("No directory specified. Will monitor the entire filesystem...\n\n");
+      strcpy(root,"/");
+      break;
+      
+    case 2: strcpy(root,argv[1]);
+      if(root[strlen(root)-1]!='/')
+	strcat(root,"/");
+      puts(root);
+
+      break;
+      
+    default: printf("Ignoring all other arguments after the first\n");
+    }
+  
+
+  /* Set up logger*/
+  fp_log = fopen("inotify_logger.log","a");
+  if (fp_log == NULL)
+    {
+      printf("Error opening logger. All output will be redirected to the stdout\n");
+      fp_log = stdout;
+    }
+
+  fd = inotify_init();
+  if ( fd < 0 ) {
+    perror( "Couldn't initialize inotify");
+  }
+
+  /* Read the sub-directories at one level under argv[1] 
+   * and monitor them for access */
+  add_watches(fd,root);
+  
+  /* do it forever*/
+  while(1)
+    {
+      i = 0;
+      length = read( fd, buffer, BUF_LEN );  
+
+      if ( length < 0 ) {
+	perror( "read" );
+      }  
+
+      /* Read the events*/
+      while ( i < length ) {
+	struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
+	if ( event->len ) {
+	  if ( event->mask & IN_CREATE) {
+	    if (event->mask & IN_ISDIR)
+	      fprintf(fp_log,"%d DIR::%s CREATED\n", event->wd,event->name );       
+	    else
+	      fprintf(fp_log, "%d FILE::%s CREATED\n", event->wd, event->name);       
+	  }
+	  
+	  if ( event->mask & IN_MODIFY) {
+	    if (event->mask & IN_ISDIR)
+	      fprintf(fp_log,"%d DIR::%s MODIFIED\n", event->wd,event->name );       
+	    else
+	      fprintf(fp_log,"%d FILE::%s MODIFIED\n", event->wd,event->name );       
+
+	  }
+	  
+	  if ( event->mask & IN_DELETE) {
+	    if (event->mask & IN_ISDIR)
+	      fprintf(fp_log,"%d DIR::%s DELETED\n", event->wd,event->name );       
+	    else
+	      fprintf(fp_log,"%d FILE::%s DELETED\n", event->wd,event->name );       
+	  }  
+
+	  i += EVENT_SIZE + event->len;
+	}
+      }
+    }
+  /* Clean up*/
+  ( void ) close( fd );
+  
+  return 0;
+}