annotate lib/open.c @ 10202:4d972085fd3a

Add a comment.
author Bruno Haible <bruno@clisp.org>
date Thu, 12 Jun 2008 13:47:37 +0200
parents 270b7afb8fb7
children 008f289e34ef
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.
10201
270b7afb8fb7 Work around open() bug on HP-UX 11 and Solaris 9.
Bruno Haible <bruno@clisp.org>
parents: 9309
diff changeset
2 Copyright (C) 2007-2008 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
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
19 #include <config.h>
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
20
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
21 /* Specification. */
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
22 #include <fcntl.h>
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
23
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
24 /* If the fchdir replacement is used, open() is defined in fchdir.c. */
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
25 #ifndef FCHDIR_REPLACEMENT
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
26
10201
270b7afb8fb7 Work around open() bug on HP-UX 11 and Solaris 9.
Bruno Haible <bruno@clisp.org>
parents: 9309
diff changeset
27 # include <errno.h>
9299
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
28 # include <stdarg.h>
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
29 # include <string.h>
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
30 # include <sys/types.h>
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
31 # include <sys/stat.h>
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
32
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
33 int
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
34 open (const char *filename, int flags, ...)
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
35 # undef open
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
36 {
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
37 mode_t mode;
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
38
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
39 mode = 0;
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
40 if (flags & O_CREAT)
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
41 {
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
42 va_list arg;
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
43 va_start (arg, flags);
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
44
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
45 /* If mode_t is narrower than int, use the promoted type (int),
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
46 not mode_t. Use sizeof to guess whether mode_t is narrower;
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
47 we don't know of any practical counterexamples. */
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
48 mode = (sizeof (mode_t) < sizeof (int)
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
49 ? va_arg (arg, int)
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
50 : va_arg (arg, mode_t));
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
51
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
52 va_end (arg);
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
53 }
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
54
10201
270b7afb8fb7 Work around open() bug on HP-UX 11 and Solaris 9.
Bruno Haible <bruno@clisp.org>
parents: 9309
diff changeset
55 # if OPEN_TRAILING_SLASH_BUG
10202
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
56 /* 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
57 is specified, then fail.
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
58 Rationale: POSIX <http://www.opengroup.org/susv3/basedefs/xbd_chap04.html>
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
59 says that
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
60 "A pathname that contains at least one non-slash character and that
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
61 ends withone or more trailing slashes shall be resolved as if a
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
62 single dot character ( '.' ) were appended to the pathname."
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
63 and
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
64 "The special filename dot shall refer to the directory specified by
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
65 its predecessor."
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
66 If the named file already exists as a directory, then
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
67 - 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
68 of O_CREAT,
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
69 - 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
70 <http://www.opengroup.org/susv3/functions/open.html> says that it
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
71 fails with errno = EISDIR in this case.
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
72 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
73 - 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
74 directories,
4d972085fd3a Add a comment.
Bruno Haible <bruno@clisp.org>
parents: 10201
diff changeset
75 - 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
76 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
77 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
78 {
270b7afb8fb7 Work around open() bug on HP-UX 11 and Solaris 9.
Bruno Haible <bruno@clisp.org>
parents: 9309
diff changeset
79 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
80 if (len > 0 && filename[len - 1] == '/')
270b7afb8fb7 Work around open() bug on HP-UX 11 and Solaris 9.
Bruno Haible <bruno@clisp.org>
parents: 9309
diff changeset
81 {
270b7afb8fb7 Work around open() bug on HP-UX 11 and Solaris 9.
Bruno Haible <bruno@clisp.org>
parents: 9309
diff changeset
82 errno = EISDIR;
270b7afb8fb7 Work around open() bug on HP-UX 11 and Solaris 9.
Bruno Haible <bruno@clisp.org>
parents: 9309
diff changeset
83 return -1;
270b7afb8fb7 Work around open() bug on HP-UX 11 and Solaris 9.
Bruno Haible <bruno@clisp.org>
parents: 9309
diff changeset
84 }
270b7afb8fb7 Work around open() bug on HP-UX 11 and Solaris 9.
Bruno Haible <bruno@clisp.org>
parents: 9309
diff changeset
85 }
270b7afb8fb7 Work around open() bug on HP-UX 11 and Solaris 9.
Bruno Haible <bruno@clisp.org>
parents: 9309
diff changeset
86 # endif
270b7afb8fb7 Work around open() bug on HP-UX 11 and Solaris 9.
Bruno Haible <bruno@clisp.org>
parents: 9309
diff changeset
87
9299
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
88 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
89 if (strcmp (filename, "/dev/null") == 0)
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
90 filename = "NUL";
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
91 # endif
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
92
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
93 return open (filename, flags, mode);
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
94 }
ada4d73c37a6 New module 'open'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
95 #endif