5

SUSv4 does not list opendir, readdir, closedir, etc. in its list of async-signal-safe functions.

Is there a safe way to read a directory listing from a signal handler?

e.g. is it possible to 'open' the directory and somehow slurp out the raw directory listing? If so what kind of data structure is returned by 'read'?

Or maybe on Linux there are certain system calls that are async-signal-safe even though SUSv4 / POSIX does not require it that could be used?

atomice
  • 3,062
  • 17
  • 23
  • I think it would not be a problem if you read directory entries using the system calls directly (not using the opendir()... wrappers) as long as you do not share the file handle between the signal handler and some other code and the signal handler cannot be nested. I'm not sure about this. – Martin Rosenau Aug 30 '13 at 19:04
  • 1
    This sounds like a terrible program design failure. – Lothar Nov 30 '15 at 01:58

1 Answers1

3

If you know in advance which directory you need to read, you could call opendir() outside the signal handler (opendir() calls malloc(), so you can't run it from within the handler) and keep the DIR* in a static variable somewhere. When your signal handler runs, you should be able to get away with calling readdir_r() on that handle as long as you can guarantee that only that one signal handler would use the DIR* handle at any moment. There is a lock field in the DIR that is taken by readdir() and readdir_r(), so if, say, you used the DIR* from two signal handlers, or you registered the same handler to handle multiple signals, you may end up with a deadlock due to the lock never being released by the interrupted handler.

A similar approach appears to also work to read a directory from a child process after calling fork() but before calling execve().

Michael Percy
  • 293
  • 1
  • 9