00001 00004 /* Copyright (C) 2006,2007,2008 Olly Betts 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 00021 #include <config.h> 00022 #include "socket_utils.h" 00023 00024 #ifdef __WIN32__ 00025 # include "safeerrno.h" 00026 00027 # include <io.h> 00028 // __STDC_SECURE_LIB__ doesn't appear to be publicly documented, but appears 00029 // to be a good idea. We cribbed this test from the python sources - see, for 00030 // example, http://svn.python.org/view?rev=47223&view=rev 00031 # if defined _MSC_VER && _MSC_VER >= 1400 && defined __STDC_SECURE_LIB__ 00032 # include <cstdlib> // For _set_invalid_parameter_handler(), etc. 00033 # include <crtdbg.h> // For _CrtSetReportMode, etc. 00034 00036 static void dummy_handler(const wchar_t*, 00037 const wchar_t*, 00038 const wchar_t*, 00039 unsigned int, 00040 uintptr_t) 00041 { 00042 } 00043 00044 // Recent versions of MSVC call an "_invalid_parameter_handler" if a 00045 // CRT function receives an invalid parameter. However, there are cases 00046 // where this is totally reasonable. To avoid the application dying, 00047 // you just need to instantiate the MSVCIgnoreInvalidParameter class in 00048 // the scope where you want MSVC to ignore invalid parameters. 00049 class MSVCIgnoreInvalidParameter { 00050 _invalid_parameter_handler old_handler; 00051 int old_report_mode; 00052 00053 public: 00054 MSVCIgnoreInvalidParameter() { 00055 // Install a dummy handler to avoid the program dying. 00056 old_handler = _set_invalid_parameter_handler(dummy_handler); 00057 // Make sure that no dialog boxes appear. 00058 old_report_mode = _CrtSetReportMode(_CRT_ASSERT, 0); 00059 } 00060 00061 ~MSVCIgnoreInvalidParameter() { 00062 // Restore the previous settings. 00063 _set_invalid_parameter_handler(old_handler); 00064 _CrtSetReportMode(_CRT_ASSERT, old_report_mode); 00065 } 00066 }; 00067 # else 00068 // Mingw seems to be free of this insanity, so for this and older MSVC versions 00069 // define a dummy class to allow MSVCIgnoreInvalidParameter to be used 00070 // unconditionally. 00071 struct MSVCIgnoreInvalidParameter { 00072 // Provide an explicit constructor so this isn't a POD struct - this seems 00073 // to prevent GCC warning about an unused variable whenever we instantiate 00074 // this class. 00075 MSVCIgnoreInvalidParameter() { } 00076 }; 00077 # endif 00078 00080 extern HANDLE fd_to_handle(int fd) { 00081 MSVCIgnoreInvalidParameter invalid_handle_value_is_ok; 00082 HANDLE handle = (HANDLE)_get_osfhandle(fd); 00083 // On WIN32, a socket fd isn't the same as a non-socket fd - in fact 00084 // it's already a HANDLE! 00085 return (handle != INVALID_HANDLE_VALUE ? handle : (HANDLE)fd); 00086 } 00087 00089 extern void close_fd_or_socket(int fd) { 00090 MSVCIgnoreInvalidParameter invalid_fd_value_is_ok; 00091 if (close(fd) == -1 && errno == EBADF) { 00092 // Bad file descriptor - probably because the fd is actually 00093 // a socket. 00094 closesocket(fd); 00095 } 00096 } 00097 #endif