close all open fd's on fork
This commit is contained in:
parent
fd5f1ef5f5
commit
b26cc12513
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (C) 2010 Paul Davis
|
Copyright (C) 2010 Paul Davis
|
||||||
|
Copyright 2005-2008 Lennart Poettering
|
||||||
Author: Robin Gareus <robin@gareus.org>
|
Author: Robin Gareus <robin@gareus.org>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
@ -23,6 +24,9 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#else
|
#else
|
||||||
@ -31,8 +35,11 @@
|
|||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include "system_exec.h"
|
#include "system_exec.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -40,6 +47,104 @@ void * interposer_thread (void *arg);
|
|||||||
|
|
||||||
static void close_fd (int& fd) { if (fd >= 0) ::close (fd); fd = -1; }
|
static void close_fd (int& fd) { if (fd >= 0) ::close (fd); fd = -1; }
|
||||||
|
|
||||||
|
#ifndef __WIN32__
|
||||||
|
/*
|
||||||
|
* This function was part of libasyncns.
|
||||||
|
* LGPL v2.1
|
||||||
|
* Copyright 2005-2008 Lennart Poettering
|
||||||
|
*/
|
||||||
|
static int close_allv(const int except_fds[]) {
|
||||||
|
struct rlimit rl;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
|
||||||
|
DIR *d;
|
||||||
|
|
||||||
|
assert(except_fds);
|
||||||
|
|
||||||
|
if ((d = opendir("/proc/self/fd"))) {
|
||||||
|
struct dirent *de;
|
||||||
|
|
||||||
|
while ((de = readdir(d))) {
|
||||||
|
int found;
|
||||||
|
long l;
|
||||||
|
char *e = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (de->d_name[0] == '.')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
l = strtol(de->d_name, &e, 10);
|
||||||
|
if (errno != 0 || !e || *e) {
|
||||||
|
closedir(d);
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = (int) l;
|
||||||
|
|
||||||
|
if ((long) fd != l) {
|
||||||
|
closedir(d);
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd < 3)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (fd == dirfd(d))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
found = 0;
|
||||||
|
for (i = 0; except_fds[i] >= 0; i++)
|
||||||
|
if (except_fds[i] == fd) {
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) continue;
|
||||||
|
|
||||||
|
if (close(fd) < 0) {
|
||||||
|
int saved_errno;
|
||||||
|
|
||||||
|
saved_errno = errno;
|
||||||
|
closedir(d);
|
||||||
|
errno = saved_errno;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(d);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (fd = 0; fd < (int) rl.rlim_max; fd++) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (fd <= 3)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (i = 0; except_fds[i] >= 0; i++)
|
||||||
|
if (except_fds[i] == fd)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (close(fd) < 0 && errno != EBADF)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* not on windows */
|
||||||
|
|
||||||
|
|
||||||
SystemExec::SystemExec (std::string c, std::string a)
|
SystemExec::SystemExec (std::string c, std::string a)
|
||||||
: cmd(c)
|
: cmd(c)
|
||||||
{
|
{
|
||||||
@ -619,6 +724,11 @@ SystemExec::start (int stderr_mode)
|
|||||||
signal(SIGPIPE, SIG_DFL);
|
signal(SIGPIPE, SIG_DFL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef __WIN32__
|
||||||
|
int good_fds[1] = { 0 };
|
||||||
|
close_allv(good_fds);
|
||||||
|
#endif
|
||||||
|
|
||||||
::execve(argp[0], argp, envp);
|
::execve(argp[0], argp, envp);
|
||||||
/* if we reach here something went wrong.. */
|
/* if we reach here something went wrong.. */
|
||||||
char buf = 0;
|
char buf = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user