annotate lib/accept4.c @ 17282:a4996fb12971

locale: port to Solaris 2.6 and 7 + GNU gettext * lib/locale.in.h: Just include_next <locale.h> when being invoked recursively. This prevents problems on Solaris 2.6 and 7 when combining the localename module with GNU gettext 0.18.2. Problem reported by Tom G. Christensen in <http://lists.gnu.org/archive/html/bug-gnulib/2013-01/msg00084.html>.
author Paul Eggert <eggert@cs.ucla.edu>
date Thu, 10 Jan 2013 13:24:13 -0800
parents e542fd46ad6f
children d8be19310ad9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11898
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1 /* Accept a connection on a socket, with specific opening flags.
17249
e542fd46ad6f maint: update all copyright year number ranges
Eric Blake <eblake@redhat.com>
parents: 16366
diff changeset
2 Copyright (C) 2009-2013 Free Software Foundation, Inc.
11898
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
3
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
4 This program is free software; you can redistribute it and/or modify
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
5 it under the terms of the GNU General Public License as published by
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
6 the Free Software Foundation; either version 2, or (at your option)
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
7 any later version.
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
8
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
9 This program is distributed in the hope that it will be useful,
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
12 GNU General Public License for more details.
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
13
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
14 You should have received a copy of the GNU General Public License along
16366
bb182ee4a09d maint: replace FSF snail-mail addresses with URLs
Paul Eggert <eggert@cs.ucla.edu>
parents: 16326
diff changeset
15 with this program; if not, see <http://www.gnu.org/licenses/>. */
11898
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
16
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
17 #include <config.h>
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
18
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
19 /* Specification. */
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
20 #include <sys/socket.h>
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
21
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
22 #include <errno.h>
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
23 #include <fcntl.h>
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
24 #include "binary-io.h"
15752
b86e9061a6d0 New module 'msvc-nothrow'. Makes _get_osfhandle safe on MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14079
diff changeset
25 #include "msvc-nothrow.h"
11898
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
26
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
27 #ifndef SOCK_CLOEXEC
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
28 # define SOCK_CLOEXEC 0
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
29 #endif
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
30
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
31 int
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
32 accept4 (int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags)
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
33 {
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
34 int fd;
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
35
11899
f0c8cf1802a2 Tolerate declared but missing accept4 syscall.
Bruno Haible <bruno@clisp.org>
parents: 11898
diff changeset
36 #if HAVE_ACCEPT4
f0c8cf1802a2 Tolerate declared but missing accept4 syscall.
Bruno Haible <bruno@clisp.org>
parents: 11898
diff changeset
37 # undef accept4
f0c8cf1802a2 Tolerate declared but missing accept4 syscall.
Bruno Haible <bruno@clisp.org>
parents: 11898
diff changeset
38 /* Try the system call first, if it exists. (We may be running with a glibc
f0c8cf1802a2 Tolerate declared but missing accept4 syscall.
Bruno Haible <bruno@clisp.org>
parents: 11898
diff changeset
39 that has the function but with an older kernel that lacks it.) */
f0c8cf1802a2 Tolerate declared but missing accept4 syscall.
Bruno Haible <bruno@clisp.org>
parents: 11898
diff changeset
40 {
f0c8cf1802a2 Tolerate declared but missing accept4 syscall.
Bruno Haible <bruno@clisp.org>
parents: 11898
diff changeset
41 /* Cache the information whether the system call really exists. */
f0c8cf1802a2 Tolerate declared but missing accept4 syscall.
Bruno Haible <bruno@clisp.org>
parents: 11898
diff changeset
42 static int have_accept4_really; /* 0 = unknown, 1 = yes, -1 = no */
f0c8cf1802a2 Tolerate declared but missing accept4 syscall.
Bruno Haible <bruno@clisp.org>
parents: 11898
diff changeset
43 if (have_accept4_really >= 0)
f0c8cf1802a2 Tolerate declared but missing accept4 syscall.
Bruno Haible <bruno@clisp.org>
parents: 11898
diff changeset
44 {
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
45 int result = accept4 (sockfd, addr, addrlen, flags);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
46 if (!(result < 0 && errno == ENOSYS))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
47 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
48 have_accept4_really = 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
49 return result;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
50 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
51 have_accept4_really = -1;
11899
f0c8cf1802a2 Tolerate declared but missing accept4 syscall.
Bruno Haible <bruno@clisp.org>
parents: 11898
diff changeset
52 }
f0c8cf1802a2 Tolerate declared but missing accept4 syscall.
Bruno Haible <bruno@clisp.org>
parents: 11898
diff changeset
53 }
f0c8cf1802a2 Tolerate declared but missing accept4 syscall.
Bruno Haible <bruno@clisp.org>
parents: 11898
diff changeset
54 #endif
f0c8cf1802a2 Tolerate declared but missing accept4 syscall.
Bruno Haible <bruno@clisp.org>
parents: 11898
diff changeset
55
11898
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
56 /* Check the supported flags. */
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
57 if ((flags & ~(SOCK_CLOEXEC | O_TEXT | O_BINARY)) != 0)
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
58 {
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
59 errno = EINVAL;
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
60 return -1;
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
61 }
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
62
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
63 fd = accept (sockfd, addr, addrlen);
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
64 if (fd < 0)
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
65 return -1;
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
66
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
67 #if SOCK_CLOEXEC
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
68 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
16242
59c686e5b2df Talk about "native Windows API", not "Woe32".
Bruno Haible <bruno@clisp.org>
parents: 16201
diff changeset
69 /* Native Windows API. */
11898
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
70 if (flags & SOCK_CLOEXEC)
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
71 {
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
72 HANDLE curr_process = GetCurrentProcess ();
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
73 HANDLE old_handle = (HANDLE) _get_osfhandle (fd);
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
74 HANDLE new_handle;
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
75 int nfd;
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
76
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
77 if (!DuplicateHandle (curr_process, /* SourceProcessHandle */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
78 old_handle, /* SourceHandle */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
79 curr_process, /* TargetProcessHandle */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
80 (PHANDLE) &new_handle, /* TargetHandle */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
81 (DWORD) 0, /* DesiredAccess */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
82 FALSE, /* InheritHandle */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
83 DUPLICATE_SAME_ACCESS)) /* Options */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
84 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
85 close (fd);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
86 errno = EBADF; /* arbitrary */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
87 return -1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
88 }
11898
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
89
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
90 /* Closing fd before allocating the new fd ensures that the new fd will
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
91 have the minimum possible value. */
11898
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
92 close (fd);
16326
067aa8df247a accept4, fcntl, socket modules: Avoid warnings on x86_64 mingw64.
Marc-André Lureau <marcandre.lureau@redhat.com>
parents: 16242
diff changeset
93 nfd = _open_osfhandle ((intptr_t) new_handle,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
94 O_NOINHERIT | (flags & (O_TEXT | O_BINARY)));
11898
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
95 if (nfd < 0)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
96 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
97 CloseHandle (new_handle);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
98 return -1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
99 }
11898
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
100 return nfd;
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
101 }
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
102 # else
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
103 /* Unix API. */
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
104 if (flags & SOCK_CLOEXEC)
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
105 {
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
106 int fcntl_flags;
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
107
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
108 if ((fcntl_flags = fcntl (fd, F_GETFD, 0)) < 0
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
109 || fcntl (fd, F_SETFD, fcntl_flags | FD_CLOEXEC) == -1)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
110 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
111 int saved_errno = errno;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
112 close (fd);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
113 errno = saved_errno;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
114 return -1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11899
diff changeset
115 }
11898
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
116 }
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
117 # endif
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
118 #endif
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
119
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
120 #if O_BINARY
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
121 if (flags & O_BINARY)
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
122 setmode (fd, O_BINARY);
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
123 else if (flags & O_TEXT)
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
124 setmode (fd, O_TEXT);
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
125 #endif
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
126
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
127 return fd;
90fb3f330caf New module 'accept4'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
128 }