105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* getdtablesize() function for platforms that don't have it. 205436638acc7c010349a69c3395f1a57c642dc62Ying Wang Copyright (C) 2008-2012 Free Software Foundation, Inc. 305436638acc7c010349a69c3395f1a57c642dc62Ying Wang Written by Bruno Haible <bruno@clisp.org>, 2008. 405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 505436638acc7c010349a69c3395f1a57c642dc62Ying Wang This program is free software: you can redistribute it and/or modify 605436638acc7c010349a69c3395f1a57c642dc62Ying Wang it under the terms of the GNU General Public License as published by 705436638acc7c010349a69c3395f1a57c642dc62Ying Wang the Free Software Foundation; either version 3 of the License, or 805436638acc7c010349a69c3395f1a57c642dc62Ying Wang (at your option) any later version. 905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 1005436638acc7c010349a69c3395f1a57c642dc62Ying Wang This program is distributed in the hope that it will be useful, 1105436638acc7c010349a69c3395f1a57c642dc62Ying Wang but WITHOUT ANY WARRANTY; without even the implied warranty of 1205436638acc7c010349a69c3395f1a57c642dc62Ying Wang MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1305436638acc7c010349a69c3395f1a57c642dc62Ying Wang GNU General Public License for more details. 1405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 1505436638acc7c010349a69c3395f1a57c642dc62Ying Wang You should have received a copy of the GNU General Public License 1605436638acc7c010349a69c3395f1a57c642dc62Ying Wang along with this program. If not, see <http://www.gnu.org/licenses/>. */ 1705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 1805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <config.h> 1905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 2005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Specification. */ 2105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <unistd.h> 2205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 2305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ 2405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 2505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <stdio.h> 2605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 2705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "msvc-inval.h" 2805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 2905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if HAVE_MSVC_INVALID_PARAMETER_HANDLER 3005436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic int 3105436638acc7c010349a69c3395f1a57c642dc62Ying Wang_setmaxstdio_nothrow (int newmax) 3205436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 3305436638acc7c010349a69c3395f1a57c642dc62Ying Wang int result; 3405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 3505436638acc7c010349a69c3395f1a57c642dc62Ying Wang TRY_MSVC_INVAL 3605436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 3705436638acc7c010349a69c3395f1a57c642dc62Ying Wang result = _setmaxstdio (newmax); 3805436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 3905436638acc7c010349a69c3395f1a57c642dc62Ying Wang CATCH_MSVC_INVAL 4005436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 4105436638acc7c010349a69c3395f1a57c642dc62Ying Wang result = -1; 4205436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 4305436638acc7c010349a69c3395f1a57c642dc62Ying Wang DONE_MSVC_INVAL; 4405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 4505436638acc7c010349a69c3395f1a57c642dc62Ying Wang return result; 4605436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 4705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define _setmaxstdio _setmaxstdio_nothrow 4805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif 4905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 5005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Cache for the previous getdtablesize () result. */ 5105436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic int dtablesize; 5205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 5305436638acc7c010349a69c3395f1a57c642dc62Ying Wangint 5405436638acc7c010349a69c3395f1a57c642dc62Ying Wanggetdtablesize (void) 5505436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 5605436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (dtablesize == 0) 5705436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 5805436638acc7c010349a69c3395f1a57c642dc62Ying Wang /* We are looking for the number N such that the valid file descriptors 5905436638acc7c010349a69c3395f1a57c642dc62Ying Wang are 0..N-1. It can be obtained through a loop as follows: 6005436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 6105436638acc7c010349a69c3395f1a57c642dc62Ying Wang int fd; 6205436638acc7c010349a69c3395f1a57c642dc62Ying Wang for (fd = 3; fd < 65536; fd++) 6305436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (dup2 (0, fd) == -1) 6405436638acc7c010349a69c3395f1a57c642dc62Ying Wang break; 6505436638acc7c010349a69c3395f1a57c642dc62Ying Wang return fd; 6605436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 6705436638acc7c010349a69c3395f1a57c642dc62Ying Wang On Windows XP, the result is 2048. 6805436638acc7c010349a69c3395f1a57c642dc62Ying Wang The drawback of this loop is that it allocates memory for a libc 6905436638acc7c010349a69c3395f1a57c642dc62Ying Wang internal array that is never freed. 7005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 7105436638acc7c010349a69c3395f1a57c642dc62Ying Wang The number N can also be obtained as the upper bound for 7205436638acc7c010349a69c3395f1a57c642dc62Ying Wang _getmaxstdio (). _getmaxstdio () returns the maximum number of open 7305436638acc7c010349a69c3395f1a57c642dc62Ying Wang FILE objects. The sanity check in _setmaxstdio reveals the maximum 7405436638acc7c010349a69c3395f1a57c642dc62Ying Wang number of file descriptors. This too allocates memory, but it is 7505436638acc7c010349a69c3395f1a57c642dc62Ying Wang freed when we call _setmaxstdio with the original value. */ 7605436638acc7c010349a69c3395f1a57c642dc62Ying Wang int orig_max_stdio = _getmaxstdio (); 7705436638acc7c010349a69c3395f1a57c642dc62Ying Wang unsigned int bound; 7805436638acc7c010349a69c3395f1a57c642dc62Ying Wang for (bound = 0x10000; _setmaxstdio (bound) < 0; bound = bound / 2) 7905436638acc7c010349a69c3395f1a57c642dc62Ying Wang ; 8005436638acc7c010349a69c3395f1a57c642dc62Ying Wang _setmaxstdio (orig_max_stdio); 8105436638acc7c010349a69c3395f1a57c642dc62Ying Wang dtablesize = bound; 8205436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 8305436638acc7c010349a69c3395f1a57c642dc62Ying Wang return dtablesize; 8405436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 8505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 8605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif 87