annotate lib/open.c @ 17323:a56636d89038

secure_getenv: fix include typo * lib/secure_getenv.c: Include config.h. Somehow I forgot!
author Paul Eggert <eggert@cs.ucla.edu>
date Thu, 07 Feb 2013 21:58:09 -0800
parents e542fd46ad6f
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.
17249
e542fd46ad6f maint: update all copyright year number ranges
Eric Blake <eblake@redhat.com>
parents: 17185
diff changeset
2 Copyright (C) 2007-2013 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
bbbbbf4cd1c5 Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents: 9299
diff changeset
15 along with this program. If not, see <http://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
10608
9559d8f05cdb Merge the two replacements for open() into a single one.
Paolo Bonzini <bonzini@gnu.org>
parents: 10533
diff changeset
41 #include <errno.h>
9559d8f05cdb Merge the two replacements for open() into a single one.
Paolo Bonzini <bonzini@gnu.org>
parents: 10533
diff changeset
42 #include <stdarg.h>
9559d8f05cdb Merge the two replacements for open() into a single one.
Paolo Bonzini <bonzini@gnu.org>
parents: 10533
diff changeset
43 #include <string.h>
9559d8f05cdb Merge the two replacements for open() into a single one.
Paolo Bonzini <bonzini@gnu.org>
parents: 10533
diff changeset
44 #include <sys/types.h>
9559d8f05cdb Merge the two replacements for open() into a single one.
Paolo Bonzini <bonzini@gnu.org>
parents: 10533
diff changeset
45 #include <sys/stat.h>
11933
1ffad224c413 fchdir: use more consistent macro convention
Eric Blake <ebb9@byu.net>
parents: 11932
diff changeset
46 #include <unistd.h>
9299
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
47
11922
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
48 #ifndef REPLACE_OPEN_DIRECTORY
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
49 # define REPLACE_OPEN_DIRECTORY 0
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
50 #endif
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
51
9299
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
52 int
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
53 open (const char *filename, int flags, ...)
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
54 {
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
55 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
56 int fd;
9299
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
57
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
58 mode = 0;
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
59 if (flags & O_CREAT)
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
60 {
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
61 va_list arg;
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
62 va_start (arg, flags);
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
63
11586
35f0931dc243 Simplify use of mode_t varargs.
Bruno Haible <bruno@clisp.org>
parents: 10608
diff changeset
64 /* 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
65 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
66 mode = va_arg (arg, PROMOTED_MODE_T);
9299
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
67
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
68 va_end (arg);
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
14532
0b3f0c54fbc8 nonblocking: provide O_NONBLOCK for mingw
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
71 #if GNULIB_defined_O_NONBLOCK
0b3f0c54fbc8 nonblocking: provide O_NONBLOCK for mingw
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
72 /* 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
73 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
74 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
75 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
76 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
77 flags &= ~O_NONBLOCK;
0b3f0c54fbc8 nonblocking: provide O_NONBLOCK for mingw
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
78 #endif
0b3f0c54fbc8 nonblocking: provide O_NONBLOCK for mingw
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
79
10608
9559d8f05cdb Merge the two replacements for open() into a single one.
Paolo Bonzini <bonzini@gnu.org>
parents: 10533
diff changeset
80 #if (defined _WIN32 || 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
81 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
82 filename = "NUL";
10608
9559d8f05cdb Merge the two replacements for open() into a single one.
Paolo Bonzini <bonzini@gnu.org>
parents: 10533
diff changeset
83 #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
84
10608
9559d8f05cdb Merge the two replacements for open() into a single one.
Paolo Bonzini <bonzini@gnu.org>
parents: 10533
diff changeset
85 #if OPEN_TRAILING_SLASH_BUG
10202
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
86 /* 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
87 is specified, then fail.
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
88 Rationale: POSIX <http://www.opengroup.org/susv3/basedefs/xbd_chap04.html>
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
89 says that
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
90 "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
91 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
92 single dot character ( '.' ) were appended to the pathname."
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
93 and
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
94 "The special filename dot shall refer to the directory specified by
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
95 its predecessor."
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
96 If the named file already exists as a directory, then
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
97 - 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
98 of O_CREAT,
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
99 - 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
100 <http://www.opengroup.org/susv3/functions/open.html> says that it
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
101 fails with errno = EISDIR in this case.
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
102 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
103 - 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
104 directories,
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
105 - 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
106 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
107 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
108 {
270b7afb8fb7 Work around open() bug on HP-UX 11 and Solaris 9.
Bruno Haible <bruno@clisp.org>
parents: 9309
diff changeset
109 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
110 if (len > 0 && filename[len - 1] == '/')
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
111 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
112 errno = EISDIR;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
113 return -1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
114 }
10201
270b7afb8fb7 Work around open() bug on HP-UX 11 and Solaris 9.
Bruno Haible <bruno@clisp.org>
parents: 9309
diff changeset
115 }
10608
9559d8f05cdb Merge the two replacements for open() into a single one.
Paolo Bonzini <bonzini@gnu.org>
parents: 10533
diff changeset
116 #endif
10201
270b7afb8fb7 Work around open() bug on HP-UX 11 and Solaris 9.
Bruno Haible <bruno@clisp.org>
parents: 9309
diff changeset
117
10533
d4b37870fdc9 Override open more carefully.
Bruno Haible <bruno@clisp.org>
parents: 10473
diff changeset
118 fd = orig_open (filename, flags, 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
119
11933
1ffad224c413 fchdir: use more consistent macro convention
Eric Blake <ebb9@byu.net>
parents: 11932
diff changeset
120 #if REPLACE_FCHDIR
11922
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
121 /* Implementing fchdir and fdopendir requires the ability to open a
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
122 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
123 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
124 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
125 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
126 dummy. */
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
127 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
128 && ((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
129 || (O_SEARCH != O_RDONLY && (flags & O_ACCMODE) == O_SEARCH)))
11922
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
130 {
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
131 struct stat statbuf;
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
132 if (stat (filename, &statbuf) == 0 && S_ISDIR (statbuf.st_mode))
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
133 {
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
134 /* Maximum recursion depth of 1. */
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
135 fd = open ("/dev/null", flags, mode);
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
136 if (0 <= fd)
11932
4073da4a848c fchdir: simplify error handling, and support dup3
Eric Blake <ebb9@byu.net>
parents: 11922
diff changeset
137 fd = _gl_register_fd (fd, filename);
11922
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
138 }
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
139 else
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
140 errno = EACCES;
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
141 }
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
142 #endif
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
143
10608
9559d8f05cdb Merge the two replacements for open() into a single one.
Paolo Bonzini <bonzini@gnu.org>
parents: 10533
diff changeset
144 #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
145 /* 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
146 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
147 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
148 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
149 "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
150 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
151 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
152 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
153 "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
154 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
155 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
156 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
157 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
158 {
12052
7891d97ab77c open, openat: minor optimization
Eric Blake <ebb9@byu.net>
parents: 11933
diff changeset
159 /* 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
160 size_t len = strlen (filename);
12052
7891d97ab77c open, openat: minor optimization
Eric Blake <ebb9@byu.net>
parents: 11933
diff changeset
161 if (filename[len - 1] == '/')
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
162 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
163 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
164
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
165 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
166 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
167 close (fd);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
168 errno = ENOTDIR;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
169 return -1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
170 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12106
diff changeset
171 }
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 }
10608
9559d8f05cdb Merge the two replacements for open() into a single one.
Paolo Bonzini <bonzini@gnu.org>
parents: 10533
diff changeset
173 #endif
9559d8f05cdb Merge the two replacements for open() into a single one.
Paolo Bonzini <bonzini@gnu.org>
parents: 10533
diff changeset
174
11933
1ffad224c413 fchdir: use more consistent macro convention
Eric Blake <ebb9@byu.net>
parents: 11932
diff changeset
175 #if REPLACE_FCHDIR
11922
9750527ffbab fchdir: port to mingw
Eric Blake <ebb9@byu.net>
parents: 11586
diff changeset
176 if (!REPLACE_OPEN_DIRECTORY && 0 <= fd)
11932
4073da4a848c fchdir: simplify error handling, and support dup3
Eric Blake <ebb9@byu.net>
parents: 11922
diff changeset
177 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
178 #endif
9299
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
179
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
180 return fd;
9299
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
181 }