1 #include <errno.h>
2 #include <fcntl.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <sys/resource.h>
6 #include <unistd.h>
7 #include "fdleak.h"
8
main(int argc,char ** argv)9 int main(int argc, char **argv)
10 {
11 struct rlimit oldrlim;
12 struct rlimit newrlim;
13 int fd;
14
15 CLOSE_INHERITED_FDS;
16
17 if (getrlimit(RLIMIT_NOFILE, &oldrlim) < 0)
18 {
19 perror("getrlimit");
20 exit(1);
21 }
22
23 newrlim.rlim_cur = oldrlim.rlim_max+1;
24 newrlim.rlim_max = oldrlim.rlim_max;
25 if (setrlimit(RLIMIT_NOFILE, &newrlim) == -1)
26 {
27 if (errno != EINVAL) {
28 fprintf(stderr, "setrlimit exceeding hardlimit must set errno=EINVAL\n");
29 exit(1);
30 }
31 }
32 else
33 {
34 fprintf(stderr, "setrlimit exceeding hardlimit must return -1\n");
35 exit(1);
36 }
37
38 newrlim.rlim_cur = oldrlim.rlim_max;
39 newrlim.rlim_max = oldrlim.rlim_max+1;
40 if (setrlimit(RLIMIT_NOFILE, &newrlim) == -1)
41 {
42 if (errno != EPERM) {
43 fprintf(stderr, "setrlimit changing hardlimit must set errno=EPERM\n");
44 exit(1);
45 }
46 }
47 else
48 {
49 fprintf(stderr, "setrlimit changing hardlimit must return -1\n");
50 exit(1);
51 }
52
53 newrlim.rlim_cur = oldrlim.rlim_cur / 2;
54 newrlim.rlim_max = oldrlim.rlim_max;
55
56 if (setrlimit(RLIMIT_NOFILE, &newrlim) < 0)
57 {
58 perror("setrlimit");
59 exit(1);
60 }
61
62 if (getrlimit(RLIMIT_NOFILE, &newrlim) < 0)
63 {
64 perror("getrlimit");
65 exit(1);
66 }
67
68 if (newrlim.rlim_cur != oldrlim.rlim_cur / 2)
69 {
70 fprintf(stderr, "rlim_cur is %llu (should be %llu)\n",
71 (unsigned long long)newrlim.rlim_cur,
72 (unsigned long long)oldrlim.rlim_cur / 2);
73 }
74
75 if (newrlim.rlim_max != oldrlim.rlim_max)
76 {
77 fprintf(stderr, "rlim_max is %llu (should be %llu)\n",
78 (unsigned long long)newrlim.rlim_max,
79 (unsigned long long)oldrlim.rlim_max);
80 }
81
82 newrlim.rlim_cur -= 3; /* allow for stdin, stdout and stderr */
83
84 while (newrlim.rlim_cur-- > 0)
85 {
86 if (open("/dev/null", O_RDONLY) < 0)
87 {
88 perror("open");
89 }
90 }
91
92 if ((fd = open("/dev/null", O_RDONLY)) >= 0)
93 {
94 fprintf(stderr, "open succeeded with fd %d - it should have failed!\n", fd);
95 }
96 else if (errno != EMFILE)
97 {
98 perror("open");
99 }
100
101 if (setrlimit(RLIMIT_NOFILE, NULL) != -1 || errno != EFAULT)
102 {
103 fprintf(stderr, "setrlimit non addressable arg2 must set errno=EFAULT\n");
104 exit(1);
105 }
106
107 exit(0);
108 }
109