bsd-closefrom.c revision 137015
1328653Shselasky/* 2328653Shselasky * Copyright (c) 2004 Todd C. Miller <Todd.Miller@courtesan.com> 3328653Shselasky * 4328653Shselasky * Permission to use, copy, modify, and distribute this software for any 5328653Shselasky * purpose with or without fee is hereby granted, provided that the above 6328653Shselasky * copyright notice and this permission notice appear in all copies. 7328653Shselasky * 8328653Shselasky * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9328653Shselasky * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10328653Shselasky * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11328653Shselasky * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12328653Shselasky * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13328653Shselasky * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14328653Shselasky * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15328653Shselasky */ 16328653Shselasky 17328653Shselasky#include "includes.h" 18328653Shselasky 19328653Shselasky#ifndef HAVE_CLOSEFROM 20328653Shselasky 21328653Shselasky#include <sys/types.h> 22328653Shselasky#include <sys/param.h> 23328653Shselasky#include <unistd.h> 24328653Shselasky#include <stdio.h> 25328653Shselasky#include <limits.h> 26328653Shselasky#include <stdlib.h> 27328653Shselasky#include <stddef.h> 28328653Shselasky#ifdef HAVE_DIRENT_H 29328653Shselasky# include <dirent.h> 30328653Shselasky# define NAMLEN(dirent) strlen((dirent)->d_name) 31328653Shselasky#else 32328653Shselasky# define dirent direct 33328653Shselasky# define NAMLEN(dirent) (dirent)->d_namlen 34328653Shselasky# ifdef HAVE_SYS_NDIR_H 35328653Shselasky# include <sys/ndir.h> 36328653Shselasky# endif 37328653Shselasky# ifdef HAVE_SYS_DIR_H 38328653Shselasky# include <sys/dir.h> 39328653Shselasky# endif 40328653Shselasky# ifdef HAVE_NDIR_H 41328653Shselasky# include <ndir.h> 42328653Shselasky# endif 43328653Shselasky#endif 44328653Shselasky 45328653Shselasky#ifndef OPEN_MAX 46328653Shselasky# define OPEN_MAX 256 47328653Shselasky#endif 48328653Shselasky 49328653ShselaskyRCSID("$Id: bsd-closefrom.c,v 1.1 2004/08/15 08:41:00 djm Exp $"); 50328653Shselasky 51328653Shselasky#ifndef lint 52330853Shselaskystatic const char sudorcsid[] = "$Sudo: closefrom.c,v 1.6 2004/06/01 20:51:56 millert Exp $"; 53328653Shselasky#endif /* lint */ 54328653Shselasky 55328653Shselasky/* 56328653Shselasky * Close all file descriptors greater than or equal to lowfd. 57328653Shselasky */ 58328653Shselaskyvoid 59328653Shselaskyclosefrom(int lowfd) 60328653Shselasky{ 61328653Shselasky long fd, maxfd; 62328653Shselasky#if defined(HAVE_DIRFD) && defined(HAVE_PROC_PID) 63328653Shselasky char fdpath[PATH_MAX], *endp; 64328653Shselasky struct dirent *dent; 65328653Shselasky DIR *dirp; 66328653Shselasky int len; 67328653Shselasky 68328653Shselasky /* Check for a /proc/$$/fd directory. */ 69328653Shselasky len = snprintf(fdpath, sizeof(fdpath), "/proc/%ld/fd", (long)getpid()); 70328653Shselasky if (len != -1 && len <= sizeof(fdpath) && (dirp = opendir(fdpath))) { 71328653Shselasky while ((dent = readdir(dirp)) != NULL) { 72328653Shselasky fd = strtol(dent->d_name, &endp, 10); 73328653Shselasky if (dent->d_name != endp && *endp == '\0' && 74328653Shselasky fd >= 0 && fd < INT_MAX && fd >= lowfd && fd != dirfd(dirp)) 75328653Shselasky (void) close((int) fd); 76328653Shselasky } 77328653Shselasky (void) closedir(dirp); 78328653Shselasky } else 79328653Shselasky#endif 80328653Shselasky { 81328653Shselasky /* 82328653Shselasky * Fall back on sysconf() or getdtablesize(). We avoid checking 83328653Shselasky * resource limits since it is possible to open a file descriptor 84328653Shselasky * and then drop the rlimit such that it is below the open fd. 85328653Shselasky */ 86328653Shselasky#ifdef HAVE_SYSCONF 87328653Shselasky maxfd = sysconf(_SC_OPEN_MAX); 88330853Shselasky#else 89328653Shselasky maxfd = getdtablesize(); 90328653Shselasky#endif /* HAVE_SYSCONF */ 91328653Shselasky if (maxfd < 0) 92328653Shselasky maxfd = OPEN_MAX; 93328653Shselasky 94328653Shselasky for (fd = lowfd; fd < maxfd; fd++) 95328653Shselasky (void) close((int) fd); 96328653Shselasky } 97328653Shselasky} 98328653Shselasky 99328653Shselasky#endif /* HAVE_CLOSEFROM */ 100328653Shselasky 101328653Shselasky