linux无限通知,非阻塞调用

时间:2015-07-03 08:15:52

标签: c linux inotify

我编写了一个代码,用于监视文件夹testnotify以查找任何新文件夹/文件的创建或删除。代码如下。

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

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

int main( )
{
    int length, i = 0;
    int fd;
    int wd;
    char buffer[EVENT_BUF_LEN];
    fd = inotify_init();

    if ( fd < 0 ) {
        perror( "inotify_init" );
    }
    wd = inotify_add_watch( fd, "testnotify", IN_CLOSE_WRITE | IN_CREATE | IN_DELETE  | IN_OPEN);
    while(1)
    {
        length = read( fd, buffer, EVENT_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( "New directory %s created.\n", event->name );
                    }
                    else {
                        printf( "New file %s created.\n", event->name );
                    }
                }
                else if ( event->mask & IN_CLOSE_WRITE ) {
                    if ( event->mask & IN_ISDIR ) {
                        printf( "Directory %s updated.\n", event->name );
                    }
                    else {
                        printf( "File %s updated\n", event->name );
                    }
                }
                else if ( event->mask & IN_DELETE ) {
                    if ( event->mask & IN_ISDIR ) {
                        printf( "Directory %s deleted.\n", event->name );
                    }
                    else {
                        printf( "File %s deleted.\n", event->name );
                    }
                }
            }
            i += EVENT_SIZE + event->len;
        }

        i = 0;
        length = 0;
        memset(buffer, 0, EVENT_BUF_LEN);
    }
    inotify_rm_watch( fd, wd );
    close( fd );
}

我现在关注的是此代码以阻止模式运行。我需要一个可以在非阻塞模式下执行类似活动的系统。

一种选择是在通知程序的fd上使用选择

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

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

int main( )
{
    int length, i = 0;
    int fd;
    int wd;
    char buffer[EVENT_BUF_LEN];

    struct timeval time;
    fd_set rfds;
    int ret;

    /*creating the INOTIFY instance*/
    fd = inotify_init();
    /*checking for error*/
    if ( fd < 0 ) {
        perror( "inotify_init" );
    }
    /*adding the “/tmp” directory into watch list. Here, the suggestion is to validate the existence of the directory before adding into monitoring list.*/
    wd = inotify_add_watch( fd, "testnoti", IN_CLOSE_WRITE | IN_CREATE | IN_DELETE | IN_ALL_EVENTS | IN_OPEN);

    /* timeout after five seconds */
    time.tv_sec = 5;
    time.tv_usec = 0;

    /* zero-out the fd_set */
    FD_ZERO (&rfds);
    /*
     * add the inotify fd to the fd_set -- of course,
     * your application will probably want to add
     * other file descriptors here, too
     */
    FD_SET (fd, &rfds);

    ret = select (fd + 1, &rfds, NULL, NULL, &time);
    if (ret < 0)
        printf("error case in select");
    else if (!ret)
        printf("error case in select timed out");
    /* timed out! */
    else if (FD_ISSET (fd, &rfds))
        /* inotify events are available! */
    {
        while(1)
        {
            /*read to determine the event change happens on “/tmp” directory. Actually this read blocks until the change event occurs*/
            length = read( fd, buffer, EVENT_BUF_LEN );
            /*checking for error*/
            if ( length < 0 ) {
                perror( "read" );
            }
            /*actually read return the list of change events happens. Here, read the change event one by one and process it accordingly.*/
            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( "New directory %s created.\n", event->name );
                        }
                        else {
                            printf( "New file %s created.\n", event->name );
                        }
                    }
                    else if ( event->mask & IN_CLOSE_WRITE ) {
                        if ( event->mask & IN_ISDIR ) {
                            printf( "Directory %s updated.\n", event->name );
                        }
                        else {
                            printf( "File %s updated\n", event->name );
                        }
                    }
                    else if ( event->mask & IN_DELETE ) {
                        if ( event->mask & IN_ISDIR ) {
                            printf( "Directory %s deleted.\n", event->name );
                        }
                        else {
                            printf( "File %s deleted.\n", event->name );
                        }
                    }
                }
                i += EVENT_SIZE + event->len;
            }

            i = 0;
            length = 0;
            memset(buffer, 0, EVENT_BUF_LEN);
            /*removing the “/tmp” directory from the watch list.*/
        }
    }
    inotify_rm_watch( fd, wd );

    /*closing the INOTIFY instance*/
    close( fd );

}

我有些不知道如果使用上述程序我能够实现非阻塞功能。非常感谢,如果有人可以帮助使这些代码更加优化,或至少引导我使用它。

0 个答案:

没有答案