如何检测inotify更改的文件名?

问题描述 投票:0回答:1

我想确定由编辑器更改的特定名称,例如 texstudio 或 geany。 我用inotify

#include<stdio.h>
#include<sys/inotify.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>
#include<fcntl.h> // library for fcntl function
//inotify_02.c

#define MAX_EVENTS 1024  /* Maximum number of events to process*/
#define LEN_NAME 1024  /* 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 file_descriptor,watch_descriptor;
 
void sig_handler(int sig){
 
       /* Step 5. Remove the watch descriptor and close the inotify instance*/
       inotify_rm_watch( file_descriptor, watch_descriptor );
       close( file_descriptor );
       exit( 0 );
 
}
 
 
int main(int argc, char **argv){
    char *path_to_be_watched;
    
    signal(SIGINT,sig_handler);
    path_to_be_watched = argv[1];
    
    /* Step 1. Initialize inotify */
    file_descriptor = inotify_init();
    if (fcntl(file_descriptor, F_SETFL, O_NONBLOCK) < 0)  // error checking for fcntl
    exit(2);

    /* Step 2. Add Watch */
    watch_descriptor = inotify_add_watch(file_descriptor,path_to_be_watched,IN_MODIFY | IN_CREATE | IN_DELETE);

    if(watch_descriptor==-1)
        printf("Could not watch : %s\n",path_to_be_watched);
    else
        printf("Watching : %s\n",path_to_be_watched);

    while(1)
    {
        int i=0,length;
        char buffer[BUF_LEN];

        /* Step 3. Read buffer*/
        length = read(file_descriptor,buffer,BUF_LEN);

        /* Step 4. Process the events which has occurred */
        while(i<length)
        {
 
            struct inotify_event *event = (struct inotify_event *) &buffer[i];
 
            if(event->len)
            {
                if ( event->mask & IN_CLOSE  ) 
                /* IN_CLOSE Equates to IN_CLOSE_WRITE | IN_CLOSE_NOWRITE 
                 * File or directory not opened for writing was closed. or
                 * File opened for writing was closed.
                 */
                {
                    if ( event->mask & IN_ISDIR ) 
                    {
                        printf( "File or directory %s not opened for writing was closed.\n", event->name );
                    }
                    else 
                    {
                       printf( "File  %sopened for writing was closed.\n", event->name );
                    }
                }
                /*-------*/
                else 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 );
                    }
                }
                /*-------*/
                else 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.\n", event->name );
                    }
                }
                /*-------*/
                else 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.\n", event->name );
                    }
                }
           }
           i += EVENT_SIZE + event->len;
        }
    }
}

当我使用此软件与 arg 中给定的目录时,我会得到这个,因为文件被编辑器更改了((inotify_02.c)

Watching : /home/francis/.../inotify
The file .goutputstream-V0EIG2 was created.
The file .goutputstream-V0EIG2 was modified.

显然 .goutputstream-V0EIG2 就像进程名称而不是文件名。

当我复制文件(inotify_02.c)时,我复制了新文件的名称

Watching : /home/francis/.../inotify
The file .goutputstream-V0EIG2 was created.
The file .goutputstream-V0EIG2 was modified.
The file inotify_02 (copie).c was created.
The file inotify_02 (copie).c was modified.

我发现了这一点:但是要小心文件编辑器,他们通常不会在现场编辑文件,而是覆盖它(删除然后重写)。因此监视 IN_MODIFY 事件是没有用的。在这种情况下,最相关的是监视相关文件上的 IN_CLOSE_WRITE / IN_MOVED_FROM (取决于编辑器的工作方式),这使得只有在文件稳定后才触发操作,而不是在每次 write() 时触发操作。

默认情况下,因为我独自一人使用我的电脑,所以我现在正在做什么。但是当乳胶编译时会发生很多变化。我的程序只需要识别特定文件上的更改。

有什么办法可以获取真名吗?

c editor inotify
1个回答
0
投票

a mwe 为了显示 stat 为文件提供足够的数据:名称、日期、权限等等....

如果手表文件日期发生变化,这对我有好处

#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <locale.h>
#include <langinfo.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>

struct dirent  *dp;
struct stat     statbuf;
struct passwd  *pwd;
struct group   *grp;
struct tm      *tm;
char            datestring[256];
//stat_02.c
 
char * str_perm(mode_t perms)
{
    char * string_perm = (char *) malloc( 4);
    strcpy(string_perm,(perms & S_IRUSR) ? "r" : "-");
    
    strcat(string_perm,(perms & S_IWUSR) ? "w" : "-");
    strcat(string_perm,(perms & S_IXUSR) ? "x" : "-");
    strcat(string_perm,(perms & S_IRGRP) ? "r" : "-");
    strcat(string_perm,(perms & S_IWGRP) ? "w" : "-");
    strcat(string_perm,(perms & S_IXGRP) ? "x" : "-");
    strcat(string_perm,(perms & S_IROTH) ? "r" : "-");
    strcat(string_perm,(perms & S_IWOTH) ? "w" : "-");
    strcat(string_perm,(perms & S_IXOTH) ? "x" : "-");
    
    return string_perm;
}

int main()
{
    DIR *dir = opendir(".");

    while ((dp = readdir(dir)) != NULL) {

    /* Get entry's information. */
    if (stat(dp->d_name, &statbuf) == -1)
        continue;

    /* Print out type, permissions, and number of links. */
    printf("%10.10s", str_perm (statbuf.st_mode));
    
    printf("%4ld", statbuf.st_nlink);


    /* Print out owner's name if it is found using getpwuid(). */
    if ((pwd = getpwuid(statbuf.st_uid)) != NULL)
        printf(" %-8.8s", pwd->pw_name);
    else
        printf(" %-8d", statbuf.st_uid);


    /* Print out group name if it is found using getgrgid(). */
    if ((grp = getgrgid(statbuf.st_gid)) != NULL)
        printf(" %-8.8s", grp->gr_name);
    else
        printf(" %-8d", statbuf.st_gid);


    /* Print size of file. */
    printf(" %9jd", (intmax_t)statbuf.st_size);


    tm = localtime(&statbuf.st_mtime);


    /* Get localized date string. */
    strftime(datestring, sizeof(datestring), nl_langinfo(D_T_FMT), tm);


    printf(" %s %s\n", datestring, dp->d_name);
}
}
© www.soinside.com 2019 - 2024. All rights reserved.