File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / compat / closefrom.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Oct 14 07:56:33 2013 UTC (10 years, 8 months ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_8p0, v1_8_8, HEAD
v 1.8.8

    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: #ifdef HAVE_PSTAT_GETPROC
   35: # include <sys/param.h>
   36: # include <sys/pstat.h>
   37: #else
   38: # ifdef HAVE_DIRENT_H
   39: #  include <dirent.h>
   40: #  define NAMLEN(dirent) strlen((dirent)->d_name)
   41: # else
   42: #  define dirent direct
   43: #  define NAMLEN(dirent) (dirent)->d_namlen
   44: #  ifdef HAVE_SYS_NDIR_H
   45: #   include <sys/ndir.h>
   46: #  endif
   47: #  ifdef HAVE_SYS_DIR_H
   48: #   include <sys/dir.h>
   49: #  endif
   50: #  ifdef HAVE_NDIR_H
   51: #   include <ndir.h>
   52: #  endif
   53: # endif
   54: #endif
   55: 
   56: #include "missing.h"
   57: 
   58: #ifndef HAVE_FCNTL_CLOSEM
   59: # ifndef HAVE_DIRFD
   60: #   define closefrom_fallback	closefrom
   61: # endif
   62: #endif
   63: 
   64: /*
   65:  * Close all file descriptors greater than or equal to lowfd.
   66:  * This is the expensive (ballback) method.
   67:  */
   68: void
   69: closefrom_fallback(int lowfd)
   70: {
   71:     long fd, maxfd;
   72: 
   73:     /*
   74:      * Fall back on sysconf() or getdtablesize().  We avoid checking
   75:      * resource limits since it is possible to open a file descriptor
   76:      * and then drop the rlimit such that it is below the open fd.
   77:      */
   78: #ifdef HAVE_SYSCONF
   79:     maxfd = sysconf(_SC_OPEN_MAX);
   80: #else
   81:     maxfd = getdtablesize();
   82: #endif /* HAVE_SYSCONF */
   83:     if (maxfd < 0)
   84: 	maxfd = OPEN_MAX;
   85: 
   86:     for (fd = lowfd; fd < maxfd; fd++) {
   87: #ifdef __APPLE__
   88: 	/* Avoid potential crash with libdispatch when we close its fds. */
   89: 	(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
   90: #else
   91: 	(void) close((int) fd);
   92: #endif
   93:     }
   94: }
   95: 
   96: /*
   97:  * Close all file descriptors greater than or equal to lowfd.
   98:  * We try the fast way first, falling back on the slow method.
   99:  */
  100: #if defined(HAVE_FCNTL_CLOSEM)
  101: void
  102: closefrom(int lowfd)
  103: {
  104:     if (fcntl(lowfd, F_CLOSEM, 0) == -1)
  105: 	closefrom_fallback(lowfd);
  106: }
  107: #elif defined(HAVE_PSTAT_GETPROC)
  108: void
  109: closefrom(int lowfd)
  110: {
  111:     struct pst_status pstat;
  112:     int fd;
  113: 
  114:     if (pstat_getproc(&pstat, sizeof(pstat), 0, getpid()) != -1) {
  115: 	for (fd = lowfd; fd <= pstat.pst_highestfd; fd++)
  116: 	    (void) close(fd);
  117:     } else {
  118: 	closefrom_fallback(lowfd);
  119:     }
  120: }
  121: #elif defined(HAVE_DIRFD)
  122: void
  123: closefrom(int lowfd)
  124: {
  125:     struct dirent *dent;
  126:     DIR *dirp;
  127:     char *endp;
  128:     long fd;
  129: 
  130:     /* Use /proc/self/fd directory if it exists. */
  131:     if ((dirp = opendir("/proc/self/fd")) != NULL) {
  132: 	while ((dent = readdir(dirp)) != NULL) {
  133: 	    fd = strtol(dent->d_name, &endp, 10);
  134: 	    if (dent->d_name != endp && *endp == '\0' &&
  135: 		fd >= 0 && fd < INT_MAX && fd >= lowfd && fd != dirfd(dirp))
  136: 		(void) close((int) fd);
  137: 	}
  138: 	(void) closedir(dirp);
  139:     } else
  140: 	closefrom_fallback(lowfd);
  141: }
  142: #endif /* HAVE_FCNTL_CLOSEM */
  143: #endif /* HAVE_CLOSEFROM */

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