]>
Commit | Line | Data |
---|---|---|
e5f14be3 | 1 | #ifdef __wasilibc_unmodified_upstream // WASI has no syscall, dup |
320054e8 DG |
2 | #include "stdio_impl.h" |
3 | #else | |
4 | #include <wasi/libc.h> | |
5 | #endif | |
6 | #include <fcntl.h> | |
7 | #include <unistd.h> | |
e5f14be3 | 8 | #ifdef __wasilibc_unmodified_upstream // WASI has no syscall, dup |
320054e8 DG |
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 | ||
23 | FILE *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) | |
e5f14be3 | 34 | #ifdef __wasilibc_unmodified_upstream // WASI has no syscall |
320054e8 DG |
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); | |
e5f14be3 | 40 | #ifdef __wasilibc_unmodified_upstream // WASI has no syscall |
320054e8 DG |
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 */ | |
e5f14be3 | 50 | #ifdef __wasilibc_unmodified_upstream // WASI has no dup |
320054e8 DG |
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 | FUNLOCK(f); | |
71 | return f; | |
72 | ||
73 | fail2: | |
74 | fclose(f2); | |
75 | fail: | |
76 | fclose(f); | |
77 | return NULL; | |
78 | } | |
79 | ||
80 | weak_alias(freopen, freopen64); |