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