--- embedaddon/sudo/compat/closefrom.c 2012/02/21 16:23:02 1.1 +++ embedaddon/sudo/compat/closefrom.c 2014/06/15 16:12:54 1.1.1.4 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2005, 2007, 2010 + * Copyright (c) 2004-2005, 2007, 2010, 2012-2013 * Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any @@ -17,8 +17,9 @@ #include +#ifndef HAVE_CLOSEFROM + #include -#include #include #include #ifdef STDC_HEADERS @@ -30,34 +31,38 @@ # endif #endif /* STDC_HEADERS */ #include -#ifdef HAVE_DIRENT_H -# include -# define NAMLEN(dirent) strlen((dirent)->d_name) +#include +#ifdef HAVE_PSTAT_GETPROC +# include +# include #else -# define dirent direct -# define NAMLEN(dirent) (dirent)->d_namlen -# ifdef HAVE_SYS_NDIR_H -# include +# ifdef HAVE_DIRENT_H +# include +# define NAMLEN(dirent) strlen((dirent)->d_name) +# else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# ifdef HAVE_SYS_NDIR_H +# include +# endif +# ifdef HAVE_SYS_DIR_H +# include +# endif +# ifdef HAVE_NDIR_H +# include +# endif # endif -# ifdef HAVE_SYS_DIR_H -# include -# endif -# ifdef HAVE_NDIR_H -# include -# endif #endif #include "missing.h" -#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) @@ -77,42 +82,71 @@ 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 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; - char *endp; - long fd; - /* Use /proc/self/fd directory if it exists. */ - if ((dirp = opendir("/proc/self/fd")) != 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 = 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 */ +#endif /* HAVE_CLOSEFROM */