xref: /third_party/musl/src/stdio/fclose.c (revision 570af302)
1#include "stdio_impl.h"
2#include <stdlib.h>
3#ifndef __LITEOS__
4#include <errno.h>
5#endif
6
7static void dummy(FILE *f) { }
8weak_alias(dummy, __unlist_locked_file);
9
10int fclose(FILE *f)
11{
12	int r;
13
14	FLOCK(f);
15#ifndef __LITEOS__
16	if (!f || f->fd < 0) {
17		errno = EBADF;
18		FUNLOCK(f);
19		return -EBADF;
20	}
21#endif
22
23	r = fflush(f);
24	r |= f->close(f);
25	FUNLOCK(f);
26
27	/* Past this point, f is closed and any further explict access
28	 * to it is undefined. However, it still exists as an entry in
29	 * the open file list and possibly in the thread's locked files
30	 * list, if it was closed while explicitly locked. Functions
31	 * which process these lists must tolerate dead FILE objects
32	 * (which necessarily have inactive buffer pointers) without
33	 * producing any side effects. */
34
35	if (f->flags & F_PERM) return r;
36
37	__unlist_locked_file(f);
38
39	free(f->getln_buf);
40	/* release base instead of buf which may be modified by setvbuf
41	 * or iniitalize by local variable */
42	free(f->base);
43
44#ifndef __LITEOS__
45	/* set file to invalid descriptor */
46	f->fd = -EBADF;
47#endif
48
49	__ofl_free(f);
50
51	return r;
52}
53