LCOV - code coverage report
Current view: top level - lib - sockets.c (source / functions) Hit Total Coverage
Test: FontForge coverage report 2017-08-04 01:21:11+02:00 (commit d35f7e4107a9e1db65cce47c468fcc914cecb8fd) Lines: 0 4 0.0 %
Date: 2017-08-04 Functions: 0 2 0.0 %

          Line data    Source code
       1             : /* sockets.c --- wrappers for Windows socket functions
       2             : 
       3             :    Copyright (C) 2008-2016 Free Software Foundation, Inc.
       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             : /* Written by Simon Josefsson */
      19             : 
      20             : #include <config.h>
      21             : 
      22             : /* Specification.  */
      23             : #include "sockets.h"
      24             : 
      25             : #if WINDOWS_SOCKETS
      26             : 
      27             : /* This includes winsock2.h on MinGW. */
      28             : # include <sys/socket.h>
      29             : 
      30             : # include "fd-hook.h"
      31             : # include "msvc-nothrow.h"
      32             : 
      33             : /* Get set_winsock_errno, FD_TO_SOCKET etc. */
      34             : # include "w32sock.h"
      35             : 
      36             : static int
      37             : close_fd_maybe_socket (const struct fd_hook *remaining_list,
      38             :                        gl_close_fn primary,
      39             :                        int fd)
      40             : {
      41             :   /* Note about multithread-safety: There is a race condition where, between
      42             :      our calls to closesocket() and the primary close(), some other thread
      43             :      could make system calls that allocate precisely the same HANDLE value
      44             :      as sock; then the primary close() would call CloseHandle() on it.  */
      45             :   SOCKET sock;
      46             :   WSANETWORKEVENTS ev;
      47             : 
      48             :   /* Test whether fd refers to a socket.  */
      49             :   sock = FD_TO_SOCKET (fd);
      50             :   ev.lNetworkEvents = 0xDEADBEEF;
      51             :   WSAEnumNetworkEvents (sock, NULL, &ev);
      52             :   if (ev.lNetworkEvents != 0xDEADBEEF)
      53             :     {
      54             :       /* fd refers to a socket.  */
      55             :       /* FIXME: other applications, like squid, use an undocumented
      56             :          _free_osfhnd free function.  But this is not enough: The 'osfile'
      57             :          flags for fd also needs to be cleared, but it is hard to access it.
      58             :          Instead, here we just close twice the file descriptor.  */
      59             :       if (closesocket (sock))
      60             :         {
      61             :           set_winsock_errno ();
      62             :           return -1;
      63             :         }
      64             :       else
      65             :         {
      66             :           /* This call frees the file descriptor and does a
      67             :              CloseHandle ((HANDLE) _get_osfhandle (fd)), which fails.  */
      68             :           _close (fd);
      69             :           return 0;
      70             :         }
      71             :     }
      72             :   else
      73             :     /* Some other type of file descriptor.  */
      74             :     return execute_close_hooks (remaining_list, primary, fd);
      75             : }
      76             : 
      77             : static int
      78             : ioctl_fd_maybe_socket (const struct fd_hook *remaining_list,
      79             :                        gl_ioctl_fn primary,
      80             :                        int fd, int request, void *arg)
      81             : {
      82             :   SOCKET sock;
      83             :   WSANETWORKEVENTS ev;
      84             : 
      85             :   /* Test whether fd refers to a socket.  */
      86             :   sock = FD_TO_SOCKET (fd);
      87             :   ev.lNetworkEvents = 0xDEADBEEF;
      88             :   WSAEnumNetworkEvents (sock, NULL, &ev);
      89             :   if (ev.lNetworkEvents != 0xDEADBEEF)
      90             :     {
      91             :       /* fd refers to a socket.  */
      92             :       if (ioctlsocket (sock, request, arg) < 0)
      93             :         {
      94             :           set_winsock_errno ();
      95             :           return -1;
      96             :         }
      97             :       else
      98             :         return 0;
      99             :     }
     100             :   else
     101             :     /* Some other type of file descriptor.  */
     102             :     return execute_ioctl_hooks (remaining_list, primary, fd, request, arg);
     103             : }
     104             : 
     105             : static struct fd_hook fd_sockets_hook;
     106             : 
     107             : static int initialized_sockets_version /* = 0 */;
     108             : 
     109             : #endif /* WINDOWS_SOCKETS */
     110             : 
     111             : int
     112           0 : gl_sockets_startup (int version _GL_UNUSED)
     113             : {
     114             : #if WINDOWS_SOCKETS
     115             :   if (version > initialized_sockets_version)
     116             :     {
     117             :       WSADATA data;
     118             :       int err;
     119             : 
     120             :       err = WSAStartup (version, &data);
     121             :       if (err != 0)
     122             :         return 1;
     123             : 
     124             :       if (data.wVersion != version)
     125             :         {
     126             :           WSACleanup ();
     127             :           return 2;
     128             :         }
     129             : 
     130             :       if (initialized_sockets_version == 0)
     131             :         register_fd_hook (close_fd_maybe_socket, ioctl_fd_maybe_socket,
     132             :                           &fd_sockets_hook);
     133             : 
     134             :       initialized_sockets_version = version;
     135             :     }
     136             : #endif
     137             : 
     138           0 :   return 0;
     139             : }
     140             : 
     141             : int
     142           0 : gl_sockets_cleanup (void)
     143             : {
     144             : #if WINDOWS_SOCKETS
     145             :   int err;
     146             : 
     147             :   initialized_sockets_version = 0;
     148             : 
     149             :   unregister_fd_hook (&fd_sockets_hook);
     150             : 
     151             :   err = WSACleanup ();
     152             :   if (err != 0)
     153             :     return 1;
     154             : #endif
     155             : 
     156           0 :   return 0;
     157             : }

Generated by: LCOV version 1.10