view lib/sockets.c @ 17463:203c036eb0c6

bootstrap: support checksum utils without a --status option * build-aux/bootstrap: Only look for sha1sum if updating po files. Add sha1 to the list of supported checksum utils since it's now supported through adjustments below. (update_po_files): Remove the use of --status in a way that will suppress all error messages, but since this is only used to minimize updates, it shouldn't cause an issue. Exit early if there is a problem updating the po file checksums. (find_tool): Remove the check for --version support as this is optional as per commit 86186b17. Don't even check for the presence of the command as if that is needed, it's supported through configuring prerequisites in bootstrap.conf. Prompt that when a tool isn't found, one can define an environment variable to add to the hardcoded search list.
author Pádraig Brady <P@draigBrady.com>
date Thu, 08 Aug 2013 11:08:49 +0100
parents e542fd46ad6f
children
line wrap: on
line source

/* sockets.c --- wrappers for Windows socket functions

   Copyright (C) 2008-2013 Free Software Foundation, Inc.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

/* Written by Simon Josefsson */

#include <config.h>

/* Specification.  */
#include "sockets.h"

#if WINDOWS_SOCKETS

/* This includes winsock2.h on MinGW. */
# include <sys/socket.h>

# include "fd-hook.h"
# include "msvc-nothrow.h"

/* Get set_winsock_errno, FD_TO_SOCKET etc. */
# include "w32sock.h"

static int
close_fd_maybe_socket (const struct fd_hook *remaining_list,
                       gl_close_fn primary,
                       int fd)
{
  /* Note about multithread-safety: There is a race condition where, between
     our calls to closesocket() and the primary close(), some other thread
     could make system calls that allocate precisely the same HANDLE value
     as sock; then the primary close() would call CloseHandle() on it.  */
  SOCKET sock;
  WSANETWORKEVENTS ev;

  /* Test whether fd refers to a socket.  */
  sock = FD_TO_SOCKET (fd);
  ev.lNetworkEvents = 0xDEADBEEF;
  WSAEnumNetworkEvents (sock, NULL, &ev);
  if (ev.lNetworkEvents != 0xDEADBEEF)
    {
      /* fd refers to a socket.  */
      /* FIXME: other applications, like squid, use an undocumented
         _free_osfhnd free function.  But this is not enough: The 'osfile'
         flags for fd also needs to be cleared, but it is hard to access it.
         Instead, here we just close twice the file descriptor.  */
      if (closesocket (sock))
        {
          set_winsock_errno ();
          return -1;
        }
      else
        {
          /* This call frees the file descriptor and does a
             CloseHandle ((HANDLE) _get_osfhandle (fd)), which fails.  */
          _close (fd);
          return 0;
        }
    }
  else
    /* Some other type of file descriptor.  */
    return execute_close_hooks (remaining_list, primary, fd);
}

static int
ioctl_fd_maybe_socket (const struct fd_hook *remaining_list,
                       gl_ioctl_fn primary,
                       int fd, int request, void *arg)
{
  SOCKET sock;
  WSANETWORKEVENTS ev;

  /* Test whether fd refers to a socket.  */
  sock = FD_TO_SOCKET (fd);
  ev.lNetworkEvents = 0xDEADBEEF;
  WSAEnumNetworkEvents (sock, NULL, &ev);
  if (ev.lNetworkEvents != 0xDEADBEEF)
    {
      /* fd refers to a socket.  */
      if (ioctlsocket (sock, request, arg) < 0)
        {
          set_winsock_errno ();
          return -1;
        }
      else
        return 0;
    }
  else
    /* Some other type of file descriptor.  */
    return execute_ioctl_hooks (remaining_list, primary, fd, request, arg);
}

static struct fd_hook fd_sockets_hook;

static int initialized_sockets_version /* = 0 */;

#endif /* WINDOWS_SOCKETS */

int
gl_sockets_startup (int version _GL_UNUSED)
{
#if WINDOWS_SOCKETS
  if (version > initialized_sockets_version)
    {
      WSADATA data;
      int err;

      err = WSAStartup (version, &data);
      if (err != 0)
        return 1;

      if (data.wVersion < version)
        return 2;

      if (initialized_sockets_version == 0)
        register_fd_hook (close_fd_maybe_socket, ioctl_fd_maybe_socket,
                          &fd_sockets_hook);

      initialized_sockets_version = version;
    }
#endif

  return 0;
}

int
gl_sockets_cleanup (void)
{
#if WINDOWS_SOCKETS
  int err;

  initialized_sockets_version = 0;

  unregister_fd_hook (&fd_sockets_hook);

  err = WSACleanup ();
  if (err != 0)
    return 1;
#endif

  return 0;
}