annotate lib/fclose.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 10eb9086bea0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
10623
cce8e54214d5 * lib/fclose.c: Fix typo in comment: s/close/fclose/.
Jim Meyering <meyering@redhat.com>
parents: 10622
diff changeset
1 /* fclose replacement.
40057
b06060465f09 maint: Run 'make update-copyright'
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
2 Copyright (C) 2008-2019 Free Software Foundation, Inc.
10622
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
3
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
4 This program is free software: you can redistribute it and/or modify
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
5 it under the terms of the GNU General Public License as published by
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
6 the Free Software Foundation; either version 3 of the License, or
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
7 (at your option) any later version.
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
8
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
9 This program is distributed in the hope that it will be useful,
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
12 GNU General Public License for more details.
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
13
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
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: 18883
diff changeset
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
10622
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
16
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
17 #include <config.h>
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
18
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
19 /* Specification. */
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
20 #include <stdio.h>
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
21
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
22 #include <errno.h>
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
23 #include <unistd.h>
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
24
14667
1f6b1f7275d0 fclose: don't fail on non-seekable input stream
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
25 #include "freading.h"
18883
19886582ca8d Implement a way to opt out from MSVC support.
Bruno Haible <bruno@clisp.org>
parents: 18626
diff changeset
26 #if HAVE_MSVC_INVALID_PARAMETER_HANDLER
19886582ca8d Implement a way to opt out from MSVC support.
Bruno Haible <bruno@clisp.org>
parents: 18626
diff changeset
27 # include "msvc-inval.h"
19886582ca8d Implement a way to opt out from MSVC support.
Bruno Haible <bruno@clisp.org>
parents: 18626
diff changeset
28 #endif
15779
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
29
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
30 #undef fclose
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
31
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
32 #if HAVE_MSVC_INVALID_PARAMETER_HANDLER
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
33 static int
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
34 fclose_nothrow (FILE *fp)
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
35 {
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
36 int result;
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
37
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
38 TRY_MSVC_INVAL
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
39 {
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
40 result = fclose (fp);
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
41 }
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
42 CATCH_MSVC_INVAL
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
43 {
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
44 result = EOF;
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
45 errno = EBADF;
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
46 }
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
47 DONE_MSVC_INVAL;
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
48
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
49 return result;
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
50 }
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
51 #else
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
52 # define fclose_nothrow fclose
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
53 #endif
14667
1f6b1f7275d0 fclose: don't fail on non-seekable input stream
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
54
14678
68c96ae4be1a fflush: also replace fclose when fixing fflush
Eric Blake <eblake@redhat.com>
parents: 14676
diff changeset
55 /* Override fclose() to call the overridden fflush() or close(). */
10622
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
56
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
57 int
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
58 rpl_fclose (FILE *fp)
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
59 {
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
60 int saved_errno = 0;
14678
68c96ae4be1a fflush: also replace fclose when fixing fflush
Eric Blake <eblake@redhat.com>
parents: 14676
diff changeset
61 int fd;
14723
890d9b0fe421 fclose: avoid double close race when possible
Eric Blake <eblake@redhat.com>
parents: 14678
diff changeset
62 int result = 0;
14678
68c96ae4be1a fflush: also replace fclose when fixing fflush
Eric Blake <eblake@redhat.com>
parents: 14676
diff changeset
63
68c96ae4be1a fflush: also replace fclose when fixing fflush
Eric Blake <eblake@redhat.com>
parents: 14676
diff changeset
64 /* Don't change behavior on memstreams. */
68c96ae4be1a fflush: also replace fclose when fixing fflush
Eric Blake <eblake@redhat.com>
parents: 14676
diff changeset
65 fd = fileno (fp);
68c96ae4be1a fflush: also replace fclose when fixing fflush
Eric Blake <eblake@redhat.com>
parents: 14676
diff changeset
66 if (fd < 0)
15779
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
67 return fclose_nothrow (fp);
10622
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
68
14667
1f6b1f7275d0 fclose: don't fail on non-seekable input stream
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
69 /* We only need to flush the file if it is not reading or if it is
14676
ead32d10a3f0 fclose: reduce dependencies
Eric Blake <eblake@redhat.com>
parents: 14667
diff changeset
70 seekable. This only guarantees the file position of input files
ead32d10a3f0 fclose: reduce dependencies
Eric Blake <eblake@redhat.com>
parents: 14667
diff changeset
71 if the fflush module is also in use. */
ead32d10a3f0 fclose: reduce dependencies
Eric Blake <eblake@redhat.com>
parents: 14667
diff changeset
72 if ((!freading (fp) || lseek (fileno (fp), 0, SEEK_CUR) != -1)
ead32d10a3f0 fclose: reduce dependencies
Eric Blake <eblake@redhat.com>
parents: 14667
diff changeset
73 && fflush (fp))
10622
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
74 saved_errno = errno;
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
75
14726
3e7ea0014c67 fclose: Fix possible link error.
Bruno Haible <bruno@clisp.org>
parents: 14723
diff changeset
76 /* fclose() calls close(), but we need to also invoke all hooks that our
3e7ea0014c67 fclose: Fix possible link error.
Bruno Haible <bruno@clisp.org>
parents: 14723
diff changeset
77 overridden close() function invokes. See lib/close.c. */
14723
890d9b0fe421 fclose: avoid double close race when possible
Eric Blake <eblake@redhat.com>
parents: 14678
diff changeset
78 #if WINDOWS_SOCKETS
14726
3e7ea0014c67 fclose: Fix possible link error.
Bruno Haible <bruno@clisp.org>
parents: 14723
diff changeset
79 /* Call the overridden close(), then the original fclose().
3e7ea0014c67 fclose: Fix possible link error.
Bruno Haible <bruno@clisp.org>
parents: 14723
diff changeset
80 Note about multithread-safety: There is a race condition where some
3e7ea0014c67 fclose: Fix possible link error.
Bruno Haible <bruno@clisp.org>
parents: 14723
diff changeset
81 other thread could open fd between our close and fclose. */
14678
68c96ae4be1a fflush: also replace fclose when fixing fflush
Eric Blake <eblake@redhat.com>
parents: 14676
diff changeset
82 if (close (fd) < 0 && saved_errno == 0)
10622
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
83 saved_errno = errno;
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
84
15779
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
85 fclose_nothrow (fp); /* will fail with errno = EBADF,
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
86 if we did not lose a race */
10622
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
87
14723
890d9b0fe421 fclose: avoid double close race when possible
Eric Blake <eblake@redhat.com>
parents: 14678
diff changeset
88 #else /* !WINDOWS_SOCKETS */
14726
3e7ea0014c67 fclose: Fix possible link error.
Bruno Haible <bruno@clisp.org>
parents: 14723
diff changeset
89 /* Call fclose() and invoke all hooks of the overridden close(). */
14723
890d9b0fe421 fclose: avoid double close race when possible
Eric Blake <eblake@redhat.com>
parents: 14678
diff changeset
90
890d9b0fe421 fclose: avoid double close race when possible
Eric Blake <eblake@redhat.com>
parents: 14678
diff changeset
91 # if REPLACE_FCHDIR
14726
3e7ea0014c67 fclose: Fix possible link error.
Bruno Haible <bruno@clisp.org>
parents: 14723
diff changeset
92 /* Note about multithread-safety: There is a race condition here as well.
3e7ea0014c67 fclose: Fix possible link error.
Bruno Haible <bruno@clisp.org>
parents: 14723
diff changeset
93 Some other thread could open fd between our calls to fclose and
3e7ea0014c67 fclose: Fix possible link error.
Bruno Haible <bruno@clisp.org>
parents: 14723
diff changeset
94 _gl_unregister_fd. */
15779
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
95 result = fclose_nothrow (fp);
14731
687d9ec4a38c fclose: Fix mistake earlier today.
Bruno Haible <bruno@clisp.org>
parents: 14730
diff changeset
96 if (result == 0)
14726
3e7ea0014c67 fclose: Fix possible link error.
Bruno Haible <bruno@clisp.org>
parents: 14723
diff changeset
97 _gl_unregister_fd (fd);
3e7ea0014c67 fclose: Fix possible link error.
Bruno Haible <bruno@clisp.org>
parents: 14723
diff changeset
98 # else
3e7ea0014c67 fclose: Fix possible link error.
Bruno Haible <bruno@clisp.org>
parents: 14723
diff changeset
99 /* No race condition here. */
15779
fb3ece2324db fclose: Support for MSVC 9.
Bruno Haible <bruno@clisp.org>
parents: 14731
diff changeset
100 result = fclose_nothrow (fp);
14723
890d9b0fe421 fclose: avoid double close race when possible
Eric Blake <eblake@redhat.com>
parents: 14678
diff changeset
101 # endif
14726
3e7ea0014c67 fclose: Fix possible link error.
Bruno Haible <bruno@clisp.org>
parents: 14723
diff changeset
102
14723
890d9b0fe421 fclose: avoid double close race when possible
Eric Blake <eblake@redhat.com>
parents: 14678
diff changeset
103 #endif /* !WINDOWS_SOCKETS */
890d9b0fe421 fclose: avoid double close race when possible
Eric Blake <eblake@redhat.com>
parents: 14678
diff changeset
104
14730
f0a9a2cd267c fclose: preserve fflush errors
Eric Blake <eblake@redhat.com>
parents: 14726
diff changeset
105 if (saved_errno != 0)
f0a9a2cd267c fclose: preserve fflush errors
Eric Blake <eblake@redhat.com>
parents: 14726
diff changeset
106 {
f0a9a2cd267c fclose: preserve fflush errors
Eric Blake <eblake@redhat.com>
parents: 14726
diff changeset
107 errno = saved_errno;
f0a9a2cd267c fclose: preserve fflush errors
Eric Blake <eblake@redhat.com>
parents: 14726
diff changeset
108 result = EOF;
f0a9a2cd267c fclose: preserve fflush errors
Eric Blake <eblake@redhat.com>
parents: 14726
diff changeset
109 }
f0a9a2cd267c fclose: preserve fflush errors
Eric Blake <eblake@redhat.com>
parents: 14726
diff changeset
110
14723
890d9b0fe421 fclose: avoid double close race when possible
Eric Blake <eblake@redhat.com>
parents: 14678
diff changeset
111 return result;
10622
ac6f431cc95d New module 'fclose'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
112 }