DannyNiu DannyNiu - 3 months ago 29
C Question

Using system() after fopen() and before the corresponding fclose() (file descriptor leak)

I'm trying to understand the fundamentalities of the file descriptor leaking problem. (If you don't know what it is, just post some code that fits the example.)

So far, I've categorized applications into several types. What I've come up with is that, in POSIX generally, ones that invokes other programs are cautious enough to set CLOEXEC flags on files they don't need child processes to handle.

But there's obviously some programs that uses only the standard C library, and opens files and invokes system commands.

So is there an example (of a valid program) that fopen()s a file, and system() a command, before close()ing it?

I'm looking for examples in C, Objective-C, or PHP. Other languages are also accepted as long as it doesn't have garbage collection.


I guess the pure C language programs won't use system(). Because:

  1. They've no idea what system commands are available.

  2. Ones know what system commands are available, usually know how to use those functionalities through library routines.

  3. It's unlikely that system() would be the equivalent of the GNU syscall() functions on any platform.

For those who're not quite clear about what I'm asking for, I'm asking for an example of valid working program that (possibly due to bad programming practice), uses system() commands while FILE*s are fopen()'ed. And it's for helping me (and others) understand the fundamentalities of the file descriptor leaking problem.


I've noticed some Apple Pro Apps such as Final Cut Pro X have child processes handling media file decoding and frame rendering. At first I thought these would be valid examples of apps that opens file and creates child process.

But, after I looked up XPC on my Mac, I found out these services are started by launchd, and listed as if they were child processes through some special attributes. Which means their FD tables are clean.


The C standard has no notion of file descriptors, hence no notion of file descriptor leakage.

How exactly a C implementation deals with the issue — by forcing CLOEXEC on any file descriptors opened by fopen, or by manually closing files before invoking exec, or by ignoring it altogether — is entirely up to the implementation.

gcc seems to ignore the issue, so if your program opens too many files and calls system, the program invoked by system may not be able to open any additional files. A simple demonstration is below:

#include <stdio.h>
#include <stdlib.h>

void toomanyfiles()
    FILE* f = fopen("example.txt", "r");
    if (f)
        fclose (f);
        system ("cat example.txt");

int main ()
    while (1)
        system ("cat example.txt");