~ubuntu-branches/ubuntu/precise/wget/precise-proposed

« back to all changes in this revision

Viewing changes to lib/sockets.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Langasek
  • Date: 2011-10-19 00:00:09 UTC
  • mfrom: (2.1.13 sid)
  • Revision ID: james.westby@ubuntu.com-20111019000009-8p33w3wz4b1rdri0
Tags: 1.13-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - Add wget-udeb to ship wget.gnu as alternative to busybox wget
    implementation.
  - Depend on libssl-dev 0.9.8k-7ubuntu4 (LP: #503339)
* Dropped changes, superseded in Debian:
  - Keep build dependencies in main:
    + debian/control: remove info2man build-dep
    + debian/patches/series: disable wget-infopod_generated_manpage
  - Mark wget Multi-Arch: foreign, so packages that aren't of the same arch
    can depend on it.
* Pass --with-ssl=openssl; we don't want to use gnutls, there's no udeb for
  it.
* Add a second build pass for the udeb, so we can build without libidn.

Show diffs side-by-side

added added

removed removed

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