diff options
author | Guillem Jover <guillem@hadrons.org> | 2014-11-02 00:23:00 +0100 |
---|---|---|
committer | Guillem Jover <guillem@hadrons.org> | 2015-09-23 07:59:34 +0200 |
commit | 3881c4fc68c7257ed22e1a25804039db5c9a0c95 (patch) | |
tree | f0801d006e4b831b963a7ee35e33bf19d431c06c /src | |
parent | 3a3d87d7301794bd4950bb583dfa590981b842e2 (diff) |
Update closefrom() function
Import from sudo. Adapt the build system to detect the required features.
Diffstat (limited to 'src')
-rw-r--r-- | src/closefrom.c | 105 |
1 files changed, 69 insertions, 36 deletions
diff --git a/src/closefrom.c b/src/closefrom.c index b7e2ad5..423a004 100644 --- a/src/closefrom.c +++ b/src/closefrom.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2005, 2007, 2010 + * Copyright (c) 2004-2005, 2007, 2010, 2012-2014 * Todd C. Miller <Todd.Miller@courtesan.com> * * Permission to use, copy, modify, and distribute this software for any @@ -18,7 +18,6 @@ #include <config.h> #include <sys/types.h> -#include <sys/param.h> #include <unistd.h> #include <stdio.h> #ifdef STDC_HEADERS @@ -30,20 +29,26 @@ # endif #endif /* STDC_HEADERS */ #include <fcntl.h> -#ifdef HAVE_DIRENT_H -# include <dirent.h> -# define NAMLEN(dirent) strlen((dirent)->d_name) +#include <limits.h> +#ifdef HAVE_PSTAT_GETPROC +# include <sys/param.h> +# include <sys/pstat.h> #else -# 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> +# ifdef HAVE_DIRENT_H +# include <dirent.h> +# define NAMLEN(dirent) strlen((dirent)->d_name) +# else +# 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 @@ -51,15 +56,13 @@ # define OPEN_MAX 256 #endif -#ifndef HAVE_FCNTL_CLOSEM -# ifndef HAVE_DIRFD -# define closefrom_fallback closefrom -# endif +#if defined(HAVE_FCNTL_CLOSEM) && !defined(HAVE_DIRFD) +# define closefrom closefrom_fallback #endif /* * Close all file descriptors greater than or equal to lowfd. - * This is the expensive (ballback) method. + * This is the expensive (fallback) method. */ void closefrom_fallback(int lowfd) @@ -79,44 +82,74 @@ closefrom_fallback(int lowfd) if (maxfd < 0) 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); +#endif + } } /* * Close all file descriptors greater than or equal to lowfd. * We try the fast way first, falling back on the slow method. */ -#ifdef HAVE_FCNTL_CLOSEM +#if defined(HAVE_FCNTL_CLOSEM) void closefrom(int lowfd) { if (fcntl(lowfd, F_CLOSEM, 0) == -1) closefrom_fallback(lowfd); } -#else -# ifdef HAVE_DIRFD +#elif defined(HAVE_PSTAT_GETPROC) +void +closefrom(int lowfd) +{ + 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) { - struct dirent *dent; + const char *path; DIR *dirp; - char *endp; - long fd; - /* Use /proc/self/fd directory if it exists. */ - dirp = opendir("/proc/self/fd"); - if (dirp != NULL) { + /* Use /proc/self/fd (or /dev/fd on FreeBSD) if it exists. */ +# 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) { - fd = strtol(dent->d_name, &endp, 10); - if (dent->d_name != endp && *endp == '\0' && - fd >= 0 && fd < INT_MAX && fd >= lowfd && - fd != dirfd(dirp)) - (void)close((int)fd); + const char *errstr; + int fd; + + fd = strtonum(dent->d_name, lowfd, INT_MAX, &errstr); + if (errstr == NULL && fd != dirfd(dirp)) { +# 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); } else closefrom_fallback(lowfd); } -#endif /* HAVE_DIRFD */ #endif /* HAVE_FCNTL_CLOSEM */ |