Mercurial > hg > octave-shane > gnulib-hg
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 |
rev | line source |
---|---|
11898 | 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 | 3 |
4 This program is free software; you can redistribute it and/or modify | |
5 it under the terms of the GNU General Public License as published by | |
6 the Free Software Foundation; either version 2, or (at your option) | |
7 any later version. | |
8 | |
9 This program is distributed in the hope that it will be useful, | |
10 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 GNU General Public License for more details. | |
13 | |
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 | 16 |
17 #include <config.h> | |
18 | |
19 /* Specification. */ | |
20 #include <sys/socket.h> | |
21 | |
22 #include <errno.h> | |
23 #include <fcntl.h> | |
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 | 26 |
27 #ifndef SOCK_CLOEXEC | |
28 # define SOCK_CLOEXEC 0 | |
29 #endif | |
30 | |
31 int | |
32 accept4 (int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) | |
33 { | |
34 int fd; | |
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 | 56 /* Check the supported flags. */ |
57 if ((flags & ~(SOCK_CLOEXEC | O_TEXT | O_BINARY)) != 0) | |
58 { | |
59 errno = EINVAL; | |
60 return -1; | |
61 } | |
62 | |
63 fd = accept (sockfd, addr, addrlen); | |
64 if (fd < 0) | |
65 return -1; | |
66 | |
67 #if SOCK_CLOEXEC | |
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 | 70 if (flags & SOCK_CLOEXEC) |
71 { | |
72 HANDLE curr_process = GetCurrentProcess (); | |
73 HANDLE old_handle = (HANDLE) _get_osfhandle (fd); | |
74 HANDLE new_handle; | |
75 int nfd; | |
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 | 89 |
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 | 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 | 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 | 100 return nfd; |
101 } | |
102 # else | |
103 /* Unix API. */ | |
104 if (flags & SOCK_CLOEXEC) | |
105 { | |
106 int fcntl_flags; | |
107 | |
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 | 116 } |
117 # endif | |
118 #endif | |
119 | |
120 #if O_BINARY | |
121 if (flags & O_BINARY) | |
122 setmode (fd, O_BINARY); | |
123 else if (flags & O_TEXT) | |
124 setmode (fd, O_TEXT); | |
125 #endif | |
126 | |
127 return fd; | |
128 } |