File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / compat / closefrom.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 10:46:11 2013 UTC (10 years, 11 months ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_7p0, v1_8_7, HEAD
1.8.7

    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: 	(void) close((int) fd);
   88: }
   89: 
   90: /*
   91:  * Close all file descriptors greater than or equal to lowfd.
   92:  * We try the fast way first, falling back on the slow method.
   93:  */
   94: #if defined(HAVE_FCNTL_CLOSEM)
   95: void
   96: closefrom(int lowfd)
   97: {
   98:     if (fcntl(lowfd, F_CLOSEM, 0) == -1)
   99: 	closefrom_fallback(lowfd);
  100: }
  101: #elif defined(HAVE_PSTAT_GETPROC)
  102: void
  103: closefrom(int lowfd)
  104: {
  105:     struct pst_status pstat;
  106:     int fd;
  107: 
  108:     if (pstat_getproc(&pstat, sizeof(pstat), 0, getpid()) != -1) {
  109: 	for (fd = lowfd; fd <= pstat.pst_highestfd; fd++)
  110: 	    (void) close(fd);
  111:     } else {
  112: 	closefrom_fallback(lowfd);
  113:     }
  114: }
  115: #elif defined(HAVE_DIRFD)
  116: void
  117: closefrom(int lowfd)
  118: {
  119:     struct dirent *dent;
  120:     DIR *dirp;
  121:     char *endp;
  122:     long fd;
  123: 
  124:     /* Use /proc/self/fd directory if it exists. */
  125:     if ((dirp = opendir("/proc/self/fd")) != NULL) {
  126: 	while ((dent = readdir(dirp)) != NULL) {
  127: 	    fd = strtol(dent->d_name, &endp, 10);
  128: 	    if (dent->d_name != endp && *endp == '\0' &&
  129: 		fd >= 0 && fd < INT_MAX && fd >= lowfd && fd != dirfd(dirp))
  130: 		(void) close((int) fd);
  131: 	}
  132: 	(void) closedir(dirp);
  133:     } else
  134: 	closefrom_fallback(lowfd);
  135: }
  136: #endif /* HAVE_FCNTL_CLOSEM */
  137: #endif /* HAVE_CLOSEFROM */

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