X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=closefrom.c;h=2cdca655798e1d539fafcc9873671d64b72e756f;hb=d96842b3b08ddb3a3528c7ea8a791ef6a59fb38b;hp=00f3c093fc5fb78826296832a48d226fe46782c2;hpb=c2b0b328d4a66431e671fb26b47997033feb5e29;p=debian%2Fsudo diff --git a/closefrom.c b/closefrom.c index 00f3c09..2cdca65 100644 --- a/closefrom.c +++ b/closefrom.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Todd C. Miller + * Copyright (c) 2004-2005 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "config.h" +#include #include #include @@ -28,6 +28,7 @@ # include # endif #endif /* STDC_HEADERS */ +#include #ifdef HAVE_DIRENT_H # include # define NAMLEN(dirent) strlen((dirent)->d_name) @@ -48,26 +49,67 @@ #include "sudo.h" #ifndef lint -static const char rcsid[] = "$Sudo: closefrom.c,v 1.6 2004/06/01 20:51:56 millert Exp $"; +__unused static const char rcsid[] = "$Sudo: closefrom.c,v 1.6.2.3 2007/06/20 11:06:50 millert Exp $"; #endif /* lint */ +#ifndef HAVE_FCNTL_CLOSEM +# ifndef HAVE_DIRFD +# define closefrom_fallback closefrom +# endif +#endif + /* * Close all file descriptors greater than or equal to lowfd. + * This is the expensive (ballback) method. */ void -closefrom(lowfd) +closefrom_fallback(lowfd) int lowfd; { long fd, maxfd; -#ifdef HAVE_DIRFD - char fdpath[PATH_MAX], *endp; + + /* + * Fall back on sysconf() or getdtablesize(). We avoid checking + * resource limits since it is possible to open a file descriptor + * and then drop the rlimit such that it is below the open fd. + */ +#ifdef HAVE_SYSCONF + maxfd = sysconf(_SC_OPEN_MAX); +#else + maxfd = getdtablesize(); +#endif /* HAVE_SYSCONF */ + if (maxfd < 0) + maxfd = OPEN_MAX; + + for (fd = lowfd; fd < maxfd; fd++) + (void) close((int) fd); +} + +/* + * 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 +void +closefrom(lowfd) + int lowfd; +{ + if (fcntl(lowfd, F_CLOSEM, 0) == -1) + closefrom_fallback(lowfd); +} +#else +# ifdef HAVE_DIRFD +void +closefrom(lowfd) + int lowfd; +{ struct dirent *dent; DIR *dirp; - int len; + char *endp; + long fd; - /* Check for a /proc/$$/fd directory. */ - len = snprintf(fdpath, sizeof(fdpath), "/proc/%ld/fd", (long)getpid()); - if (len != -1 && len <= sizeof(fdpath) && (dirp = opendir(fdpath))) { + /* Use /proc/self/fd directory if it exists. */ + if ((dirp = opendir("/proc/self/fd")) != NULL) { while ((dent = readdir(dirp)) != NULL) { fd = strtol(dent->d_name, &endp, 10); if (dent->d_name != endp && *endp == '\0' && @@ -76,22 +118,7 @@ closefrom(lowfd) } (void) closedir(dirp); } else -#endif - { - /* - * Fall back on sysconf() or getdtablesize(). We avoid checking - * resource limits since it is possible to open a file descriptor - * and then drop the rlimit such that it is below the open fd. - */ -#ifdef HAVE_SYSCONF - maxfd = sysconf(_SC_OPEN_MAX); -#else - maxfd = getdtablesize(); -#endif /* HAVE_SYSCONF */ - if (maxfd < 0) - maxfd = OPEN_MAX; - - for (fd = lowfd; fd < maxfd; fd++) - (void) close((int) fd); - } + closefrom_fallback(lowfd); } +#endif /* HAVE_DIRFD */ +#endif /* HAVE_FCNTL_CLOSEM */