File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / compat / closefrom.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 16:12:54 2014 UTC (10 years ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_10p3_0, v1_8_10p3, HEAD
sudo v 1.8.10p3

    1: /*
    2:  * Copyright (c) 2004-2005, 2007, 2010, 2012-2013
    3:  *	Todd C. Miller <Todd.Miller@courtesan.com>
    4:  *
    5:  * Permission to use, copy, modify, and distribute this software for any
    6:  * purpose with or without fee is hereby granted, provided that the above
    7:  * copyright notice and this permission notice appear in all copies.
    8:  *
    9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   16:  */
   17: 
   18: #include <config.h>
   19: 
   20: #ifndef HAVE_CLOSEFROM
   21: 
   22: #include <sys/types.h>
   23: #include <unistd.h>
   24: #include <stdio.h>
   25: #ifdef STDC_HEADERS
   26: # include <stdlib.h>
   27: # include <stddef.h>
   28: #else
   29: # ifdef HAVE_STDLIB_H
   30: #  include <stdlib.h>
   31: # endif
   32: #endif /* STDC_HEADERS */
   33: #include <fcntl.h>
   34: #include <limits.h>
   35: #ifdef HAVE_PSTAT_GETPROC
   36: # include <sys/param.h>
   37: # include <sys/pstat.h>
   38: #else
   39: # ifdef HAVE_DIRENT_H
   40: #  include <dirent.h>
   41: #  define NAMLEN(dirent) strlen((dirent)->d_name)
   42: # else
   43: #  define dirent direct
   44: #  define NAMLEN(dirent) (dirent)->d_namlen
   45: #  ifdef HAVE_SYS_NDIR_H
   46: #   include <sys/ndir.h>
   47: #  endif
   48: #  ifdef HAVE_SYS_DIR_H
   49: #   include <sys/dir.h>
   50: #  endif
   51: #  ifdef HAVE_NDIR_H
   52: #   include <ndir.h>
   53: #  endif
   54: # endif
   55: #endif
   56: 
   57: #include "missing.h"
   58: 
   59: #if defined(HAVE_FCNTL_CLOSEM) && !defined(HAVE_DIRFD)
   60: # define closefrom	closefrom_fallback
   61: #endif
   62: 
   63: /*
   64:  * Close all file descriptors greater than or equal to lowfd.
   65:  * This is the expensive (fallback) method.
   66:  */
   67: void
   68: closefrom_fallback(int lowfd)
   69: {
   70:     long fd, maxfd;
   71: 
   72:     /*
   73:      * Fall back on sysconf() or getdtablesize().  We avoid checking
   74:      * resource limits since it is possible to open a file descriptor
   75:      * and then drop the rlimit such that it is below the open fd.
   76:      */
   77: #ifdef HAVE_SYSCONF
   78:     maxfd = sysconf(_SC_OPEN_MAX);
   79: #else
   80:     maxfd = getdtablesize();
   81: #endif /* HAVE_SYSCONF */
   82:     if (maxfd < 0)
   83: 	maxfd = OPEN_MAX;
   84: 
   85:     for (fd = lowfd; fd < maxfd; fd++) {
   86: #ifdef __APPLE__
   87: 	/* Avoid potential libdispatch crash when we close its fds. */
   88: 	(void) fcntl((int) fd, F_SETFD, FD_CLOEXEC);
   89: #else
   90: 	(void) close((int) fd);
   91: #endif
   92:     }
   93: }
   94: 
   95: /*
   96:  * Close all file descriptors greater than or equal to lowfd.
   97:  * We try the fast way first, falling back on the slow method.
   98:  */
   99: #if defined(HAVE_FCNTL_CLOSEM)
  100: void
  101: closefrom(int lowfd)
  102: {
  103:     if (fcntl(lowfd, F_CLOSEM, 0) == -1)
  104: 	closefrom_fallback(lowfd);
  105: }
  106: #elif defined(HAVE_PSTAT_GETPROC)
  107: void
  108: closefrom(int lowfd)
  109: {
  110:     struct pst_status pstat;
  111:     int fd;
  112: 
  113:     if (pstat_getproc(&pstat, sizeof(pstat), 0, getpid()) != -1) {
  114: 	for (fd = lowfd; fd <= pstat.pst_highestfd; fd++)
  115: 	    (void) close(fd);
  116:     } else {
  117: 	closefrom_fallback(lowfd);
  118:     }
  119: }
  120: #elif defined(HAVE_DIRFD)
  121: void
  122: closefrom(int lowfd)
  123: {
  124:     const char *path;
  125:     DIR *dirp;
  126: 
  127:     /* Use /proc/self/fd (or /dev/fd on FreeBSD) if it exists. */
  128: # if defined(__FreeBSD__) || defined(__APPLE__)
  129:     path = "/dev/fd";
  130: # else
  131:     path = "/proc/self/fd";
  132: # endif
  133:     if ((dirp = opendir(path)) != NULL) {
  134: 	struct dirent *dent;
  135: 	while ((dent = readdir(dirp)) != NULL) {
  136: 	    const char *errstr;
  137: 	    int fd = strtonum(dent->d_name, lowfd, INT_MAX, &errstr);
  138: 	    if (errstr == NULL && fd != dirfd(dirp)) {
  139: # ifdef __APPLE__
  140: 		/* Avoid potential libdispatch crash when we close its fds. */
  141: 		(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
  142: # else
  143: 		(void) close(fd);
  144: # endif
  145: 	    }
  146: 	}
  147: 	(void) closedir(dirp);
  148:     } else
  149: 	closefrom_fallback(lowfd);
  150: }
  151: #endif /* HAVE_FCNTL_CLOSEM */
  152: #endif /* HAVE_CLOSEFROM */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>