[GRASS-dev] Open/close db drivers order

Glynn Clements glynn at gclements.plus.com
Thu Oct 22 14:58:50 PDT 2015


Radim Blazek wrote:

> But there may be other file descriptors not related to db drivers. Is
> it possible to close all of them in driver process?

Maybe.

When fork() clones a process, the descriptor table is cloned along
with everything else. When the process changes its program with
execve(), any descriptors without the FD_CLOEXEC flag remain open.

But the new program won't know of their existence, where they came
from, what they refer to, etc. The "knowledge" about the descriptors
only exists in the original program, so closing specific descriptors
(or setting their close-on-exec flags) has to be done prior to the
execve().

Once the program is changed and that information is lost, about the
only option available to the driver is to close *every* open
descriptor except for 0, 1 and 2 (standard input/output/error). This
needs to be done before calling any library function which might
create additional descriptors (which in practice means almost any
library function).

Even that is complicated by the fact that there's no standard
mechanism for discovering the highest open descriptor number. You just
have to iterate until reaching some arbitrary maximum, or until some
(again, arbitrary) number of consecutive descriptors are found to be
unused (by close() failing with EBADF), and hope that's all of them.

The only robust solution is for the original program to systematically
set the close-on-exec flag on every descriptor *except* those which
are meant to be inherited.

The fact that descriptors are always inherited across fork() and
preserved across execve() by default is generally considered to be a
mistake in the POSIX API, but we're now stuck with it.

-- 
Glynn Clements <glynn at gclements.plus.com>


More information about the grass-dev mailing list