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 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