Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to monitor a folder with all subfolders and files inside?

Tags:

c++

c

linux

monitor

I have a folder called "Datas". This folder has a subfolder called "Inbox" inside of which there are multiple ".txt" files. This "Datas" folder can be modified and in the end there will be multiple subfolders with "Inbox" subfolders and ".txt" files. I need to monitor the "Datas" folder and the ".txt" file from the "Inbox" folder. How can I do that?

INotify is just monitoring a folder and pops events when subfolders are created. How to pop events when ".txt" files are created (in which folder)?

I need C or C++ code but I am stuck. I do not know how to solve this.

like image 326
just ME Avatar asked Feb 03 '23 08:02

just ME


1 Answers

From the inotify manpage:

   IN_CREATE         File/directory created in watched directory (*).

It can be done by catching this event.

Again from the manpage:

  Limitations and caveats
       Inotify  monitoring  of  directories  is  not recursive: to monitor subdirectories under a directory, additional watches must be created.  This can take a significant
       amount time for large directory trees.

So, you will need to do the recursive part yourself. You can start by looking an example from here. You should also have a look at the project notify-tools

EXAMPLE as asked in comments: It monitors /tmp/inotify1 & /tmp/inotify2 for new files created & displays the events

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/inotify.h>

#define EVENT_SIZE  ( sizeof (struct inotify_event) )
#define BUF_LEN     ( 1024 * ( EVENT_SIZE + 16 ) )

int main( int argc, char **argv ) 
{
    int length, i = 0;
    int fd;
    int wd[2];
    char buffer[BUF_LEN];

    fd = inotify_init();

    if ( fd < 0 ) {
        perror( "inotify_init" );
    }

    wd[0] = inotify_add_watch( fd, "/tmp/inotify1", IN_CREATE);
    wd[1] = inotify_add_watch (fd, "/tmp/inotify2", IN_CREATE);

    while (1){
        struct inotify_event *event;

        length = read( fd, buffer, BUF_LEN );  

        if ( length < 0 ) {
            perror( "read" );
        } 

        event = ( struct inotify_event * ) &buffer[ i ];

        if ( event->len ) {
            if (event->wd == wd[0]) printf("%s\n", "In /tmp/inotify1: ");
            else printf("%s\n", "In /tmp/inotify2: ");
            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.\n", event->name );
                }
            }
        }
    }
    ( void ) inotify_rm_watch( fd, wd[0] );
    ( void ) inotify_rm_watch( fd, wd[1]);
    ( void ) close( fd );

    exit( 0 );
}

Test run:

shadyabhi@archlinux ~ $ ./a.out 
In /tmp/inotify1: 
The file abhijeet was created.
In /tmp/inotify2: 
The file rastogi was created.
^C
shadyabhi@archlinux ~ $
like image 78
Abhijeet Rastogi Avatar answered Feb 05 '23 14:02

Abhijeet Rastogi