master
 1#ifdef __wasilibc_unmodified_upstream // WASI has no syscall, dup
 2#include "stdio_impl.h"
 3#else
 4#include <wasi/libc.h>
 5#endif
 6#include <fcntl.h>
 7#include <unistd.h>
 8#ifdef __wasilibc_unmodified_upstream // WASI has no syscall, dup
 9#else
10// Move this below fcntl.h and unistd.h so that the __syscall macro doesn't
11// cause trouble.
12#include "stdio_impl.h"
13#endif
14
15/* The basic idea of this implementation is to open a new FILE,
16 * hack the necessary parts of the new FILE into the old one, then
17 * close the new FILE. */
18
19/* Locking IS necessary because another thread may provably hold the
20 * lock, via flockfile or otherwise, when freopen is called, and in that
21 * case, freopen cannot act until the lock is released. */
22
23FILE *freopen(const char *restrict filename, const char *restrict mode, FILE *restrict f)
24{
25	int fl = __fmodeflags(mode);
26	FILE *f2;
27
28	FLOCK(f);
29
30	fflush(f);
31
32	if (!filename) {
33		if (fl&O_CLOEXEC)
34#ifdef __wasilibc_unmodified_upstream // WASI has no syscall
35			__syscall(SYS_fcntl, f->fd, F_SETFD, FD_CLOEXEC);
36#else
37			fcntl(f->fd, F_SETFD, FD_CLOEXEC);
38#endif
39		fl &= ~(O_CREAT|O_EXCL|O_CLOEXEC);
40#ifdef __wasilibc_unmodified_upstream // WASI has no syscall
41		if (syscall(SYS_fcntl, f->fd, F_SETFL, fl) < 0)
42#else
43		if (fcntl(f->fd, F_SETFL, fl) < 0)
44#endif
45			goto fail;
46	} else {
47		f2 = fopen(filename, mode);
48		if (!f2) goto fail;
49		if (f2->fd == f->fd) f2->fd = -1; /* avoid closing in fclose */
50#ifdef __wasilibc_unmodified_upstream // WASI has no dup
51		else if (__dup3(f2->fd, f->fd, fl&O_CLOEXEC)<0) goto fail2;
52#else
53		// WASI doesn't have dup3, but does have a way to renumber
54		// an existing file descriptor.
55		else {
56			if (__wasilibc_fd_renumber(f2->fd, f->fd)<0) goto fail2;
57			f2->fd = -1; /* avoid closing in fclose */
58		}
59#endif
60
61		f->flags = (f->flags & F_PERM) | f2->flags;
62		f->read = f2->read;
63		f->write = f2->write;
64		f->seek = f2->seek;
65		f->close = f2->close;
66
67		fclose(f2);
68	}
69
70	f->mode = 0;
71	f->locale = 0;
72	FUNLOCK(f);
73	return f;
74
75fail2:
76	fclose(f2);
77fail:
78	fclose(f);
79	return NULL;
80}
81
82weak_alias(freopen, freopen64);