File: fdlimit.c

package info (click to toggle)
inn2 2.4.5-5
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 8,912 kB
  • ctags: 7,860
  • sloc: ansic: 85,104; perl: 11,427; sh: 9,863; makefile: 2,498; yacc: 1,563; python: 298; lex: 252; tcl: 7
file content (136 lines) | stat: -rw-r--r-- 2,667 bytes parent folder | download
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