2009-10-29 10 views
15

Ich implementiere eine Bibliothek, um Befehle auszuführen. Die Bibliothek ist C, unter Linux.wie Sie Close-on-Exec standardmäßig festlegen

Es führt derzeit einen Aufruf popen() aus, um einen Befehl auszuführen und Ausgabe zu erhalten. Das Problem besteht darin, dass der Befehl alle aktuell geöffneten Dateihandler erbt.

Wenn ich eine fork/exec gemacht habe, konnte ich die Handler in Kind explizit schließen. Aber das bedeutet, popen() erneut zu implementieren.

Kann ich Close-on-Exec auf allen Handlern einstellen, ohne sie nacheinander durchlaufen zu müssen?

Kann ich Close-on-Exec als Standard für den Prozess festlegen?

Danke!

+0

Wenn Sie die Dateideskriptoren durchlaufen, lesen Sie das Verzeichnis/proc/self/fd /, um nur die zu verwenden, die verwendet werden, und nicht jeden möglichen Dateideskriptor. – mark4o

Antwort

25

Nein und nein.

Sie müssen nur vorsichtig sein und Close-on-Exec für alle Dateideskriptoren festlegen, die Ihnen wichtig sind.

einstellen es einfach ist, aber:

#include <fcntl.h> 
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); 

#include <unistd.h> 
/* please don't do this */ 
for (i = getdtablesize(); i --> 3;) { 
    if ((flags = fcntl(i, F_GETFD)) != -1) 
     fcntl(fd, F_SETFD, flags | FD_CLOEXEC); 
} 

Wenn Sie Linux-Kernel laufen ≥ 2.6.23 und glibc ≥ 2.7, open (zusammen mit anderen ähnlichen syscalls) übernimmt eine neue Flagge O_CLOEXEC:

#include <unistd.h> 
fd = open("...", ... | O_CLOEXEC); 

Wenn Sie mit Linux-Kernel 2.6.24 ≥ und glibc ≥ 2.7, fcntl ein neues Argument akzeptiert F_DUPFD_CLOEXEC :

#include <fcntl.h> 
newfd = fcntl(oldfd, F_DUPFD_CLOEXEC); 

Wenn Sie Linux-Kernel 2.6.27 ≥ und glibc laufen ≥ 2.9 gibt es neue syscalls pipe2, dup3 etc. und viele mehr syscalls gewinnen neue *_CLOEXEC Fahnen:

#define _GNU_SOURCE 
#include <unistd.h> 
pipe2(pipefds, O_CLOEXEC); 
dup3(oldfd, newfd, O_CLOEXEC); 

beachten Sie, dass POSIXspecifies dass

Die popen() Funktion soll sicherstellen, dass alle Ströme von vorherigen popen() Aufrufen, die in dem übergeordneten Prozess geöffnet bleiben, in dem neuen unterordneten Prozess geschlossen werden.

also, wenn Sie besorgt sind über , dass Leck, nicht sein.

+0

ich bin eine Bibliothek, ich kontrolliere nicht, wie meine Benutzer Dateien öffnen, also ist die Verwendung von Flags in open() keine Option –

+0

Schade, du hast kein Glück - UNIX (und Linux) lässt dich nicht ändern zugrundeliegende Semantik von 'open' et al. Du musst nur damit leben, wie alle anderen auch. – ephemient

+0

Siehe http://lkml.org/lkml/2004/3/29/191 für ein Beispiel für einen Cloexec-by-Default-Switch-Vorschlag, der abgeschossen wird. Dies wurde viele Male vorgeschlagen und ebenso oft abgelehnt. – ephemient

-2

Kinda alte Frage, aber wie über die Verwendung getpid() in Kind nach fork(), dann schauen Sie in /proc/PID/fd/ Verzeichnis und schließen Sie einfach alle Deskriptoren Sie dort finden (mit Ausnahme von 0, 1, 2 und diejenige, die Sie erhalten von opendir()) und dann execve()?

Verwandte Themen