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