|  | /* $Id$ */ | 
|  |  | 
|  | /* | 
|  | * Copyright (c) 2004-2005 Todd C. Miller <Todd.Miller@courtesan.com> | 
|  | * | 
|  | * Permission to use, copy, modify, and distribute this software for any | 
|  | * purpose with or without fee is hereby granted, provided that the above | 
|  | * copyright notice and this permission notice appear in all copies. | 
|  | * | 
|  | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | 
|  | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | 
|  | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | 
|  | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | 
|  | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | 
|  | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | 
|  | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 
|  | */ | 
|  |  | 
|  | #include "tmux.h" | 
|  |  | 
|  | #ifndef HAVE_CLOSEFROM | 
|  |  | 
|  | #include <sys/types.h> | 
|  | #include <sys/param.h> | 
|  | #include <unistd.h> | 
|  | #include <stdio.h> | 
|  | #ifdef HAVE_FCNTL_H | 
|  | # include <fcntl.h> | 
|  | #endif | 
|  | #include <limits.h> | 
|  | #include <stdlib.h> | 
|  | #include <stddef.h> | 
|  | #include <string.h> | 
|  | #include <unistd.h> | 
|  | #ifdef HAVE_DIRENT_H | 
|  | # include <dirent.h> | 
|  | # define NAMLEN(dirent) strlen((dirent)->d_name) | 
|  | #else | 
|  | # define dirent direct | 
|  | # define NAMLEN(dirent) (dirent)->d_namlen | 
|  | # ifdef HAVE_SYS_NDIR_H | 
|  | #  include <sys/ndir.h> | 
|  | # endif | 
|  | # ifdef HAVE_SYS_DIR_H | 
|  | #  include <sys/dir.h> | 
|  | # endif | 
|  | # ifdef HAVE_NDIR_H | 
|  | #  include <ndir.h> | 
|  | # endif | 
|  | #endif | 
|  |  | 
|  | #ifndef OPEN_MAX | 
|  | # define OPEN_MAX	256 | 
|  | #endif | 
|  |  | 
|  | #if 0 | 
|  | __unused static const char rcsid[] = "$Sudo: closefrom.c,v 1.11 2006/08/17 15:26:54 millert Exp $"; | 
|  | #endif /* lint */ | 
|  |  | 
|  | /* | 
|  | * Close all file descriptors greater than or equal to lowfd. | 
|  | */ | 
|  | #ifdef HAVE_FCNTL_CLOSEM | 
|  | void | 
|  | closefrom(int lowfd) | 
|  | { | 
|  | (void) fcntl(lowfd, F_CLOSEM, 0); | 
|  | } | 
|  | #else | 
|  | void | 
|  | closefrom(int lowfd) | 
|  | { | 
|  | long fd, maxfd; | 
|  | #if defined(HAVE_DIRFD) && defined(HAVE_PROC_PID) | 
|  | char fdpath[PATH_MAX], *endp; | 
|  | struct dirent *dent; | 
|  | DIR *dirp; | 
|  | int len; | 
|  |  | 
|  | /* Check for a /proc/$$/fd directory. */ | 
|  | len = snprintf(fdpath, sizeof(fdpath), "/proc/%ld/fd", (long)getpid()); | 
|  | if (len > 0 && (size_t)len <= sizeof(fdpath) && (dirp = opendir(fdpath))) { | 
|  | 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); | 
|  | } | 
|  | (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); | 
|  | } | 
|  | } | 
|  | #endif /* !HAVE_FCNTL_CLOSEM */ | 
|  | #endif /* HAVE_CLOSEFROM */ |