annotate lib/open.c @ 40057:b06060465f09

maint: Run 'make update-copyright'
author Paul Eggert <eggert@cs.ucla.edu>
date Tue, 01 Jan 2019 00:25:11 +0100
parents beb2ad957aca
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
9299
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1 /* Open a descriptor to a file.
40057
b06060465f09 maint: Run 'make update-copyright'
Paul Eggert <eggert@cs.ucla.edu>
parents: 19595
diff changeset
2 Copyright (C) 2007-2019 Free Software Foundation, Inc.
9299
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
3
9309
bbbbbf4cd1c5 Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents: 9299
diff changeset
4 This program is free software: you can redistribute it and/or modify
9299
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
5 it under the terms of the GNU General Public License as published by
9309
bbbbbf4cd1c5 Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents: 9299
diff changeset
6 the Free Software Foundation; either version 3 of the License, or
bbbbbf4cd1c5 Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents: 9299
diff changeset
7 (at your option) any later version.
9299
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
8
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
9 This program is distributed in the hope that it will be useful,
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
12 GNU General Public License for more details.
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
13
9309
bbbbbf4cd1c5 Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents: 9299
diff changeset
14 You should have received a copy of the GNU General Public License
19190
9759915b2aca all: prefer https: URLs
Paul Eggert <eggert@cs.ucla.edu>
parents: 19052
diff changeset
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
9299
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
16
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
17 /* Written by Bruno Haible <bruno@clisp.org>, 2007. */
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
18
15538
9fd857e43955 Avoid endless recursions if config.h includes some header files.
Bruno Haible <bruno@clisp.org>
parents: 14532
diff changeset
19 /* If the user's config.h happens to include <fcntl.h>, let it include only
9fd857e43955 Avoid endless recursions if config.h includes some header files.
Bruno Haible <bruno@clisp.org>
parents: 14532
diff changeset
20 the system's <fcntl.h> here, so that orig_open doesn't recurse to
9fd857e43955 Avoid endless recursions if config.h includes some header files.
Bruno Haible <bruno@clisp.org>
parents: 14532
diff changeset
21 rpl_open. */
9fd857e43955 Avoid endless recursions if config.h includes some header files.
Bruno Haible <bruno@clisp.org>
parents: 14532
diff changeset
22 #define __need_system_fcntl_h
9299
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
23 #include <config.h>
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
24
10533
d4b37870fdc9 Override open more carefully.
Bruno Haible <bruno@clisp.org>
parents: 10473
diff changeset
25 /* Get the original definition of open. It might be defined as a macro. */
d4b37870fdc9 Override open more carefully.
Bruno Haible <bruno@clisp.org>
parents: 10473
diff changeset
26 #include <fcntl.h>
15538
9fd857e43955 Avoid endless recursions if config.h includes some header files.
Bruno Haible <bruno@clisp.org>
parents: 14532
diff changeset
27 #include <sys/types.h>
10533
d4b37870fdc9 Override open more carefully.
Bruno Haible <bruno@clisp.org>
parents: 10473
diff changeset
28 #undef __need_system_fcntl_h
d4b37870fdc9 Override open more carefully.
Bruno Haible <bruno@clisp.org>
parents: 10473
diff changeset
29
17185
dd46d4e6beea dup, execute, fatal-signal, etc.: no 'static inline'
Paul Eggert <eggert@cs.ucla.edu>
parents: 16201
diff changeset
30 static int
10533
d4b37870fdc9 Override open more carefully.
Bruno Haible <bruno@clisp.org>
parents: 10473
diff changeset
31 orig_open (const char *filename, int flags, mode_t mode)
d4b37870fdc9 Override open more carefully.
Bruno Haible <bruno@clisp.org>
parents: 10473
diff changeset
32 {
d4b37870fdc9 Override open more carefully.
Bruno Haible <bruno@clisp.org>
parents: 10473
diff changeset
33 return open (filename, flags, mode);
d4b37870fdc9 Override open more carefully.
Bruno Haible <bruno@clisp.org>
parents: 10473
diff changeset
34 }
d4b37870fdc9 Override open more carefully.
Bruno Haible <bruno@clisp.org>
parents: 10473
diff changeset
35
9299
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
36 /* Specification. */
15583
716e67b8d5a9 openat: Work around compilation error with OSF/1 5.1 DTK cc.
Bruno Haible <bruno@clisp.org>
parents: 15538
diff changeset
37 /* Write "fcntl.h" here, not <fcntl.h>, otherwise OSF/1 5.1 DTK cc eliminates
716e67b8d5a9 openat: Work around compilation error with OSF/1 5.1 DTK cc.
Bruno Haible <bruno@clisp.org>
parents: 15538
diff changeset
38 this include because of the preliminary #include <fcntl.h> above. */
716e67b8d5a9 openat: Work around compilation error with OSF/1 5.1 DTK cc.
Bruno Haible <bruno@clisp.org>
parents: 15538
diff changeset
39 #include "fcntl.h"
9299
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
40
19052
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
41 #include "cloexec.h"
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
42
10608
9559d8f05cdb Merge the two replacements for open() into a single one.
Paolo Bonzini <bonzini@gnu.org>
parents: 10533
diff changeset
43 #include <errno.h>
9559d8f05cdb Merge the two replacements for open() into a single one.
Paolo Bonzini <bonzini@gnu.org>
parents: 10533
diff changeset
44 #include <stdarg.h>
9559d8f05cdb Merge the two replacements for open() into a single one.
Paolo Bonzini <bonzini@gnu.org>
parents: 10533
diff changeset
45 #include <string.h>
9559d8f05cdb Merge the two replacements for open() into a single one.
Paolo Bonzini <bonzini@gnu.org>
parents: 10533
diff changeset
46 #include <sys/types.h>
9559d8f05cdb Merge the two replacements for open() into a single one.
Paolo Bonzini <bonzini@gnu.org>
parents: 10533
diff changeset
47 #include <sys/stat.h>
11933
1ffad224c413 fchdir: use more consistent macro convention
Eric Blake <ebb9@byu.net>
parents: 11932
diff changeset
48 #include <unistd.h>
9299
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
49
11922
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
50 #ifndef REPLACE_OPEN_DIRECTORY
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
51 # define REPLACE_OPEN_DIRECTORY 0
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
52 #endif
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
53
9299
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
54 int
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
55 open (const char *filename, int flags, ...)
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
56 {
19052
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
57 /* 0 = unknown, 1 = yes, -1 = no. */
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
58 #if GNULIB_defined_O_CLOEXEC
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
59 int have_cloexec = -1;
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
60 #else
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
61 static int have_cloexec;
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
62 #endif
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
63
9299
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
64 mode_t mode;
10472
a4dc39a18d54 Ensure that a filename ending in a slash cannot be used to access a non-directory.
Bruno Haible <bruno@clisp.org>
parents: 10203
diff changeset
65 int fd;
9299
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
66
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
67 mode = 0;
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
68 if (flags & O_CREAT)
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
69 {
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
70 va_list arg;
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
71 va_start (arg, flags);
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
72
11586
35f0931dc243 Simplify use of mode_t varargs.
Bruno Haible <bruno@clisp.org>
parents: 10608
diff changeset
73 /* We have to use PROMOTED_MODE_T instead of mode_t, otherwise GCC 4
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
74 creates crashing code when 'mode_t' is smaller than 'int'. */
11586
35f0931dc243 Simplify use of mode_t varargs.
Bruno Haible <bruno@clisp.org>
parents: 10608
diff changeset
75 mode = va_arg (arg, PROMOTED_MODE_T);
9299
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
76
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
77 va_end (arg);
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
78 }
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
79
14532
0b3f0c54fbc8 nonblocking: provide O_NONBLOCK for mingw
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
80 #if GNULIB_defined_O_NONBLOCK
0b3f0c54fbc8 nonblocking: provide O_NONBLOCK for mingw
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
81 /* The only known platform that lacks O_NONBLOCK is mingw, but it
0b3f0c54fbc8 nonblocking: provide O_NONBLOCK for mingw
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
82 also lacks named pipes and Unix sockets, which are the only two
0b3f0c54fbc8 nonblocking: provide O_NONBLOCK for mingw
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
83 file types that require non-blocking handling in open().
0b3f0c54fbc8 nonblocking: provide O_NONBLOCK for mingw
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
84 Therefore, it is safe to ignore O_NONBLOCK here. It is handy
0b3f0c54fbc8 nonblocking: provide O_NONBLOCK for mingw
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
85 that mingw also lacks openat(), so that is also covered here. */
0b3f0c54fbc8 nonblocking: provide O_NONBLOCK for mingw
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
86 flags &= ~O_NONBLOCK;
0b3f0c54fbc8 nonblocking: provide O_NONBLOCK for mingw
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
87 #endif
0b3f0c54fbc8 nonblocking: provide O_NONBLOCK for mingw
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
88
19595
beb2ad957aca Simplify code. Drop support for Borland C++ on Windows.
Bruno Haible <bruno@clisp.org>
parents: 19484
diff changeset
89 #if defined _WIN32 && ! defined __CYGWIN__
10472
a4dc39a18d54 Ensure that a filename ending in a slash cannot be used to access a non-directory.
Bruno Haible <bruno@clisp.org>
parents: 10203
diff changeset
90 if (strcmp (filename, "/dev/null") == 0)
a4dc39a18d54 Ensure that a filename ending in a slash cannot be used to access a non-directory.
Bruno Haible <bruno@clisp.org>
parents: 10203
diff changeset
91 filename = "NUL";
10608
9559d8f05cdb Merge the two replacements for open() into a single one.
Paolo Bonzini <bonzini@gnu.org>
parents: 10533
diff changeset
92 #endif
10472
a4dc39a18d54 Ensure that a filename ending in a slash cannot be used to access a non-directory.
Bruno Haible <bruno@clisp.org>
parents: 10203
diff changeset
93
10608
9559d8f05cdb Merge the two replacements for open() into a single one.
Paolo Bonzini <bonzini@gnu.org>
parents: 10533
diff changeset
94 #if OPEN_TRAILING_SLASH_BUG
10202
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
95 /* If the filename ends in a slash and one of O_CREAT, O_WRONLY, O_RDWR
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
96 is specified, then fail.
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
97 Rationale: POSIX <http://www.opengroup.org/susv3/basedefs/xbd_chap04.html>
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
98 says that
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
99 "A pathname that contains at least one non-slash character and that
10203
008f289e34ef Typo in comment.
Bruno Haible <bruno@clisp.org>
parents: 10202
diff changeset
100 ends with one or more trailing slashes shall be resolved as if a
10202
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
101 single dot character ( '.' ) were appended to the pathname."
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
102 and
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
103 "The special filename dot shall refer to the directory specified by
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
104 its predecessor."
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
105 If the named file already exists as a directory, then
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
106 - if O_CREAT is specified, open() must fail because of the semantics
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
107 of O_CREAT,
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
108 - if O_WRONLY or O_RDWR is specified, open() must fail because POSIX
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
109 <http://www.opengroup.org/susv3/functions/open.html> says that it
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
110 fails with errno = EISDIR in this case.
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
111 If the named file does not exist or does not name a directory, then
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
112 - if O_CREAT is specified, open() must fail since open() cannot create
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
113 directories,
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
114 - if O_WRONLY or O_RDWR is specified, open() must fail because the
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
115 file does not contain a '.' directory. */
10201
270b7afb8fb7 Work around open() bug on HP-UX 11 and Solaris 9.
Bruno Haible <bruno@clisp.org>
parents: 9309
diff changeset
116 if (flags & (O_CREAT | O_WRONLY | O_RDWR))
270b7afb8fb7 Work around open() bug on HP-UX 11 and Solaris 9.
Bruno Haible <bruno@clisp.org>
parents: 9309
diff changeset
117 {
270b7afb8fb7 Work around open() bug on HP-UX 11 and Solaris 9.
Bruno Haible <bruno@clisp.org>
parents: 9309
diff changeset
118 size_t len = strlen (filename);
270b7afb8fb7 Work around open() bug on HP-UX 11 and Solaris 9.
Bruno Haible <bruno@clisp.org>
parents: 9309
diff changeset
119 if (len > 0 && filename[len - 1] == '/')
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
120 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
121 errno = EISDIR;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
122 return -1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
123 }
10201
270b7afb8fb7 Work around open() bug on HP-UX 11 and Solaris 9.
Bruno Haible <bruno@clisp.org>
parents: 9309
diff changeset
124 }
10608
9559d8f05cdb Merge the two replacements for open() into a single one.
Paolo Bonzini <bonzini@gnu.org>
parents: 10533
diff changeset
125 #endif
10201
270b7afb8fb7 Work around open() bug on HP-UX 11 and Solaris 9.
Bruno Haible <bruno@clisp.org>
parents: 9309
diff changeset
126
19052
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
127 fd = orig_open (filename,
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
128 flags & ~(have_cloexec <= 0 ? O_CLOEXEC : 0), mode);
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
129
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
130 if (flags & O_CLOEXEC)
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
131 {
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
132 if (! have_cloexec)
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
133 {
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
134 if (0 <= fd)
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
135 have_cloexec = 1;
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
136 else if (errno == EINVAL)
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
137 {
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
138 fd = orig_open (filename, flags & ~O_CLOEXEC, mode);
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
139 have_cloexec = -1;
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
140 }
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
141 }
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
142 if (have_cloexec < 0 && 0 <= fd)
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
143 set_cloexec_flag (fd, true);
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
144 }
637f3a63efbd open: support O_CLOEXEC
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
145
10472
a4dc39a18d54 Ensure that a filename ending in a slash cannot be used to access a non-directory.
Bruno Haible <bruno@clisp.org>
parents: 10203
diff changeset
146
11933
1ffad224c413 fchdir: use more consistent macro convention
Eric Blake <ebb9@byu.net>
parents: 11932
diff changeset
147 #if REPLACE_FCHDIR
11922
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
148 /* Implementing fchdir and fdopendir requires the ability to open a
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
149 directory file descriptor. If open doesn't support that (as on
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
150 mingw), we use a dummy file that behaves the same as directories
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
151 on Linux (ie. always reports EOF on attempts to read()), and
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
152 override fstat() in fchdir.c to hide the fact that we have a
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
153 dummy. */
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
154 if (REPLACE_OPEN_DIRECTORY && fd < 0 && errno == EACCES
13664
241057e2e60f fcntl-h: define O_CLOEXEC and O_EXEC if not defined; use new defines
Paul Eggert <eggert@cs.ucla.edu>
parents: 12559
diff changeset
155 && ((flags & O_ACCMODE) == O_RDONLY
241057e2e60f fcntl-h: define O_CLOEXEC and O_EXEC if not defined; use new defines
Paul Eggert <eggert@cs.ucla.edu>
parents: 12559
diff changeset
156 || (O_SEARCH != O_RDONLY && (flags & O_ACCMODE) == O_SEARCH)))
11922
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
157 {
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
158 struct stat statbuf;
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
159 if (stat (filename, &statbuf) == 0 && S_ISDIR (statbuf.st_mode))
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
160 {
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
161 /* Maximum recursion depth of 1. */
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
162 fd = open ("/dev/null", flags, mode);
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
163 if (0 <= fd)
11932
4073da4a848c fchdir: simplify error handling, and support dup3
Eric Blake <ebb9@byu.net>
parents: 11922
diff changeset
164 fd = _gl_register_fd (fd, filename);
11922
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
165 }
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
166 else
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
167 errno = EACCES;
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
168 }
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
169 #endif
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
170
10608
9559d8f05cdb Merge the two replacements for open() into a single one.
Paolo Bonzini <bonzini@gnu.org>
parents: 10533
diff changeset
171 #if OPEN_TRAILING_SLASH_BUG
10472
a4dc39a18d54 Ensure that a filename ending in a slash cannot be used to access a non-directory.
Bruno Haible <bruno@clisp.org>
parents: 10203
diff changeset
172 /* If the filename ends in a slash and fd does not refer to a directory,
a4dc39a18d54 Ensure that a filename ending in a slash cannot be used to access a non-directory.
Bruno Haible <bruno@clisp.org>
parents: 10203
diff changeset
173 then fail.
a4dc39a18d54 Ensure that a filename ending in a slash cannot be used to access a non-directory.
Bruno Haible <bruno@clisp.org>
parents: 10203
diff changeset
174 Rationale: POSIX <http://www.opengroup.org/susv3/basedefs/xbd_chap04.html>
a4dc39a18d54 Ensure that a filename ending in a slash cannot be used to access a non-directory.
Bruno Haible <bruno@clisp.org>
parents: 10203
diff changeset
175 says that
a4dc39a18d54 Ensure that a filename ending in a slash cannot be used to access a non-directory.
Bruno Haible <bruno@clisp.org>
parents: 10203
diff changeset
176 "A pathname that contains at least one non-slash character and that
a4dc39a18d54 Ensure that a filename ending in a slash cannot be used to access a non-directory.
Bruno Haible <bruno@clisp.org>
parents: 10203
diff changeset
177 ends with one or more trailing slashes shall be resolved as if a
a4dc39a18d54 Ensure that a filename ending in a slash cannot be used to access a non-directory.
Bruno Haible <bruno@clisp.org>
parents: 10203
diff changeset
178 single dot character ( '.' ) were appended to the pathname."
a4dc39a18d54 Ensure that a filename ending in a slash cannot be used to access a non-directory.
Bruno Haible <bruno@clisp.org>
parents: 10203
diff changeset
179 and
a4dc39a18d54 Ensure that a filename ending in a slash cannot be used to access a non-directory.
Bruno Haible <bruno@clisp.org>
parents: 10203
diff changeset
180 "The special filename dot shall refer to the directory specified by
a4dc39a18d54 Ensure that a filename ending in a slash cannot be used to access a non-directory.
Bruno Haible <bruno@clisp.org>
parents: 10203
diff changeset
181 its predecessor."
a4dc39a18d54 Ensure that a filename ending in a slash cannot be used to access a non-directory.
Bruno Haible <bruno@clisp.org>
parents: 10203
diff changeset
182 If the named file without the slash is not a directory, open() must fail
a4dc39a18d54 Ensure that a filename ending in a slash cannot be used to access a non-directory.
Bruno Haible <bruno@clisp.org>
parents: 10203
diff changeset
183 with ENOTDIR. */
a4dc39a18d54 Ensure that a filename ending in a slash cannot be used to access a non-directory.
Bruno Haible <bruno@clisp.org>
parents: 10203
diff changeset
184 if (fd >= 0)
a4dc39a18d54 Ensure that a filename ending in a slash cannot be used to access a non-directory.
Bruno Haible <bruno@clisp.org>
parents: 10203
diff changeset
185 {
12052
7891d97ab77c open, openat: minor optimization
Eric Blake <ebb9@byu.net>
parents: 11933
diff changeset
186 /* We know len is positive, since open did not fail with ENOENT. */
10472
a4dc39a18d54 Ensure that a filename ending in a slash cannot be used to access a non-directory.
Bruno Haible <bruno@clisp.org>
parents: 10203
diff changeset
187 size_t len = strlen (filename);
12052
7891d97ab77c open, openat: minor optimization
Eric Blake <ebb9@byu.net>
parents: 11933
diff changeset
188 if (filename[len - 1] == '/')
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
189 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
190 struct stat statbuf;
10472
a4dc39a18d54 Ensure that a filename ending in a slash cannot be used to access a non-directory.
Bruno Haible <bruno@clisp.org>
parents: 10203
diff changeset
191
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
192 if (fstat (fd, &statbuf) >= 0 && !S_ISDIR (statbuf.st_mode))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
193 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
194 close (fd);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
195 errno = ENOTDIR;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
196 return -1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
197 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
198 }
10472
a4dc39a18d54 Ensure that a filename ending in a slash cannot be used to access a non-directory.
Bruno Haible <bruno@clisp.org>
parents: 10203
diff changeset
199 }
10608
9559d8f05cdb Merge the two replacements for open() into a single one.
Paolo Bonzini <bonzini@gnu.org>
parents: 10533
diff changeset
200 #endif
9559d8f05cdb Merge the two replacements for open() into a single one.
Paolo Bonzini <bonzini@gnu.org>
parents: 10533
diff changeset
201
11933
1ffad224c413 fchdir: use more consistent macro convention
Eric Blake <ebb9@byu.net>
parents: 11932
diff changeset
202 #if REPLACE_FCHDIR
11922
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
203 if (!REPLACE_OPEN_DIRECTORY && 0 <= fd)
11932
4073da4a848c fchdir: simplify error handling, and support dup3
Eric Blake <ebb9@byu.net>
parents: 11922
diff changeset
204 fd = _gl_register_fd (fd, filename);
10608
9559d8f05cdb Merge the two replacements for open() into a single one.
Paolo Bonzini <bonzini@gnu.org>
parents: 10533
diff changeset
205 #endif
9299
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
206
10472
a4dc39a18d54 Ensure that a filename ending in a slash cannot be used to access a non-directory.
Bruno Haible <bruno@clisp.org>
parents: 10203
diff changeset
207 return fd;
9299
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
208 }