Skip to content

readdir() skips files if the directory is modified, behaviour is not POSIX-compliant. #7

@Vincent-Dalstra

Description

@Vincent-Dalstra

This causes problems when deleting files in a directory that is currently open.

A good example is the following code: it is supposed to delete all the files in a directory, but it will instead skip every second file.

#include <sys/unistd.h>
#include <sys/dirent.h>

int delete_all_files(const char* dirpath)
{
    DIR* dir = opendir(dirpath);
    if (dir == NULL) return -1;

    struct dirent* entry;
    while ((entry = readdir(dir)) != NULL) {
        if (entry->d_type != DT_REG) continue;
        char path[PATH_MAX];
        strcpy(path, dirpath);
        strcat(path, "/");
        strcat(path, entry->d_name);
        unlink(path);
    }
    closedir(dir);
    return 0;
}

Following POSIX specifications, the function should work:

If a file is removed from or added to the directory after the most recent call to opendir() or rewinddir(), whether a subsequent call to readdir_r() returns an entry for that file is unspecified.

The source of the problem is the way directory handles currently work; they record a pointer to the directory object (ramfs_fs_t), and an index (loc) indicating position. However, when a file is deleted, it causes all entries after it to be moved back a space. This MAY cause an entry to get skipped.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions