version 1.1, 2012/02/21 16:23:02
|
version 1.1.1.4, 2014/06/15 16:12:54
|
Line 1
|
Line 1
|
/* |
/* |
* Copyright (c) 2004-2005, 2007, 2010 | * Copyright (c) 2004-2005, 2007, 2010, 2012-2013 |
* Todd C. Miller <Todd.Miller@courtesan.com> |
* Todd C. Miller <Todd.Miller@courtesan.com> |
* |
* |
* Permission to use, copy, modify, and distribute this software for any |
* Permission to use, copy, modify, and distribute this software for any |
Line 17
|
Line 17
|
|
|
#include <config.h> |
#include <config.h> |
|
|
|
#ifndef HAVE_CLOSEFROM |
|
|
#include <sys/types.h> |
#include <sys/types.h> |
#include <sys/param.h> |
|
#include <unistd.h> |
#include <unistd.h> |
#include <stdio.h> |
#include <stdio.h> |
#ifdef STDC_HEADERS |
#ifdef STDC_HEADERS |
Line 30
|
Line 31
|
# endif |
# endif |
#endif /* STDC_HEADERS */ |
#endif /* STDC_HEADERS */ |
#include <fcntl.h> |
#include <fcntl.h> |
#ifdef HAVE_DIRENT_H | #include <limits.h> |
# include <dirent.h> | #ifdef HAVE_PSTAT_GETPROC |
# define NAMLEN(dirent) strlen((dirent)->d_name) | # include <sys/param.h> |
| # include <sys/pstat.h> |
#else |
#else |
# define dirent direct | # ifdef HAVE_DIRENT_H |
# define NAMLEN(dirent) (dirent)->d_namlen | # include <dirent.h> |
# ifdef HAVE_SYS_NDIR_H | # define NAMLEN(dirent) strlen((dirent)->d_name) |
# include <sys/ndir.h> | # endif |
| # define dirent direct |
| # define NAMLEN(dirent) (dirent)->d_namlen |
| # ifdef HAVE_SYS_NDIR_H |
| # include <sys/ndir.h> |
| # endif |
| # ifdef HAVE_SYS_DIR_H |
| # include <sys/dir.h> |
| # endif |
| # ifdef HAVE_NDIR_H |
| # include <ndir.h> |
| # endif |
# endif |
# endif |
# ifdef HAVE_SYS_DIR_H |
|
# include <sys/dir.h> |
|
# endif |
|
# ifdef HAVE_NDIR_H |
|
# include <ndir.h> |
|
# endif |
|
#endif |
#endif |
|
|
#include "missing.h" |
#include "missing.h" |
|
|
#ifndef HAVE_FCNTL_CLOSEM | #if defined(HAVE_FCNTL_CLOSEM) && !defined(HAVE_DIRFD) |
# ifndef HAVE_DIRFD | # define closefrom closefrom_fallback |
# define closefrom_fallback closefrom | |
# endif | |
#endif |
#endif |
|
|
/* |
/* |
* Close all file descriptors greater than or equal to lowfd. |
* Close all file descriptors greater than or equal to lowfd. |
* This is the expensive (ballback) method. | * This is the expensive (fallback) method. |
*/ |
*/ |
void |
void |
closefrom_fallback(int lowfd) |
closefrom_fallback(int lowfd) |
Line 77 closefrom_fallback(int lowfd)
|
Line 82 closefrom_fallback(int lowfd)
|
if (maxfd < 0) |
if (maxfd < 0) |
maxfd = OPEN_MAX; |
maxfd = OPEN_MAX; |
|
|
for (fd = lowfd; fd < maxfd; fd++) | for (fd = lowfd; fd < maxfd; fd++) { |
| #ifdef __APPLE__ |
| /* Avoid potential libdispatch crash when we close its fds. */ |
| (void) fcntl((int) fd, F_SETFD, FD_CLOEXEC); |
| #else |
(void) close((int) fd); |
(void) close((int) fd); |
|
#endif |
|
} |
} |
} |
|
|
/* |
/* |
* Close all file descriptors greater than or equal to lowfd. |
* Close all file descriptors greater than or equal to lowfd. |
* We try the fast way first, falling back on the slow method. |
* We try the fast way first, falling back on the slow method. |
*/ |
*/ |
#ifdef HAVE_FCNTL_CLOSEM | #if defined(HAVE_FCNTL_CLOSEM) |
void |
void |
closefrom(int lowfd) |
closefrom(int lowfd) |
{ |
{ |
if (fcntl(lowfd, F_CLOSEM, 0) == -1) |
if (fcntl(lowfd, F_CLOSEM, 0) == -1) |
closefrom_fallback(lowfd); |
closefrom_fallback(lowfd); |
} |
} |
#else | #elif defined(HAVE_PSTAT_GETPROC) |
# ifdef HAVE_DIRFD | |
void |
void |
closefrom(int lowfd) |
closefrom(int lowfd) |
{ |
{ |
struct dirent *dent; | struct pst_status pstat; |
| int fd; |
| |
| if (pstat_getproc(&pstat, sizeof(pstat), 0, getpid()) != -1) { |
| for (fd = lowfd; fd <= pstat.pst_highestfd; fd++) |
| (void) close(fd); |
| } else { |
| closefrom_fallback(lowfd); |
| } |
| } |
| #elif defined(HAVE_DIRFD) |
| void |
| closefrom(int lowfd) |
| { |
| const char *path; |
DIR *dirp; |
DIR *dirp; |
char *endp; |
|
long fd; |
|
|
|
/* Use /proc/self/fd directory if it exists. */ | /* Use /proc/self/fd (or /dev/fd on FreeBSD) if it exists. */ |
if ((dirp = opendir("/proc/self/fd")) != NULL) { | # if defined(__FreeBSD__) || defined(__APPLE__) |
| path = "/dev/fd"; |
| # else |
| path = "/proc/self/fd"; |
| # endif |
| if ((dirp = opendir(path)) != NULL) { |
| struct dirent *dent; |
while ((dent = readdir(dirp)) != NULL) { |
while ((dent = readdir(dirp)) != NULL) { |
fd = strtol(dent->d_name, &endp, 10); | const char *errstr; |
if (dent->d_name != endp && *endp == '\0' && | int fd = strtonum(dent->d_name, lowfd, INT_MAX, &errstr); |
fd >= 0 && fd < INT_MAX && fd >= lowfd && fd != dirfd(dirp)) | if (errstr == NULL && fd != dirfd(dirp)) { |
(void) close((int) fd); | # ifdef __APPLE__ |
| /* Avoid potential libdispatch crash when we close its fds. */ |
| (void) fcntl(fd, F_SETFD, FD_CLOEXEC); |
| # else |
| (void) close(fd); |
| # endif |
| } |
} |
} |
(void) closedir(dirp); |
(void) closedir(dirp); |
} else |
} else |
closefrom_fallback(lowfd); |
closefrom_fallback(lowfd); |
} |
} |
#endif /* HAVE_DIRFD */ |
|
#endif /* HAVE_FCNTL_CLOSEM */ |
#endif /* HAVE_FCNTL_CLOSEM */ |
|
#endif /* HAVE_CLOSEFROM */ |