Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/lib/libc/stdio/fclose.c
39476 views
1
/*-
2
* SPDX-License-Identifier: BSD-3-Clause
3
*
4
* Copyright (c) 1990, 1993 The Regents of the University of California.
5
* Copyright (c) 2013 Mariusz Zaborski <[email protected]>
6
* All rights reserved.
7
*
8
* This code is derived from software contributed to Berkeley by
9
* Chris Torek.
10
*
11
* Redistribution and use in source and binary forms, with or without
12
* modification, are permitted provided that the following conditions
13
* are met:
14
* 1. Redistributions of source code must retain the above copyright
15
* notice, this list of conditions and the following disclaimer.
16
* 2. Redistributions in binary form must reproduce the above copyright
17
* notice, this list of conditions and the following disclaimer in the
18
* documentation and/or other materials provided with the distribution.
19
* 3. Neither the name of the University nor the names of its contributors
20
* may be used to endorse or promote products derived from this software
21
* without specific prior written permission.
22
*
23
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33
* SUCH DAMAGE.
34
*/
35
36
#include "namespace.h"
37
#include <errno.h>
38
#include <stdbool.h>
39
#include <stdio.h>
40
#include <stdlib.h>
41
#include "un-namespace.h"
42
#include <spinlock.h>
43
#include "libc_private.h"
44
#include "local.h"
45
46
static int
47
cleanfile(FILE *fp, bool c)
48
{
49
int r;
50
51
r = fp->_flags & __SWR ? __sflush(fp) : 0;
52
if (c) {
53
if (fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0)
54
r = EOF;
55
}
56
57
if (fp->_flags & __SMBF)
58
free((char *)fp->_bf._base);
59
if (HASUB(fp))
60
FREEUB(fp);
61
if (HASLB(fp))
62
FREELB(fp);
63
fp->_file = -1;
64
fp->_r = fp->_w = 0; /* Mess up if reaccessed. */
65
66
/*
67
* Lock the spinlock used to protect __sglue list walk in
68
* __sfp(). The __sfp() uses fp->_flags == 0 test as an
69
* indication of the unused FILE.
70
*
71
* Taking the lock prevents possible compiler or processor
72
* reordering of the writes performed before the final _flags
73
* cleanup, making sure that we are done with the FILE before
74
* it is considered available.
75
*/
76
STDIO_THREAD_LOCK();
77
fp->_flags = 0; /* Release this FILE for reuse. */
78
STDIO_THREAD_UNLOCK();
79
80
return (r);
81
}
82
83
int
84
fdclose(FILE *fp, int *fdp)
85
{
86
int r, err;
87
88
if (fdp != NULL)
89
*fdp = -1;
90
91
if (fp->_flags == 0) { /* not open! */
92
errno = EBADF;
93
return (EOF);
94
}
95
96
FLOCKFILE_CANCELSAFE(fp);
97
r = 0;
98
if (fp->_close != __sclose) {
99
r = EOF;
100
errno = EOPNOTSUPP;
101
} else if (fp->_file < 0) {
102
r = EOF;
103
errno = EBADF;
104
}
105
if (r == EOF) {
106
err = errno;
107
(void)cleanfile(fp, true);
108
errno = err;
109
} else {
110
if (fdp != NULL)
111
*fdp = fp->_file;
112
r = cleanfile(fp, false);
113
}
114
FUNLOCKFILE_CANCELSAFE();
115
116
return (r);
117
}
118
119
int
120
fclose(FILE *fp)
121
{
122
int r;
123
124
if (fp->_flags == 0) { /* not open! */
125
errno = EBADF;
126
return (EOF);
127
}
128
129
FLOCKFILE_CANCELSAFE(fp);
130
r = cleanfile(fp, true);
131
FUNLOCKFILE_CANCELSAFE();
132
133
return (r);
134
}
135
136