Waiting for the file to appear in Linux using inotify

written by - 4 Comments

Imagine a situation where your program has asked a user to create/upload a file to a server and has to wait for it. The easiest solution is to check whether the file exist, wait some period of time using sleep () if it doesn’t and try again. However, it is not clear what period of time to sleep. If you decide to make it a second, then user may experience a second delay in the worst case. This might not be acceptable. So Linux introduced the iNotify subsystem aimed at solving this and many other problems by extending the filesystem with notifications of changes that are reported to the applications.
Here is a simple C++ example illustrating how to check if the file exists and wait for it if it doesn’t:

#include <cstdio>
#include <cstring>
#include <string>
 
#include <unistd.h>
#include <sys/inotify.h>
 
int
main ()
{
    const std::string directory = "/tmp";
    const std::string filename = "test.txt";
    const std::string fullpath = directory + "/" + filename;
 
    int fd = inotify_init ();
    int watch = inotify_add_watch (fd, directory.c_str (),
                                   IN_MODIFY | IN_CREATE | IN_MOVED_TO);
 
    if (access (fullpath.c_str (), F_OK) == 0)
    {
        printf ("File %s exists.\n", fullpath.c_str ());
        return 0;
    }
 
    char buf [1024 * (sizeof (inotify_event) + 16)];
    ssize_t length;
 
    bool isCreated = false;
 
    while (!isCreated)
    {
        length = read (fd, buf, sizeof (buf));
        if (length < 0)
            break;
        inotify_event *event;
        for (size_t i = 0; i < static_cast<size_t> (length);
             i += sizeof (inotify_event) + event->len)
        {
            event = reinterpret_cast<inotify_event *> (&buf[i]);
            if (event->len > 0 && filename == event->name)
            {
                printf ("The file %s was created.\n", event->name);
                isCreated = true;
                break;
            }
        }
    }
 
    inotify_rm_watch (fd, watch);
    close (fd);
}

Note that we subscribe for filesystem notifications before checking if file exists. It is needed in order to avoid a race condition where file is created exactly after we checked for its existence and before we subscribed for notifications.

The similar approach is used, for example, in Transmission BitTorrent client when it monitors the downloads directory for new torrent files and adds them automatically.

4 comments

  1. Free Patch - 17/10/2010 Reply

    Salut! Can I quote piece of the information from your blog if I provide a linkback to your website?

  2. Vlad - 17/10/2010 Reply

    Free Patch, sure.

  3. Keygen - 05/11/2010 Reply

    At least 4 or 5 hundred visitors at your weblog now, nice results for single website.

Leave a Reply

*

You can add images to your comment by clicking here.

© Copyright 2010-2011 Vlad Lazarenko. All rights reserved.