1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
/* $Id: fdlimit.c 4511 2001-02-07 23:41:08Z rra $
**
** Portably determine or set the limit on open file descriptors.
**
** Pretty much all platforms these days have getrlimit and setrlimit, so
** prefer those, but for determining the current limit preserve the old
** portability (if we don't have getrlimit, try sysconf, then
** getdtablesize, then ulimit, and then try to find a hard-coded constant
** in <sys/param.h> and failing that fall back to the POSIX-guaranteed
** minimum of 20.
**
** For setting the limit, only setrlimit is supported; if it isn't
** available, return -1 always. We also refuse to set the limit to
** something higher than select can handle, checking against FD_SETSIZE.
**
** Note that on some versions of Linux (2.2.x reported), sysconf may return
** the wrong value for the maximum file descriptors. getrlimit is correct,
** so always prefer it.
*/
#include "config.h"
#include "clibrary.h"
#include <errno.h>
#if HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif
/* FreeBSD 3.4 RELEASE needs <sys/time.h> before <sys/resource.h>. */
#if HAVE_GETRLIMIT || HAVE_SETRLIMIT
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# endif
# include <sys/resource.h>
#endif
#include "libinn.h"
#if HAVE_SETRLIMIT && defined(RLIMIT_NOFILE)
int
setfdlimit(unsigned int limit)
{
struct rlimit rl;
#ifdef FD_SETSIZE
if (limit > FD_SETSIZE) {
errno = EINVAL;
return -1;
}
#endif
rl.rlim_cur = 0;
rl.rlim_max = 0;
#if HAVE_GETRLIMIT
if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
rl.rlim_cur = 0;
rl.rlim_max = 0;
}
#endif
rl.rlim_cur = limit;
if (limit > rl.rlim_max)
rl.rlim_max = limit;
return setrlimit(RLIMIT_NOFILE, &rl);
}
#else /* !(HAVE_SETRLIMIT && RLIMIT_NOFILE) */
int
setfdlimit(unsigned int limit UNUSED)
{
/* Unimplemented system call is close enough. */
errno = ENOSYS;
return -1;
}
#endif /* !(HAVE_SETRLIMIT && RLIMIT_NOFILE) */
#if HAVE_GETRLIMIT && defined(RLIMIT_NOFILE)
int
getfdlimit(void)
{
struct rlimit rl;
if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
return -1;
return rl.rlim_cur;
}
#elif HAVE_SYSCONF
int
getfdlimit(void)
{
return sysconf(_SC_OPEN_MAX);
}
#elif HAVE_GETDTABLESIZE
int
getfdlimit(void)
{
return getdtablesize();
}
#elif HAVE_ULIMIT
int
getfdlimit(void)
{
# ifdef UL_GDESLIM
return ulimit(UL_GDESLIM, 0);
# else
return ulimit(4, 0);
# endif
}
#else /* no function mechanism available */
# if HAVE_LIMITS_H
# include <limits.h>
# endif
# include <sys/param.h>
int
getfdcount(void)
{
# ifdef NOFILE
return NOFILE;
# else
return 20;
# endif
}
#endif
|