Mercurial > hg > octave-nkf > gnulib-hg
annotate lib/pipe2.c @ 17907:0a1c2535cad9
euidaccess: Fix Android build
* modules/euidaccess (Depends-on): Add fcntl-h to ensure that
AT_EACCESS gets declared.
author | Kevin Cernekee <cernekee@google.com> |
---|---|
date | Wed, 11 Feb 2015 15:22:54 -0800 |
parents | ab58d4870664 |
children |
rev | line source |
---|---|
11870 | 1 /* Create a pipe, with specific opening flags. |
17848 | 2 Copyright (C) 2009-2015 Free Software Foundation, Inc. |
11870 | 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:
16242
diff
changeset
|
15 with this program; if not, see <http://www.gnu.org/licenses/>. */ |
11870 | 16 |
17 #include <config.h> | |
18 | |
19 /* Specification. */ | |
20 #include <unistd.h> | |
21 | |
22 #include <errno.h> | |
23 #include <fcntl.h> | |
24 | |
17447
d8be19310ad9
accept4, dup3, pipe2: port to Cygwin
Paul Eggert <eggert@cs.ucla.edu>
parents:
17443
diff
changeset
|
25 #include "binary-io.h" |
14856
c593fd7d2ab9
pipe2: Remove dependency on 'nonblocking' module.
Bruno Haible <bruno@clisp.org>
parents:
14592
diff
changeset
|
26 #include "verify.h" |
c593fd7d2ab9
pipe2: Remove dependency on 'nonblocking' module.
Bruno Haible <bruno@clisp.org>
parents:
14592
diff
changeset
|
27 |
c593fd7d2ab9
pipe2: Remove dependency on 'nonblocking' module.
Bruno Haible <bruno@clisp.org>
parents:
14592
diff
changeset
|
28 #if GNULIB_defined_O_NONBLOCK |
c593fd7d2ab9
pipe2: Remove dependency on 'nonblocking' module.
Bruno Haible <bruno@clisp.org>
parents:
14592
diff
changeset
|
29 # include "nonblocking.h" |
c593fd7d2ab9
pipe2: Remove dependency on 'nonblocking' module.
Bruno Haible <bruno@clisp.org>
parents:
14592
diff
changeset
|
30 #endif |
11900
ec8584c5c427
dup2, pipe2: fix some recent test failures on cygwin 1.5.x
Eric Blake <ebb9@byu.net>
parents:
11895
diff
changeset
|
31 |
11870 | 32 #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
|
33 /* Native Windows API. */ |
11870 | 34 |
35 # include <io.h> | |
36 | |
11892
26347f7d2cac
Move #ifs inside function.
Bruno Haible <bruno@clisp.org>
parents:
11881
diff
changeset
|
37 #endif |
26347f7d2cac
Move #ifs inside function.
Bruno Haible <bruno@clisp.org>
parents:
11881
diff
changeset
|
38 |
11870 | 39 int |
40 pipe2 (int fd[2], int flags) | |
41 { | |
15326
52719068f9c2
pipe, pipe2: don't corrupt fd on error
Eric Blake <eblake@redhat.com>
parents:
14856
diff
changeset
|
42 /* Mingw _pipe() corrupts fd on failure; also, if we succeed at |
52719068f9c2
pipe, pipe2: don't corrupt fd on error
Eric Blake <eblake@redhat.com>
parents:
14856
diff
changeset
|
43 creating the pipe but later fail at changing fcntl, we want |
52719068f9c2
pipe, pipe2: don't corrupt fd on error
Eric Blake <eblake@redhat.com>
parents:
14856
diff
changeset
|
44 to leave fd unchanged: http://austingroupbugs.net/view.php?id=467 */ |
15327
5e07722935cf
pipe2: fix C89 compile problem
Eric Blake <eblake@redhat.com>
parents:
15326
diff
changeset
|
45 int tmp[2]; |
5e07722935cf
pipe2: fix C89 compile problem
Eric Blake <eblake@redhat.com>
parents:
15326
diff
changeset
|
46 tmp[0] = fd[0]; |
5e07722935cf
pipe2: fix C89 compile problem
Eric Blake <eblake@redhat.com>
parents:
15326
diff
changeset
|
47 tmp[1] = fd[1]; |
15326
52719068f9c2
pipe, pipe2: don't corrupt fd on error
Eric Blake <eblake@redhat.com>
parents:
14856
diff
changeset
|
48 |
11893
476cefda5290
Tolerate declared but missing pipe2 syscall.
Bruno Haible <bruno@clisp.org>
parents:
11892
diff
changeset
|
49 #if HAVE_PIPE2 |
476cefda5290
Tolerate declared but missing pipe2 syscall.
Bruno Haible <bruno@clisp.org>
parents:
11892
diff
changeset
|
50 # undef pipe2 |
476cefda5290
Tolerate declared but missing pipe2 syscall.
Bruno Haible <bruno@clisp.org>
parents:
11892
diff
changeset
|
51 /* Try the system call first, if it exists. (We may be running with a glibc |
476cefda5290
Tolerate declared but missing pipe2 syscall.
Bruno Haible <bruno@clisp.org>
parents:
11892
diff
changeset
|
52 that has the function but with an older kernel that lacks it.) */ |
476cefda5290
Tolerate declared but missing pipe2 syscall.
Bruno Haible <bruno@clisp.org>
parents:
11892
diff
changeset
|
53 { |
11895
3ef16b8c79cd
Avoid running into nonexistent system calls repeatedly.
Bruno Haible <bruno@clisp.org>
parents:
11893
diff
changeset
|
54 /* Cache the information whether the system call really exists. */ |
3ef16b8c79cd
Avoid running into nonexistent system calls repeatedly.
Bruno Haible <bruno@clisp.org>
parents:
11893
diff
changeset
|
55 static int have_pipe2_really; /* 0 = unknown, 1 = yes, -1 = no */ |
3ef16b8c79cd
Avoid running into nonexistent system calls repeatedly.
Bruno Haible <bruno@clisp.org>
parents:
11893
diff
changeset
|
56 if (have_pipe2_really >= 0) |
3ef16b8c79cd
Avoid running into nonexistent system calls repeatedly.
Bruno Haible <bruno@clisp.org>
parents:
11893
diff
changeset
|
57 { |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11900
diff
changeset
|
58 int result = pipe2 (fd, flags); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11900
diff
changeset
|
59 if (!(result < 0 && errno == ENOSYS)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11900
diff
changeset
|
60 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11900
diff
changeset
|
61 have_pipe2_really = 1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11900
diff
changeset
|
62 return result; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11900
diff
changeset
|
63 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11900
diff
changeset
|
64 have_pipe2_really = -1; |
11895
3ef16b8c79cd
Avoid running into nonexistent system calls repeatedly.
Bruno Haible <bruno@clisp.org>
parents:
11893
diff
changeset
|
65 } |
11893
476cefda5290
Tolerate declared but missing pipe2 syscall.
Bruno Haible <bruno@clisp.org>
parents:
11892
diff
changeset
|
66 } |
476cefda5290
Tolerate declared but missing pipe2 syscall.
Bruno Haible <bruno@clisp.org>
parents:
11892
diff
changeset
|
67 #endif |
476cefda5290
Tolerate declared but missing pipe2 syscall.
Bruno Haible <bruno@clisp.org>
parents:
11892
diff
changeset
|
68 |
11870 | 69 /* Check the supported flags. */ |
14535
7ba508565384
pipe2: fix O_NONBLOCK support on mingw
Eric Blake <eblake@redhat.com>
parents:
14079
diff
changeset
|
70 if ((flags & ~(O_CLOEXEC | O_NONBLOCK | O_BINARY | O_TEXT)) != 0) |
11870 | 71 { |
72 errno = EINVAL; | |
73 return -1; | |
74 } | |
75 | |
14535
7ba508565384
pipe2: fix O_NONBLOCK support on mingw
Eric Blake <eblake@redhat.com>
parents:
14079
diff
changeset
|
76 #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
|
77 /* Native Windows API. */ |
14535
7ba508565384
pipe2: fix O_NONBLOCK support on mingw
Eric Blake <eblake@redhat.com>
parents:
14079
diff
changeset
|
78 |
14592 | 79 if (_pipe (fd, 4096, flags & ~O_NONBLOCK) < 0) |
15326
52719068f9c2
pipe, pipe2: don't corrupt fd on error
Eric Blake <eblake@redhat.com>
parents:
14856
diff
changeset
|
80 { |
52719068f9c2
pipe, pipe2: don't corrupt fd on error
Eric Blake <eblake@redhat.com>
parents:
14856
diff
changeset
|
81 fd[0] = tmp[0]; |
52719068f9c2
pipe, pipe2: don't corrupt fd on error
Eric Blake <eblake@redhat.com>
parents:
14856
diff
changeset
|
82 fd[1] = tmp[1]; |
52719068f9c2
pipe, pipe2: don't corrupt fd on error
Eric Blake <eblake@redhat.com>
parents:
14856
diff
changeset
|
83 return -1; |
52719068f9c2
pipe, pipe2: don't corrupt fd on error
Eric Blake <eblake@redhat.com>
parents:
14856
diff
changeset
|
84 } |
14592 | 85 |
14856
c593fd7d2ab9
pipe2: Remove dependency on 'nonblocking' module.
Bruno Haible <bruno@clisp.org>
parents:
14592
diff
changeset
|
86 /* O_NONBLOCK handling. |
c593fd7d2ab9
pipe2: Remove dependency on 'nonblocking' module.
Bruno Haible <bruno@clisp.org>
parents:
14592
diff
changeset
|
87 On native Windows platforms, O_NONBLOCK is defined by gnulib. Use the |
c593fd7d2ab9
pipe2: Remove dependency on 'nonblocking' module.
Bruno Haible <bruno@clisp.org>
parents:
14592
diff
changeset
|
88 functions defined by the gnulib module 'nonblocking'. */ |
c593fd7d2ab9
pipe2: Remove dependency on 'nonblocking' module.
Bruno Haible <bruno@clisp.org>
parents:
14592
diff
changeset
|
89 # if GNULIB_defined_O_NONBLOCK |
14535
7ba508565384
pipe2: fix O_NONBLOCK support on mingw
Eric Blake <eblake@redhat.com>
parents:
14079
diff
changeset
|
90 if (flags & O_NONBLOCK) |
7ba508565384
pipe2: fix O_NONBLOCK support on mingw
Eric Blake <eblake@redhat.com>
parents:
14079
diff
changeset
|
91 { |
7ba508565384
pipe2: fix O_NONBLOCK support on mingw
Eric Blake <eblake@redhat.com>
parents:
14079
diff
changeset
|
92 if (set_nonblocking_flag (fd[0], true) != 0 |
7ba508565384
pipe2: fix O_NONBLOCK support on mingw
Eric Blake <eblake@redhat.com>
parents:
14079
diff
changeset
|
93 || set_nonblocking_flag (fd[1], true) != 0) |
14592 | 94 goto fail; |
14535
7ba508565384
pipe2: fix O_NONBLOCK support on mingw
Eric Blake <eblake@redhat.com>
parents:
14079
diff
changeset
|
95 } |
14856
c593fd7d2ab9
pipe2: Remove dependency on 'nonblocking' module.
Bruno Haible <bruno@clisp.org>
parents:
14592
diff
changeset
|
96 # else |
15754
05bdc6eefa07
pipe2: Fix compilation on pre-C99 compilers.
Bruno Haible <bruno@clisp.org>
parents:
15519
diff
changeset
|
97 { |
05bdc6eefa07
pipe2: Fix compilation on pre-C99 compilers.
Bruno Haible <bruno@clisp.org>
parents:
15519
diff
changeset
|
98 verify (O_NONBLOCK == 0); |
05bdc6eefa07
pipe2: Fix compilation on pre-C99 compilers.
Bruno Haible <bruno@clisp.org>
parents:
15519
diff
changeset
|
99 } |
14856
c593fd7d2ab9
pipe2: Remove dependency on 'nonblocking' module.
Bruno Haible <bruno@clisp.org>
parents:
14592
diff
changeset
|
100 # endif |
14592 | 101 |
102 return 0; | |
11870 | 103 |
104 #else | |
105 /* Unix API. */ | |
106 | |
107 if (pipe (fd) < 0) | |
108 return -1; | |
109 | |
110 /* POSIX <http://www.opengroup.org/onlinepubs/9699919799/functions/pipe.html> | |
111 says that initially, the O_NONBLOCK and FD_CLOEXEC flags are cleared on | |
14535
7ba508565384
pipe2: fix O_NONBLOCK support on mingw
Eric Blake <eblake@redhat.com>
parents:
14079
diff
changeset
|
112 both fd[0] and fd[1]. */ |
11870 | 113 |
14856
c593fd7d2ab9
pipe2: Remove dependency on 'nonblocking' module.
Bruno Haible <bruno@clisp.org>
parents:
14592
diff
changeset
|
114 /* O_NONBLOCK handling. |
c593fd7d2ab9
pipe2: Remove dependency on 'nonblocking' module.
Bruno Haible <bruno@clisp.org>
parents:
14592
diff
changeset
|
115 On Unix platforms, O_NONBLOCK is defined by the system. Use fcntl(). */ |
11870 | 116 if (flags & O_NONBLOCK) |
117 { | |
118 int fcntl_flags; | |
119 | |
120 if ((fcntl_flags = fcntl (fd[1], F_GETFL, 0)) < 0 | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11900
diff
changeset
|
121 || fcntl (fd[1], F_SETFL, fcntl_flags | O_NONBLOCK) == -1 |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11900
diff
changeset
|
122 || (fcntl_flags = fcntl (fd[0], F_GETFL, 0)) < 0 |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11900
diff
changeset
|
123 || fcntl (fd[0], F_SETFL, fcntl_flags | O_NONBLOCK) == -1) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11900
diff
changeset
|
124 goto fail; |
11870 | 125 } |
126 | |
127 if (flags & O_CLOEXEC) | |
128 { | |
129 int fcntl_flags; | |
130 | |
131 if ((fcntl_flags = fcntl (fd[1], F_GETFD, 0)) < 0 | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11900
diff
changeset
|
132 || fcntl (fd[1], F_SETFD, fcntl_flags | FD_CLOEXEC) == -1 |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11900
diff
changeset
|
133 || (fcntl_flags = fcntl (fd[0], F_GETFD, 0)) < 0 |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11900
diff
changeset
|
134 || fcntl (fd[0], F_SETFD, fcntl_flags | FD_CLOEXEC) == -1) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11900
diff
changeset
|
135 goto fail; |
11870 | 136 } |
137 | |
11892
26347f7d2cac
Move #ifs inside function.
Bruno Haible <bruno@clisp.org>
parents:
11881
diff
changeset
|
138 # if O_BINARY |
11880
d5e0338c205a
Support O_TEXT, O_BINARY on all platforms.
Bruno Haible <bruno@clisp.org>
parents:
11879
diff
changeset
|
139 if (flags & O_BINARY) |
11881 | 140 { |
17447
d8be19310ad9
accept4, dup3, pipe2: port to Cygwin
Paul Eggert <eggert@cs.ucla.edu>
parents:
17443
diff
changeset
|
141 set_binary_mode (fd[1], O_BINARY); |
d8be19310ad9
accept4, dup3, pipe2: port to Cygwin
Paul Eggert <eggert@cs.ucla.edu>
parents:
17443
diff
changeset
|
142 set_binary_mode (fd[0], O_BINARY); |
11881 | 143 } |
11880
d5e0338c205a
Support O_TEXT, O_BINARY on all platforms.
Bruno Haible <bruno@clisp.org>
parents:
11879
diff
changeset
|
144 else if (flags & O_TEXT) |
11881 | 145 { |
17447
d8be19310ad9
accept4, dup3, pipe2: port to Cygwin
Paul Eggert <eggert@cs.ucla.edu>
parents:
17443
diff
changeset
|
146 set_binary_mode (fd[1], O_TEXT); |
d8be19310ad9
accept4, dup3, pipe2: port to Cygwin
Paul Eggert <eggert@cs.ucla.edu>
parents:
17443
diff
changeset
|
147 set_binary_mode (fd[0], O_TEXT); |
11881 | 148 } |
11892
26347f7d2cac
Move #ifs inside function.
Bruno Haible <bruno@clisp.org>
parents:
11881
diff
changeset
|
149 # endif |
11880
d5e0338c205a
Support O_TEXT, O_BINARY on all platforms.
Bruno Haible <bruno@clisp.org>
parents:
11879
diff
changeset
|
150 |
11870 | 151 return 0; |
152 | |
14592 | 153 #endif |
154 | |
15519
5b310380e54f
pipe2: silence compiler warning
Eric Blake <eblake@redhat.com>
parents:
15327
diff
changeset
|
155 #if GNULIB_defined_O_NONBLOCK || \ |
5b310380e54f
pipe2: silence compiler warning
Eric Blake <eblake@redhat.com>
parents:
15327
diff
changeset
|
156 !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) |
11870 | 157 fail: |
158 { | |
159 int saved_errno = errno; | |
160 close (fd[0]); | |
161 close (fd[1]); | |
15326
52719068f9c2
pipe, pipe2: don't corrupt fd on error
Eric Blake <eblake@redhat.com>
parents:
14856
diff
changeset
|
162 fd[0] = tmp[0]; |
52719068f9c2
pipe, pipe2: don't corrupt fd on error
Eric Blake <eblake@redhat.com>
parents:
14856
diff
changeset
|
163 fd[1] = tmp[1]; |
11870 | 164 errno = saved_errno; |
165 return -1; | |
166 } | |
15519
5b310380e54f
pipe2: silence compiler warning
Eric Blake <eblake@redhat.com>
parents:
15327
diff
changeset
|
167 #endif |
11892
26347f7d2cac
Move #ifs inside function.
Bruno Haible <bruno@clisp.org>
parents:
11881
diff
changeset
|
168 } |