[Xcb] [PATCH] Open the X11 socket with close-on-exec flag

Rémi Denis-Courmont remi at remlab.net
Wed Feb 17 00:47:39 PST 2010

On Tue, 16 Feb 2010 22:20:13 -0800, Barton C Massey <bart at cs.pdx.edu>
> Not that.  If the application allocates a resource from a C
> library, e.g. by calling xcb_connect(), it should be
> prepared to dispose of this resource, e.g. by calling
> xcb_disconnect(), at appropriate times.  If the resource
> includes a file descriptor, as an xcb_connection most
> explicitly does, then the application should know that after
> a fork() and before the corresponding exec() is one of those
> times.

Most libraries cannot be cleanly closed after a fork(). XCB fails
completely here as it uses pthread. pthread_atfork() would fix that, but I
doubt anyone would want to go that path...

But that is irrelevant. The piece of code that forks is typically somewhere
completely different from the component that connects to X, if not in a
different thread. Thus, there are two ways to fix the issue:
* the super mutex idea: take the mutex before forking *or* and before open
a descriptor until marking it close-on-exec.
* thread-safe close-on-exec (Linux-only so far).

> It's always nice when, as in the case of memory allocations,
> this application responsibility can be ignored and the
> library or OS will do "the right thing" automatically.  But
> file descriptors are persistent across exec() for good
> reasons.

Yes, sure. So that you can inherit the standard input/output/error, pipe
stuff, etc.

> I'm not even entirely sure that XCB's behavior of
> marking fds CLOEXEC by default is a good idea--I can imagine
> situations in which the user might want to turn it back off.

They have had the same discussion in ALSA 10 years ago, came to the same
conclusion. Then they finally switched to close-on-exec in the latest
release of libasound.

The library internal state is lost with exec(). Then there is no use to the
descriptor. The protocol state machine is irreversibly lost, you cannot
talk to the server. In fact, because XCB uses pthread, you cannot even
preserve the XCB state across fork() - mutexes and condition variables
become stale.

> In other words, application developers like to pretend that
> this is the "library problem". Namely the library should
> have some kind of super table to keep track of what the
> application is doing and magically make the app right behind
> its back. :-) :-)

The library "cluttered" the application process state with its descriptor.
That's the libraries problem. The application does not even know about that
file descriptor. Setting close-on-exec seems logical, if the library is not
expected to survive fork+exec. I guess that's why XCB already does mark
close-on-exec, albeit in a portable but not-thread-safe manner.

It just so happens, as you note that file descriptor are special because
they persist across exec by default (as do signal masks and environment
variables), whereas especially threads, memory mappings and heap
allocations do not.

Rémi Denis-Courmont

More information about the Xcb mailing list