forked from net-snmp/net-snmp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnetsnmp_close_fds.c
66 lines (59 loc) · 1.46 KB
/
netsnmp_close_fds.c
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
#include <net-snmp/net-snmp-config.h>
#include <stdio.h>
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <net-snmp/agent/netsnmp_close_fds.h>
/**
* Close all file descriptors larger than @fd.
*/
void netsnmp_close_fds(int fd)
{
#if defined(HAVE_FORK)
DIR *dir NETSNMP_ATTRIBUTE_UNUSED;
struct dirent *ent NETSNMP_ATTRIBUTE_UNUSED;
int i, largest_fd = -1;
if (fd < -1)
fd = -1;
#ifdef __linux__
#ifdef __NR_close_range
if (syscall(__NR_close_range, fd + 1, UINT_MAX, 0) == 0)
return;
#endif
if ((dir = opendir("/proc/self/fd"))) {
while ((ent = readdir(dir))) {
if (sscanf(ent->d_name, "%d", &i) == 1) {
if (i > largest_fd)
largest_fd = i;
}
}
closedir(dir);
}
#elif defined(__FreeBSD__) || defined(__OpenBSD__)
if ((dir = opendir("/dev/fd"))) {
while ((ent = readdir(dir))) {
if (sscanf(ent->d_name, "%d", &i) == 1) {
if (i > largest_fd)
largest_fd = i;
}
}
closedir(dir);
}
#endif
if (largest_fd < 0) {
#ifdef HAVE_GETDTABLESIZE
largest_fd = getdtablesize() - 1;
#else
largest_fd = sysconf(_SC_OPEN_MAX);
#endif
}
for (i = largest_fd; i > fd && i >= 0; i--)
close(i);
#endif /* defined(HAVE_FORK) */
}