root/maint/gnulib/lib/getdtablesize.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _setmaxstdio_nothrow
  2. getdtablesize
  3. getdtablesize

   1 /* getdtablesize() function: Return maximum possible file descriptor value + 1.
   2    Copyright (C) 2008-2021 Free Software Foundation, Inc.
   3    Written by Bruno Haible <bruno@clisp.org>, 2008.
   4 
   5    This file is free software: you can redistribute it and/or modify
   6    it under the terms of the GNU Lesser General Public License as
   7    published by the Free Software Foundation; either version 2.1 of the
   8    License, or (at your option) any later version.
   9 
  10    This file is distributed in the hope that it will be useful,
  11    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13    GNU Lesser General Public License for more details.
  14 
  15    You should have received a copy of the GNU Lesser General Public License
  16    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  17 
  18 #include <config.h>
  19 
  20 /* Specification.  */
  21 #include <unistd.h>
  22 
  23 #if defined _WIN32 && ! defined __CYGWIN__
  24 
  25 # include <stdio.h>
  26 
  27 # if HAVE_MSVC_INVALID_PARAMETER_HANDLER
  28 #  include "msvc-inval.h"
  29 # endif
  30 
  31 # if HAVE_MSVC_INVALID_PARAMETER_HANDLER
  32 static int
  33 _setmaxstdio_nothrow (int newmax)
     /* [previous][next][first][last][top][bottom][index][help] */
  34 {
  35   int result;
  36 
  37   TRY_MSVC_INVAL
  38     {
  39       result = _setmaxstdio (newmax);
  40     }
  41   CATCH_MSVC_INVAL
  42     {
  43       result = -1;
  44     }
  45   DONE_MSVC_INVAL;
  46 
  47   return result;
  48 }
  49 # else
  50 #  define _setmaxstdio_nothrow _setmaxstdio
  51 # endif
  52 
  53 /* Cache for the previous getdtablesize () result.  Safe to cache because
  54    Windows also lacks setrlimit.  */
  55 static int dtablesize;
  56 
  57 int
  58 getdtablesize (void)
     /* [previous][next][first][last][top][bottom][index][help] */
  59 {
  60   if (dtablesize == 0)
  61     {
  62       /* We are looking for the number N such that the valid file descriptors
  63          are 0..N-1.  It can be obtained through a loop as follows:
  64            {
  65              int fd;
  66              for (fd = 3; fd < 65536; fd++)
  67                if (dup2 (0, fd) == -1)
  68                  break;
  69              return fd;
  70            }
  71          On Windows XP, the result is 2048.
  72          The drawback of this loop is that it allocates memory for a libc
  73          internal array that is never freed.
  74 
  75          The number N can also be obtained as the upper bound for
  76          _getmaxstdio ().  _getmaxstdio () returns the maximum number of open
  77          FILE objects.  The sanity check in _setmaxstdio reveals the maximum
  78          number of file descriptors.  This too allocates memory, but it is
  79          freed when we call _setmaxstdio with the original value.  */
  80       int orig_max_stdio = _getmaxstdio ();
  81       unsigned int bound;
  82       for (bound = 0x10000; _setmaxstdio_nothrow (bound) < 0; bound = bound / 2)
  83         ;
  84       _setmaxstdio_nothrow (orig_max_stdio);
  85       dtablesize = bound;
  86     }
  87   return dtablesize;
  88 }
  89 
  90 #else
  91 
  92 # include <limits.h>
  93 # include <sys/resource.h>
  94 
  95 # ifndef RLIM_SAVED_CUR
  96 #  define RLIM_SAVED_CUR RLIM_INFINITY
  97 # endif
  98 # ifndef RLIM_SAVED_MAX
  99 #  define RLIM_SAVED_MAX RLIM_INFINITY
 100 # endif
 101 
 102 # ifdef __CYGWIN__
 103   /* Cygwin 1.7.25 auto-increases the RLIMIT_NOFILE soft limit until it
 104      hits the compile-time constant hard limit of 3200.  We might as
 105      well just report the hard limit.  */
 106 #  define rlim_cur rlim_max
 107 # endif
 108 
 109 int
 110 getdtablesize (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 111 {
 112   struct rlimit lim;
 113 
 114   if (getrlimit (RLIMIT_NOFILE, &lim) == 0
 115       && 0 <= lim.rlim_cur && lim.rlim_cur <= INT_MAX
 116       && lim.rlim_cur != RLIM_INFINITY
 117       && lim.rlim_cur != RLIM_SAVED_CUR
 118       && lim.rlim_cur != RLIM_SAVED_MAX)
 119     return lim.rlim_cur;
 120 
 121   return INT_MAX;
 122 }
 123 
 124 #endif

/* [previous][next][first][last][top][bottom][index][help] */