cómo establecer close-on-exec por defecto

Estoy implementando una biblioteca para ejecutar comandos. La biblioteca es C, en Linux.

Actualmente realiza una llamada a popen () para ejecutar un comando y obtener resultados. El problema es que el comando hereda todos los manejadores de archivos actualmente abiertos.

Si hiciera un fork / exec, podría cerrar los manejadores en child explícitamente. Pero eso significa volver a implementar popen ().

¿Puedo establecer close-on-exec en todos los controladores sin recorrerlos uno a uno?

¿Puedo configurar close-on-exec por defecto para el proceso?

¡Gracias!

No y no.

Simplemente debe tener cuidado y establecer close-on-exec en todos los descriptores de archivos que le interesan.

Sin embargo, configurarlo es fácil:

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

Si está ejecutando kernel de Linux ≥2.6.23 y glibc ≥2.7, open (junto con otras syscalls similares) acepta una nueva bandera O_CLOEXEC :

 #include  fd = open("...", ... | O_CLOEXEC); 

Si está ejecutando kernel de Linux ≥2.6.24 y glibc ≥2.7, fcntl acepta un nuevo argumento F_DUPFD_CLOEXEC :

 #include  newfd = fcntl(oldfd, F_DUPFD_CLOEXEC); 

Si está ejecutando kernel de Linux ≥2.6.27 y glibc ≥2.9, hay nuevas llamadas de sistema pipe2 , dup3 , etc., y muchas más syscalls obtienen nuevas banderas *_CLOEXEC :

 #define _GNU_SOURCE #include  pipe2(pipefds, O_CLOEXEC); dup3(oldfd, newfd, O_CLOEXEC); 

Tenga en cuenta que POSIX especifica que

La función popen () asegurará que cualquier flujo de llamadas popen () anteriores que permanecen abiertas en el proceso principal se cierre en el nuevo proceso hijo.

entonces si te preocupa esa fuga, no lo seas.

Una vieja pregunta, pero ¿qué tal si utilizas getpid() en child after fork() , luego miras en el /proc/PID/fd/ y cierras todos los descriptores que encuentres allí (excepto 0, 1, 2 y el que obtienes de opendir() ) y luego execve() ?