3

This page describes the guaranteed behavior of the functions readdir and readdir_r and contains the following sentence:

After a call to fork(), either the parent or child (but not both) may continue processing the directory stream using readdir(), rewinddir() or seekdir(). If both the parent and child processes use these functions, the result is undefined.

I'm writing a fork-safe wrapper around the DIR*-related family of functions as an exercise and I'm wondering whether it's safe to closedir the directory stream in both the parent and the child simultaneously or whether the process that doesn't continue reading from the directory stream isn't supposed to interact with the directory stream at all.

9
  • 1
    Executing in other process needs ptrace. Or you have setup IPC between parent and child so they can communicate and do the requested action. Commented Mar 22, 2019 at 1:49
  • @炸鱼薯条德里克 I was going to have a static atomic flag and register a fork handler and force the user to pick when opendiring the directory whether the parent or child inherits it on fork. My wrapper library that doesn't exist yet will promise nothing if you use the unwrapped library calls in addition to the wrapper. Commented Mar 22, 2019 at 2:00
  • Don't know what you're talking about. If you want disallow some process from accessing some file, then use mount namespace or simply revoke the file permissions for that user or use selinux or whatever. Then that process can only get an fd from another privileged process Commented Mar 22, 2019 at 2:03
  • @炸鱼薯条德里克 I see. I'm not trying to force processes that I have no control over to "play by the POSIX rules" or prevent them for accessing particular files. I'm trying to understand what exactly the POSIX rules are regarding directory streams. My motivation for understanding what the rules are is to write a wrapper library around the POSIX API that makes it easier to write programs that only use the API in defined ways. Commented Mar 22, 2019 at 2:13
  • @炸鱼薯条德里克 there’s no IPC or ptrace here, the fds are shared because opendir was called before fork. The relevant scenario is fork without exec, so the execution context is identical in the parent and child. Commented Mar 22, 2019 at 6:10

1 Answer 1

2

As a general comment, I recommend referring to the current description of readdir (it doesn’t change anything here).

closedir does two things in practice: it frees the memory allocated by the C library to keep track of the directory stream, and if the opendir/readdir/closedir family of functions are implemented using file descriptors, it closes the file descriptor. Both of these operations apply to the process calling them, not a potential parent or child from a fork: freeing the directory stream only affects the calling process’ memory (if necessary, creating a copy of the relevant pages to make changes to them independently of any other process with a shared memory map from a copy-on-write fork), and closing the file descriptor only affects the current process (if another process has a file descriptor sharing the underlying file description, the file description isn’t released).

Thus, while readdir isn’t safe to call from different processes on a shared directory stream (because of the underlying shared file description), closedir is safe.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .