Home | History | Annotate | Download | only in lib
      1 /* getdtablesize() function for platforms that don't have it.
      2    Copyright (C) 2008-2012 Free Software Foundation, Inc.
      3    Written by Bruno Haible <bruno (at) clisp.org>, 2008.
      4 
      5    This program is free software: you can redistribute it and/or modify
      6    it under the terms of the GNU General Public License as published by
      7    the Free Software Foundation; either version 3 of the License, or
      8    (at your option) any later version.
      9 
     10    This program 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 General Public License for more details.
     14 
     15    You should have received a copy of the GNU General Public License
     16    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     17 
     18 #include <config.h>
     19 
     20 /* Specification.  */
     21 #include <unistd.h>
     22 
     23 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
     24 
     25 #include <stdio.h>
     26 
     27 #include "msvc-inval.h"
     28 
     29 #if HAVE_MSVC_INVALID_PARAMETER_HANDLER
     30 static int
     31 _setmaxstdio_nothrow (int newmax)
     32 {
     33   int result;
     34 
     35   TRY_MSVC_INVAL
     36     {
     37       result = _setmaxstdio (newmax);
     38     }
     39   CATCH_MSVC_INVAL
     40     {
     41       result = -1;
     42     }
     43   DONE_MSVC_INVAL;
     44 
     45   return result;
     46 }
     47 # define _setmaxstdio _setmaxstdio_nothrow
     48 #endif
     49 
     50 /* Cache for the previous getdtablesize () result.  */
     51 static int dtablesize;
     52 
     53 int
     54 getdtablesize (void)
     55 {
     56   if (dtablesize == 0)
     57     {
     58       /* We are looking for the number N such that the valid file descriptors
     59          are 0..N-1.  It can be obtained through a loop as follows:
     60            {
     61              int fd;
     62              for (fd = 3; fd < 65536; fd++)
     63                if (dup2 (0, fd) == -1)
     64                  break;
     65              return fd;
     66            }
     67          On Windows XP, the result is 2048.
     68          The drawback of this loop is that it allocates memory for a libc
     69          internal array that is never freed.
     70 
     71          The number N can also be obtained as the upper bound for
     72          _getmaxstdio ().  _getmaxstdio () returns the maximum number of open
     73          FILE objects.  The sanity check in _setmaxstdio reveals the maximum
     74          number of file descriptors.  This too allocates memory, but it is
     75          freed when we call _setmaxstdio with the original value.  */
     76       int orig_max_stdio = _getmaxstdio ();
     77       unsigned int bound;
     78       for (bound = 0x10000; _setmaxstdio (bound) < 0; bound = bound / 2)
     79         ;
     80       _setmaxstdio (orig_max_stdio);
     81       dtablesize = bound;
     82     }
     83   return dtablesize;
     84 }
     85 
     86 #endif
     87