Back to index

nagios-plugins  1.4.16
sockets.c
Go to the documentation of this file.
00001 /* sockets.c --- wrappers for Windows socket functions
00002 
00003    Copyright (C) 2008-2010 Free Software Foundation, Inc.
00004 
00005    This program is free software: you can redistribute it and/or modify
00006    it under the terms of the GNU General Public License as published by
00007    the Free Software Foundation; either version 3 of the License, or
00008    (at your option) any later version.
00009 
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013    GNU General Public License for more details.
00014 
00015    You should have received a copy of the GNU General Public License
00016    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00017 
00018 /* Written by Simon Josefsson */
00019 
00020 #include <config.h>
00021 
00022 /* Specification.  */
00023 #include "sockets.h"
00024 
00025 #if WINDOWS_SOCKETS
00026 
00027 /* This includes winsock2.h on MinGW. */
00028 # include <sys/socket.h>
00029 
00030 # include "close-hook.h"
00031 
00032 /* Get set_winsock_errno, FD_TO_SOCKET etc. */
00033 # include "w32sock.h"
00034 
00035 static int
00036 close_fd_maybe_socket (int fd, const struct close_hook *remaining_list)
00037 {
00038   SOCKET sock;
00039   WSANETWORKEVENTS ev;
00040 
00041   /* Test whether fd refers to a socket.  */
00042   sock = FD_TO_SOCKET (fd);
00043   ev.lNetworkEvents = 0xDEADBEEF;
00044   WSAEnumNetworkEvents (sock, NULL, &ev);
00045   if (ev.lNetworkEvents != 0xDEADBEEF)
00046     {
00047       /* fd refers to a socket.  */
00048       /* FIXME: other applications, like squid, use an undocumented
00049          _free_osfhnd free function.  But this is not enough: The 'osfile'
00050          flags for fd also needs to be cleared, but it is hard to access it.
00051          Instead, here we just close twice the file descriptor.  */
00052       if (closesocket (sock))
00053         {
00054           set_winsock_errno ();
00055           return -1;
00056         }
00057       else
00058         {
00059           /* This call frees the file descriptor and does a
00060              CloseHandle ((HANDLE) _get_osfhandle (fd)), which fails.  */
00061           _close (fd);
00062           return 0;
00063         }
00064     }
00065   else
00066     /* Some other type of file descriptor.  */
00067     return execute_close_hooks (fd, remaining_list);
00068 }
00069 
00070 static struct close_hook close_sockets_hook;
00071 
00072 static int initialized_sockets_version /* = 0 */;
00073 
00074 #endif /* WINDOWS_SOCKETS */
00075 
00076 int
00077 gl_sockets_startup (int version _GL_UNUSED)
00078 {
00079 #if WINDOWS_SOCKETS
00080   if (version > initialized_sockets_version)
00081     {
00082       WSADATA data;
00083       int err;
00084 
00085       err = WSAStartup (version, &data);
00086       if (err != 0)
00087         return 1;
00088 
00089       if (data.wVersion < version)
00090         return 2;
00091 
00092       if (initialized_sockets_version == 0)
00093         register_close_hook (close_fd_maybe_socket, &close_sockets_hook);
00094 
00095       initialized_sockets_version = version;
00096     }
00097 #endif
00098 
00099   return 0;
00100 }
00101 
00102 int
00103 gl_sockets_cleanup (void)
00104 {
00105 #if WINDOWS_SOCKETS
00106   int err;
00107 
00108   initialized_sockets_version = 0;
00109 
00110   unregister_close_hook (&close_sockets_hook);
00111 
00112   err = WSACleanup ();
00113   if (err != 0)
00114     return 1;
00115 #endif
00116 
00117   return 0;
00118 }