summaryrefslogtreecommitdiff
path: root/lib/gl
diff options
context:
space:
mode:
authorSimon Josefsson <simon@josefsson.org>2009-03-30 12:08:38 +0200
committerSimon Josefsson <simon@josefsson.org>2009-03-30 12:08:38 +0200
commit96b8ed443933193a0d18ca21f5fd65028f948077 (patch)
treecb1e5b247f4170da6426627d8ae1fc6bb25f8f68 /lib/gl
parentfe5597bd4c51cfce5328b0a869a35dd5cda64a6b (diff)
downloadgnutls-96b8ed443933193a0d18ca21f5fd65028f948077.tar.gz
Update gnulib files.
Diffstat (limited to 'lib/gl')
-rw-r--r--lib/gl/Makefile.am11
-rw-r--r--lib/gl/close-hook.c91
-rw-r--r--lib/gl/close-hook.h72
-rw-r--r--lib/gl/fseeko.c8
-rw-r--r--lib/gl/m4/gnulib-common.m415
-rw-r--r--lib/gl/m4/gnulib-comp.m44
-rw-r--r--lib/gl/m4/printf.m424
-rw-r--r--lib/gl/sockets.c55
-rw-r--r--lib/gl/sockets.h10
-rw-r--r--lib/gl/stdint.in.h4
-rw-r--r--lib/gl/sys_socket.in.h6
-rw-r--r--lib/gl/tests/test-sockets.c2
-rw-r--r--lib/gl/unistd.in.h4
-rw-r--r--lib/gl/vasnprintf.c2
-rw-r--r--lib/gl/w32sock.h62
15 files changed, 347 insertions, 23 deletions
diff --git a/lib/gl/Makefile.am b/lib/gl/Makefile.am
index fd1e88972f..e06f9e1d19 100644
--- a/lib/gl/Makefile.am
+++ b/lib/gl/Makefile.am
@@ -29,6 +29,7 @@ SUBDIRS += tests
EXTRA_DIST += m4/gnulib-cache.m4
AM_CPPFLAGS =
+AM_CFLAGS =
noinst_LTLIBRARIES += liblgnu.la
@@ -78,6 +79,14 @@ liblgnu_la_SOURCES += c-ctype.h c-ctype.c
## end gnulib module c-ctype
+## begin gnulib module close-hook
+
+liblgnu_la_SOURCES += close-hook.c
+
+EXTRA_DIST += close-hook.h
+
+## end gnulib module close-hook
+
## begin gnulib module errno
BUILT_SOURCES += $(ERRNO_H)
@@ -270,6 +279,8 @@ EXTRA_liblgnu_la_SOURCES += snprintf.c
liblgnu_la_SOURCES += sockets.h sockets.c
+EXTRA_DIST += w32sock.h
+
## end gnulib module sockets
## begin gnulib module stdbool
diff --git a/lib/gl/close-hook.c b/lib/gl/close-hook.c
new file mode 100644
index 0000000000..045dcf7210
--- /dev/null
+++ b/lib/gl/close-hook.c
@@ -0,0 +1,91 @@
+/* Hook for making the close() function extensible.
+ Copyright (C) 2009 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2009.
+
+ This program is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include "close-hook.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#undef close
+
+
+/* Currently, this entire code is only needed for the handling of sockets
+ on native Windows platforms. */
+#if WINDOWS_SOCKETS
+
+/* The first and last link in the doubly linked list.
+ Initially the list is empty. */
+static struct close_hook anchor = { &anchor, &anchor, NULL };
+
+int
+execute_close_hooks (int fd, const struct close_hook *remaining_list)
+{
+ if (remaining_list == &anchor)
+ /* End of list reached. */
+ return close (fd);
+ else
+ return remaining_list->private_fn (fd, remaining_list->private_next);
+}
+
+int
+execute_all_close_hooks (int fd)
+{
+ return execute_close_hooks (fd, anchor.private_next);
+}
+
+void
+register_close_hook (close_hook_fn hook, struct close_hook *link)
+{
+ if (link->private_next == NULL && link->private_prev == NULL)
+ {
+ /* Add the link to the doubly linked list. */
+ link->private_next = anchor.private_next;
+ link->private_prev = &anchor;
+ link->private_fn = hook;
+ anchor.private_next->private_prev = link;
+ anchor.private_next = link;
+ }
+ else
+ {
+ /* The link is already in use. */
+ if (link->private_fn != hook)
+ abort ();
+ }
+}
+
+void
+unregister_close_hook (struct close_hook *link)
+{
+ struct close_hook *next = link->private_next;
+ struct close_hook *prev = link->private_prev;
+
+ if (next != NULL && prev != NULL)
+ {
+ /* The link is in use. Remove it from the doubly linked list. */
+ prev->private_next = next;
+ next->private_prev = prev;
+ /* Clear the link, to mark it unused. */
+ link->private_next = NULL;
+ link->private_prev = NULL;
+ link->private_fn = NULL;
+ }
+}
+
+#endif
diff --git a/lib/gl/close-hook.h b/lib/gl/close-hook.h
new file mode 100644
index 0000000000..483d69c8da
--- /dev/null
+++ b/lib/gl/close-hook.h
@@ -0,0 +1,72 @@
+/* Hook for making the close() function extensible.
+ Copyright (C) 2009 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+
+#ifndef CLOSE_HOOK_H
+#define CLOSE_HOOK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Currently, this entire code is only needed for the handling of sockets
+ on native Windows platforms. */
+#if WINDOWS_SOCKETS
+
+
+/* An element of the list of close hooks.
+ The fields of this structure are considered private. */
+struct close_hook
+{
+ /* Doubly linked list. */
+ struct close_hook *private_next;
+ struct close_hook *private_prev;
+ /* Function that treats the types of FD that it knows about and calls
+ execute_close_hooks (FD, REMAINING_LIST) as a fallback. */
+ int (*private_fn) (int fd, const struct close_hook *remaining_list);
+};
+
+/* This type of function closes FD, applying special knowledge for the FD
+ types it knows about, and calls execute_close_hooks (FD, REMAINING_LIST)
+ for the other FD types. */
+typedef int (*close_hook_fn) (int fd, const struct close_hook *remaining_list);
+
+/* Execute the close hooks in REMAINING_LIST.
+ Return 0 or -1, like close() would do. */
+extern int execute_close_hooks (int fd, const struct close_hook *remaining_list);
+
+/* Execute all close hooks.
+ Return 0 or -1, like close() would do. */
+extern int execute_all_close_hooks (int fd);
+
+/* Add a function to the list of close hooks.
+ The LINK variable points to a piece of memory which is guaranteed to be
+ accessible until the corresponding call to unregister_close_hook. */
+extern void register_close_hook (close_hook_fn hook, struct close_hook *link);
+
+/* Removes a function from the list of close hooks. */
+extern void unregister_close_hook (struct close_hook *link);
+
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CLOSE_HOOK_H */
diff --git a/lib/gl/fseeko.c b/lib/gl/fseeko.c
index 7ba8e58431..b2ed87c420 100644
--- a/lib/gl/fseeko.c
+++ b/lib/gl/fseeko.c
@@ -82,6 +82,11 @@ rpl_fseeko (FILE *fp, off_t offset, int whence)
if ((fp->_Mode & _MWRITE ? fp->_Next == fp->_Buf : fp->_Next == fp->_Rend)
&& fp->_Rback == fp->_Back + sizeof (fp->_Back)
&& fp->_Rsave == NULL)
+#elif defined __MINT__ /* Atari FreeMiNT */
+ if (fp->__bufp == fp->__buffer
+ && fp->__get_limit == fp->__bufp
+ && fp->__put_limit == fp->__bufp
+ && !fp->__pushed_back)
#else
#error "Please port gnulib fseeko.c to your platform! Look at the code in fpurge.c, then report this to bug-gnulib."
#endif
@@ -112,6 +117,9 @@ rpl_fseeko (FILE *fp, off_t offset, int whence)
fp->_flags &= ~_IOEOF;
#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw */
fp->_flag &= ~_IOEOF;
+#elif defined __MINT__ /* Atari FreeMiNT */
+ fp->__offset = pos;
+ fp->__eof = 0;
#endif
/* If we were not requested to position beyond end of file, we're
done. */
diff --git a/lib/gl/m4/gnulib-common.m4 b/lib/gl/m4/gnulib-common.m4
index 50e399aa1c..c8fda20330 100644
--- a/lib/gl/m4/gnulib-common.m4
+++ b/lib/gl/m4/gnulib-common.m4
@@ -1,4 +1,4 @@
-# gnulib-common.m4 serial 10
+# gnulib-common.m4 serial 11
dnl Copyright (C) 2007-2009 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -109,3 +109,16 @@ AC_DEFUN([gl_BIGENDIAN],
[
AC_C_BIGENDIAN
])
+
+# gl_CACHE_VAL_SILENT(cache-id, command-to-set-it)
+# is like AC_CACHE_VAL(cache-id, command-to-set-it), except that it does not
+# output a spurious "(cached)" mark in the midst of other configure output.
+# This macro should be used instead of AC_CACHE_VAL when it is not surrounded
+# by an AC_MSG_CHECKING/AC_MSG_RESULT pair.
+AC_DEFUN([gl_CACHE_VAL_SILENT],
+[
+ saved_as_echo_n="$as_echo_n"
+ as_echo_n=':'
+ AC_CACHE_VAL([$1], [$2])
+ as_echo_n="$saved_as_echo_n"
+])
diff --git a/lib/gl/m4/gnulib-comp.m4 b/lib/gl/m4/gnulib-comp.m4
index 77ca8b8fd9..2319787e96 100644
--- a/lib/gl/m4/gnulib-comp.m4
+++ b/lib/gl/m4/gnulib-comp.m4
@@ -79,7 +79,6 @@ AC_DEFUN([lgl_INIT],
gl_FUNC_STRVERSCMP
gl_STRING_MODULE_INDICATOR([strverscmp])
gl_HEADER_SYS_SOCKET
- gl_MODULE_INDICATOR([sys_socket])
AC_PROG_MKDIR_P
gl_HEADER_SYS_STAT_H
AC_PROG_MKDIR_P
@@ -236,6 +235,8 @@ AC_DEFUN([lgl_FILE_LIST], [
lib/byteswap.in.h
lib/c-ctype.c
lib/c-ctype.h
+ lib/close-hook.c
+ lib/close-hook.h
lib/errno.in.h
lib/float+.h
lib/float.in.h
@@ -277,6 +278,7 @@ AC_DEFUN([lgl_FILE_LIST], [
lib/vasnprintf.c
lib/vasnprintf.h
lib/vasprintf.c
+ lib/w32sock.h
lib/wchar.in.h
lib/xsize.h
m4/00gnulib.m4
diff --git a/lib/gl/m4/printf.m4 b/lib/gl/m4/printf.m4
index 4207ace49f..87aa45c5e7 100644
--- a/lib/gl/m4/printf.m4
+++ b/lib/gl/m4/printf.m4
@@ -1,4 +1,4 @@
-# printf.m4 serial 31
+# printf.m4 serial 33
dnl Copyright (C) 2003, 2007-2009 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -558,7 +558,7 @@ int main ()
if (sprintf (buf, "%F", 1.0 / 0.0) < 0
|| (strcmp (buf, "INF") != 0 && strcmp (buf, "INFINITY") != 0))
return 1;
- /* This catches a Cygwin 2007 bug. */
+ /* This catches a Cygwin 1.5.x bug. */
if (sprintf (buf, "%.F", 1234.0) < 0
|| strcmp (buf, "1234") != 0)
return 1;
@@ -653,7 +653,8 @@ int main ()
{
char buf[100];
/* Test whether %ls works at all.
- This test fails on OpenBSD 4.0, IRIX 6.5, Solaris 2.6, Haiku. */
+ This test fails on OpenBSD 4.0, IRIX 6.5, Solaris 2.6, Haiku, but not on
+ Cygwin 1.5. */
{
static const wchar_t wstring[] = { 'a', 'b', 'c', 0 };
buf[0] = '\0';
@@ -661,6 +662,15 @@ int main ()
|| strcmp (buf, "abc") != 0)
return 1;
}
+ /* This test fails on IRIX 6.5, Solaris 2.6, Cygwin 1.5, Haiku (with an
+ assertion failure inside libc), but not on OpenBSD 4.0. */
+ {
+ static const wchar_t wstring[] = { 'a', 0 };
+ buf[0] = '\0';
+ if (sprintf (buf, "%ls", wstring) < 0
+ || strcmp (buf, "a") != 0)
+ return 1;
+ }
/* Test whether precisions in %ls are supported as specified in ISO C 99
section 7.19.6.1:
"If a precision is specified, no more than that many bytes are written
@@ -682,8 +692,9 @@ int main ()
changequote(,)dnl
case "$host_os" in
openbsd*) gl_cv_func_printf_directive_ls="guessing no";;
- solaris*) gl_cv_func_printf_directive_ls="guessing no";;
irix*) gl_cv_func_printf_directive_ls="guessing no";;
+ solaris*) gl_cv_func_printf_directive_ls="guessing no";;
+ cygwin*) gl_cv_func_printf_directive_ls="guessing no";;
beos* | haiku*) gl_cv_func_printf_directive_ls="guessing no";;
*) gl_cv_func_printf_directive_ls="guessing yes";;
esac
@@ -1384,8 +1395,9 @@ dnl glibc 2.3.6 . . . . # . . . . . . . . . .
dnl FreeBSD 5.4, 6.1 . . . . # . . . . . . # . # . . . . . .
dnl MacOS X 10.3.9 . . . . # . . . . . . # . # . . . . . .
dnl OpenBSD 3.9, 4.0 . . # # # # . # . # . # . # . . . . . .
-dnl Cygwin 2007 (= Cygwin 1.5.24) . . . . # # . . . . ? # ? ? . . . . . .
-dnl Cygwin 2006 (= Cygwin 1.5.19) # . . . # # . ? . # ? # ? ? . . . . . .
+dnl Cygwin 1.7.0 (2009) . . . # . . . ? . . . . . ? . . . . . .
+dnl Cygwin 1.5.25 (2008) . . . # # . . # . . . . . # . . . . . .
+dnl Cygwin 1.5.19 (2006) # . . # # # . # . # . # # # . . . . . .
dnl Solaris 10 . . # # # . . # . . . # . . . . . . . .
dnl Solaris 2.6 ... 9 # . # # # # . # . . . # . . . . . . . .
dnl Solaris 2.5.1 # . # # # # . # . . . # . . # # # # # #
diff --git a/lib/gl/sockets.c b/lib/gl/sockets.c
index 4d03346e64..758bad98ae 100644
--- a/lib/gl/sockets.c
+++ b/lib/gl/sockets.c
@@ -1,6 +1,6 @@
/* sockets.c --- wrappers for Windows socket functions
- Copyright (C) 2008 Free Software Foundation, Inc.
+ Copyright (C) 2008-2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
@@ -19,10 +19,57 @@
#include <config.h>
+/* Specification. */
+#include "sockets.h"
+
+#if WINDOWS_SOCKETS
+
/* This includes winsock2.h on MinGW. */
#include <sys/socket.h>
-#include "sockets.h"
+#include "close-hook.h"
+
+/* Get set_winsock_errno, FD_TO_SOCKET etc. */
+#include "w32sock.h"
+
+static int
+close_fd_maybe_socket (int fd, const struct close_hook *remaining_list)
+{
+ 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 (fd, remaining_list);
+}
+
+static struct close_hook close_sockets_hook;
+
+#endif
int
gl_sockets_startup (int version)
@@ -37,6 +84,8 @@ gl_sockets_startup (int version)
if (data.wVersion < version)
return 2;
+
+ register_close_hook (close_fd_maybe_socket, &close_sockets_hook);
#endif
return 0;
@@ -48,6 +97,8 @@ gl_sockets_cleanup (void)
#if WINDOWS_SOCKETS
int err;
+ unregister_close_hook (&close_sockets_hook);
+
err = WSACleanup ();
if (err != 0)
return 1;
diff --git a/lib/gl/sockets.h b/lib/gl/sockets.h
index 6785824bd0..315d1b6422 100644
--- a/lib/gl/sockets.h
+++ b/lib/gl/sockets.h
@@ -33,13 +33,19 @@ int gl_sockets_cleanup (void);
Winsock wrappers but needs to pass on the socket handle to some
other library that only accepts sockets. */
#if WINDOWS_SOCKETS
+
+#include <sys/socket.h>
+
static inline SOCKET
gl_fd_to_handle (int fd)
{
return _get_osfhandle (fd);
}
+
#else
+
#define gl_fd_to_handle(x) (x)
-#endif
-#endif
+#endif /* WINDOWS_SOCKETS */
+
+#endif /* SOCKETS_H */
diff --git a/lib/gl/stdint.in.h b/lib/gl/stdint.in.h
index 7cbfc2cf7e..e7a3be57b0 100644
--- a/lib/gl/stdint.in.h
+++ b/lib/gl/stdint.in.h
@@ -435,7 +435,7 @@ typedef int _verify_intmax_size[2 * (sizeof (intmax_t) == sizeof (uintmax_t)) -
#undef PTRDIFF_MIN
#undef PTRDIFF_MAX
#if @APPLE_UNIVERSAL_BUILD@
-# if _LP64
+# ifdef _LP64
# define PTRDIFF_MIN _STDINT_MIN (1, 64, 0l)
# define PTRDIFF_MAX _STDINT_MAX (1, 64, 0l)
# else
@@ -463,7 +463,7 @@ typedef int _verify_intmax_size[2 * (sizeof (intmax_t) == sizeof (uintmax_t)) -
/* size_t limit */
#undef SIZE_MAX
#if @APPLE_UNIVERSAL_BUILD@
-# if _LP64
+# ifdef _LP64
# define SIZE_MAX _STDINT_MAX (0, 64, 0ul)
# else
# define SIZE_MAX _STDINT_MAX (0, 32, 0ul)
diff --git a/lib/gl/sys_socket.in.h b/lib/gl/sys_socket.in.h
index c8247e9ab3..575bbb7517 100644
--- a/lib/gl/sys_socket.in.h
+++ b/lib/gl/sys_socket.in.h
@@ -1,6 +1,6 @@
/* Provide a sys/socket header file for systems lacking it (read: MinGW)
and for systems where it is incomplete.
- Copyright (C) 2005-2008 Free Software Foundation, Inc.
+ Copyright (C) 2005-2009 Free Software Foundation, Inc.
Written by Simon Josefsson.
This program is free software; you can redistribute it and/or modify
@@ -256,7 +256,7 @@ extern int rpl_getsockname (int, struct sockaddr *, int *);
# if @HAVE_WINSOCK2_H@
# undef getsockopt
# define getsockopt rpl_getsockopt
-extern int rpl_getsockopt (int, int, int, void *, int *);
+extern int rpl_getsockopt (int, int, int, void *, socklen_t *);
# endif
# elif @HAVE_WINSOCK2_H@
# undef getsockopt
@@ -358,7 +358,7 @@ extern int rpl_sendto (int, const void *, int, int, struct sockaddr *, int);
# if @HAVE_WINSOCK2_H@
# undef setsockopt
# define setsockopt rpl_setsockopt
-extern int rpl_setsockopt (int, int, int, const void *, int);
+extern int rpl_setsockopt (int, int, int, const void *, socklen_t);
# endif
# elif @HAVE_WINSOCK2_H@
# undef setsockopt
diff --git a/lib/gl/tests/test-sockets.c b/lib/gl/tests/test-sockets.c
index a37a1978c4..3c85a431c5 100644
--- a/lib/gl/tests/test-sockets.c
+++ b/lib/gl/tests/test-sockets.c
@@ -40,7 +40,7 @@ main (int argc, char *argv[])
return 1;
}
- gl_fd_to_handle (0);
+ (void) gl_fd_to_handle (0);
return 0;
}
diff --git a/lib/gl/unistd.in.h b/lib/gl/unistd.in.h
index c1a2d2ba99..4c1fc3fdaa 100644
--- a/lib/gl/unistd.in.h
+++ b/lib/gl/unistd.in.h
@@ -131,10 +131,6 @@ extern int chown (const char *file, uid_t uid, gid_t gid);
#if @GNULIB_CLOSE@
-# if @UNISTD_H_HAVE_WINSOCK2_H@
-/* Need a gnulib internal function. */
-# define HAVE__GL_CLOSE_FD_MAYBE_SOCKET 1
-# endif
# if @REPLACE_CLOSE@
/* Automatically included by modules that need a replacement for close. */
# undef close
diff --git a/lib/gl/vasnprintf.c b/lib/gl/vasnprintf.c
index f7cf309c4d..67834fa913 100644
--- a/lib/gl/vasnprintf.c
+++ b/lib/gl/vasnprintf.c
@@ -413,7 +413,7 @@ divide (mpn_t a, mpn_t b, mpn_t *q)
Normalise [q[m-1],...,q[0]], yields q.
If m>=n>1, perform a multiple-precision division:
We have a/b < beta^(m-n+1).
- s:=intDsize-1-(hightest bit in b[n-1]), 0<=s<intDsize.
+ s:=intDsize-1-(highest bit in b[n-1]), 0<=s<intDsize.
Shift a and b left by s bits, copying them. r:=a.
r=[r[m],...,r[0]], b=[b[n-1],...,b[0]] with b[n-1]>=beta/2.
For j=m-n,...,0: {Here 0 <= r < b*beta^(j+1).}
diff --git a/lib/gl/w32sock.h b/lib/gl/w32sock.h
new file mode 100644
index 0000000000..12977f7cab
--- /dev/null
+++ b/lib/gl/w32sock.h
@@ -0,0 +1,62 @@
+/* w32sock.h --- internal auxilliary functions for Windows socket functions
+
+ Copyright (C) 2008 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Paolo Bonzini */
+
+#include <errno.h>
+
+/* Get O_RDWR and O_BINARY. */
+#include <fcntl.h>
+
+/* Get _get_osfhandle() and _open_osfhandle(). */
+#include <io.h>
+
+#define FD_TO_SOCKET(fd) ((SOCKET) _get_osfhandle ((fd)))
+#define SOCKET_TO_FD(fh) (_open_osfhandle ((long) (fh), O_RDWR | O_BINARY))
+
+static inline void
+set_winsock_errno (void)
+{
+ int err = WSAGetLastError ();
+ WSASetLastError (0);
+
+ /* Map some WSAE* errors to the runtime library's error codes. */
+ switch (err)
+ {
+ case WSA_INVALID_HANDLE:
+ errno = EBADF;
+ break;
+ case WSA_NOT_ENOUGH_MEMORY:
+ errno = ENOMEM;
+ break;
+ case WSA_INVALID_PARAMETER:
+ errno = EINVAL;
+ break;
+ case WSAEWOULDBLOCK:
+ errno = EWOULDBLOCK;
+ break;
+ case WSAENAMETOOLONG:
+ errno = ENAMETOOLONG;
+ break;
+ case WSAENOTEMPTY:
+ errno = ENOTEMPTY;
+ break;
+ default:
+ errno = (err > 10000 && err < 10025) ? err - 10000 : err;
+ break;
+ }
+}