Retrieve the full path name from inotify_event

2020-04-04 07:12发布

问题:

The inotify_event struct looks like this :

struct inotify_event {
int      wd;       /* Watch descriptor */
uint32_t mask;     /* Mask of events */
uint32_t cookie;   /* Unique cookie associating related
                      events (for rename(2)) */
uint32_t len;      /* Size of name field */
char     name[];   /* Optional null-terminated name */

};

The name part stores only the file name(not the path to the file). How do we get the fully qualified path from the inotify_event struct or do I have to wrap my own struct around it ?

Edit: I wait for the events for around 2s and then process it on one go.I maintain a queue of events. My question is whether I can get the complete path to my file from the inotify_event struct only ?

The number of events per second is large.

回答1:

There are two options:

  1. You're watching a file. You have passed its name to inotify_add_watch, and got a watch descriptor. If you get an event, you can figure out the file by the watch descriptor.

  2. You're watching a directory. Again, you have passed the directory name to inotify_add_watch, and can find which name it was, based on the watch ID. Now inotify_event.name contains the file name. Concatenate the two and you're done.



回答2:

I think you need to keep track of each of the watch descriptors as you add them in some structure (all with the full path when you add it). Then, when you receive an event, look up the full path in that structure by using the wd in the event.

wd identifies the watch for which this event occurs. It is one of the watch descriptors returned by a previous call to inotify_add_watch(2).

http://www.kernel.org/doc/man-pages/online/pages/man7/inotify.7.html

Hope that helps...



回答3:

Associate (with a struct) the resulted watch descriptors with the path you add to be watched. Thus you'll created a list of watches. When you get an event it contains the watch descriptor, thus, you'll find the path associated with this watch descriptor from the list of watches. Concatenate the name you get from the event struct with the path you get from the list of watches. Also when you add a path to watch, at this time you'll also add recursively all the sub-paths in the same way you added the parent path.



回答4:

This is ok as far as it goes, but it is not the whole answer.

If you have a directory structure and you are watching file & dir events and it looks like this: /root/dir1 & /root/dir2, then you will not have correct resolution of where a file or dir was created in dir1 or dir2, even after you add them to the watch list.

Inotify returns the name of the item and does not tell you which dir it was in.



回答5:

The inotify system, uses contiguous numbers as watch descriptors, let's say you want to watch 3 directories, the ../A , the ../B and the ../C , if lets say, I create a file inside ../A , then the watch descriptor return from read() will be 1., if i create a file inside ../C , the watch descriptor will be 3 and so on. So, the association is pretty easy, you can create an array with the paths, and apply inotify_add_watch() to each of them, then, if a event has the watch descriptor x, just piece together the pathsArray[x-1] with the event->name and you have the path :)

std::string getPathFromEvent(struct inotify_event *ptr){
    std::stringstream builder ;
    builder<<directories->DetectedDirectories.operator[](ptr->wd-1).string();
    builder<<ptr->name;
    return builder.str();
}


标签: c linux inotify