Here I have a code under Linux, which should monitor changes in directories or files. This is called watchfulness. On this code I have two questions
1) How to exit the program? Here we use an infinite loop
while(1) while the user is not able to complete the process. There is only CTRL + C, but the text from the buffer does not fit into the log. Therefore, I added a function
fflush(fp_log); which pushes the text from the buffer to the file. But in short, it is ugly. How to provide an exit from a cycle? I tried getch or getchar but I get errors.
2) When I create a directory or change a file, the message is displayed in the terminal, but when I delete a file or folder, or rename it, it is not displayed. How to make to output? Add another mask? Which one?
/* Inotify ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ Π½Π°Π±Π»ΡΠ΄Π΅Π½ΠΈΡ Π·Π° ΠΏΠΎΠ΄Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡΠΌΠΈ Π²ΡΠ±ΡΠ°Π½Π½ΠΎΠΉ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΈ*/ #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 /*Π΄Π»ΠΈΠ½Π° ΠΏΡΡΠΈ Π΄Π»Ρ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΈ*/ #define MAX_EVENTS 1024 /*ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΠΎΠ΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΠΎΠ±ΡΡΠΈΠΉ Π΄Π»Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ Π·Π° ΠΎΠ΄ΠΈΠ½ ΡΠ°Π·*/ #define LEN_NAME 16 /*ΠΏΡΠ΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, ΡΡΠΎ Π΄Π»ΠΈΠ½Π° ΠΈΠΌΠ΅Π½ΠΈ ΡΠ°ΠΉΠ»Π° Π½Π΅ ΠΏΡΠ΅Π²ΡΡΠ°Π΅Ρ 16 Π±Π°ΠΉΡ*/ #define EVENT_SIZE ( sizeof (struct inotify_event) ) /*ΡΠ°Π·ΠΌΠ΅Ρ ΡΡΡΡΠΊΡΡΡΡ ΡΠΎΠ±ΡΡΠΈΡ*/ #define BUF_LEN ( MAX_EVENTS * ( EVENT_SIZE + LEN_NAME )) /*Π±ΡΡΠ΅Ρ Π΄Π»Ρ Ρ
ΡΠ°Π½Π΅Π½ΠΈΡ Π΄Π°Π½Π½ΡΡ
ΡΠΎΠ±ΡΡΠΈΡ*/ /* Π€Π°ΠΉΠ» ΠΆΡΡΠ½Π°Π»Π°*/ FILE *fp_log; /* ΠΠΎΠ±Π°Π²ΠΈΠΌ Π½Π°Π±Π»ΡΠ΄Π΅Π½ΠΈΡ inotify Π΄Π»Ρ ΠΏΠΎΠ΄Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΉ ΡΡΠ°Π·Ρ ΠΏΠΎΡΠ»Π΅ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΡ ΠΊΠΎΡΠ½Π΅Π²ΠΎΠΉ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΈ */ void add_watches(int fd, char *root) { int wd; char *abs_dir; DIR *dp; dp = opendir(root); if (dp == NULL) { perror("Error opening the starting directory"); exit(0); } /* Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½Π°Π±Π»ΡΠ΄Π΅Π½ΠΈΡ Π΄Π»Ρ ΠΊΠΎΡΠ½Π΅Π²ΠΎΠΉ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΈ */ 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); } closedir(dp); } /* Π€ΡΠ½ΠΊΡΠΈΡ main*/ int main( int argc, char **argv ) { int length, i = 0; int fd; char buffer[BUF_LEN], root[MAX_LEN]; char s; /*ΠΡΠΎΠ²Π΅ΡΠΊΠ° Π½Π°Π»ΠΈΡΠΈΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ° ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ*/ 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"); } /* ΠΡΠΊΡΡΡΠΈΠ΅ ΡΠ°ΠΉΠ»Π° ΠΆΡΡΠ½Π°Π»Π°*/ fp_log = fopen("asasas111.log","w+"); if (fp_log == NULL) { printf("Error opening logger. All output will be redirected to the stdout\n"); } fd = inotify_init(); if ( fd < 0 ) { perror( "Couldn't initialize inotify"); } /* ΠΎΠ±Ρ
ΠΎΠ΄ ΠΏΠΎΠ΄Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΉ ΠΏΠ΅ΡΠ²ΠΎΠ³ΠΎ ΡΡΠΎΠ²Π½Ρ ΠΈ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½Π°Π±Π»ΡΠ΄Π΅Π½ΠΈΠΉ */ add_watches(fd,root); /* Π±Π΅ΡΠΊΠΎΠ½Π΅ΡΠ½ΡΠΉ ΡΠΈΠΊΠ»*/ 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) { fprintf(fp_log,"%d DIR::%s CREATED\n", event->wd,event->name ); fflush(fp_log); printf("%d DIR::%s CREATED\n", event->wd,event->name ); } else { fprintf(fp_log, "%d FILE::%s CREATED\n", event->wd, event->name); fflush(fp_log); printf("%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 ); fflush(fp_log); printf("%d DIR::%s MODIFIED\n", event->wd,event->name ); } else { fprintf(fp_log,"%d FILE::%s MODIFIED\n", event->wd,event->name ); printf("%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 ); fflush(fp_log); printf("%d DIR::%s DELETED\n", event->wd,event->name ); } else { fprintf(fp_log,"%d FILE::%s DELETED\n", event->wd,event->name ); fflush(fp_log); printf("%d FILE::%s DELETED\n", event->wd,event->name ); } } i += EVENT_SIZE + event->len; } } } /* ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ ΡΠ΅ΡΡΡΡΠΎΠ²*/ ( void ) close( fd ); return 0; }