Home | History | Annotate | Download | only in tests
      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