forked from enlightenment/efl
eina - add portable close all fd's we don't need function
close all fd's starting at a given fd and then leving out an exception list specially passed, if any. useful for fork+exec. this uses it in efl's fork+exec paths. @feat
This commit is contained in:
parent
dd941fe4f8
commit
1127409564
|
@ -364,6 +364,10 @@ _impl_ecore_exe_efl_object_finalize(Eo *obj, Ecore_Exe_Data *exe)
|
|||
E_NO_ERRNO(result, close(statusPipe[0]), ok);
|
||||
E_IF_NO_ERRNO(result, eina_file_close_on_exec(statusPipe[1], EINA_TRUE), ok) /* close on exec shows success */
|
||||
{
|
||||
int except[2] = { 0, -1 };
|
||||
|
||||
except[0] = statusPipe[1];
|
||||
eina_file_close_from(3, except);
|
||||
/* Run the actual command. */
|
||||
_ecore_exe_exec_it(exe_cmd, flags); /* no return */
|
||||
}
|
||||
|
|
|
@ -540,6 +540,11 @@ _efl_exe_efl_task_run(Eo *obj, Efl_Exe_Data *pd)
|
|||
pd->env = NULL;
|
||||
}
|
||||
|
||||
// close all fd's other than the first 3 (0, 1, 2) and exited write fd
|
||||
int except[2] = { 0, -1 };
|
||||
except[0] = pd->fd.exited_write;
|
||||
eina_file_close_from(3, except);
|
||||
|
||||
// actually execute!
|
||||
_exec(cmd, pd->flags, td->flags);
|
||||
// we couldn't exec... uh oh. HAAAAAAAALP!
|
||||
|
|
|
@ -36,6 +36,10 @@
|
|||
#endif
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
# include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#define PATH_DELIM '/'
|
||||
|
||||
#include "eina_config.h"
|
||||
|
@ -1252,3 +1256,83 @@ eina_file_statat(void *container, Eina_File_Direct_Info *info, Eina_Stat *st)
|
|||
return 0;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
eina_file_close_from(int fd, int *except_fd)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
// XXX: what do to here? anything?
|
||||
#else
|
||||
#ifdef HAVE_DIRENT_H
|
||||
DIR *dir;
|
||||
|
||||
dir = opendir("/proc/sefl/fd");
|
||||
if (!dir) dir = opendir("/dev/fd");
|
||||
if (dir)
|
||||
{
|
||||
struct dirent *dp;
|
||||
const char *fname;
|
||||
int *closes = NULL;
|
||||
int num_closes = 0, i;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
skip:
|
||||
dp = readdir(dir);
|
||||
if (!dp) break;
|
||||
fname = dp->d_name;
|
||||
|
||||
if ((fname[0] >= '0') && (fname[0] <= '9'))
|
||||
{
|
||||
int num = atoi(fname);
|
||||
if (num >= fd)
|
||||
{
|
||||
if (except_fd)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; except_fd[j] >= 0; j++)
|
||||
{
|
||||
if (except_fd[j] == num) goto skip;
|
||||
}
|
||||
}
|
||||
num_closes++;
|
||||
int *tmp = realloc(closes, num_closes * sizeof(int));
|
||||
if (!tmp) num_closes--;
|
||||
else
|
||||
{
|
||||
closes = tmp;
|
||||
closes[num_closes - 1] = num;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
for (i = 0; i < num_closes; i++) close(closes[i]);
|
||||
free(closes);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
int i, max = 1024;
|
||||
|
||||
# ifdef HAVE_SYS_RESOURCE_H
|
||||
struct rlimit lim;
|
||||
if (getrlimit(RLIMIT_NOFILE, &lim) < 0) return;
|
||||
max = lim.rlim_max;
|
||||
# endif
|
||||
for (i = fd; i < max;)
|
||||
{
|
||||
if (except_fd)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; except_fd[j] >= 0; j++)
|
||||
{
|
||||
if (except_fd[j] == i) goto skip2;
|
||||
}
|
||||
}
|
||||
close(i);
|
||||
skip2:
|
||||
i++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -347,6 +347,23 @@ EAPI Eina_Iterator *eina_file_stat_ls(const char *dir) EINA_WARN_UNUSED_RESULT E
|
|||
*/
|
||||
EAPI int eina_file_statat(void *container, Eina_File_Direct_Info *info, Eina_Stat *buf) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2, 3);
|
||||
|
||||
/**
|
||||
* @brief Close all file descriptors that are open at or above the given fd
|
||||
* @details This closes all open file descriptors that are equal to or of
|
||||
* higher value than the given inpit fd given. This is intended for
|
||||
* niche use like closing all open files just before exec()ing a
|
||||
* new process after calling fork(). The except_fd array can be NULL
|
||||
* if no fd's are to be skipped, but if some fd's are to skip being
|
||||
* closed then this will be an array of fd numbers being terminated
|
||||
* by a fd value of -1.
|
||||
*
|
||||
* @param[in] fd The fd value to begin closing at
|
||||
* @param[in] except_fd An array of fd's not to close terminated by -1 as the last invalid fd
|
||||
*
|
||||
* @since 1.24
|
||||
*/
|
||||
EAPI void eina_file_close_from(int fd, int *except_fd);
|
||||
|
||||
/**
|
||||
* @brief Generates and creates a uniquely named temporary file from a template name.
|
||||
* The generated file is opened with the open(2) @c O_EXCL flag.
|
||||
|
|
Loading…
Reference in New Issue