Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend standalone support #18285

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 71 additions & 36 deletions system/lib/libc/musl/src/stdio/freopen.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
#ifdef __wasilibc_unmodified_upstream // WASI has no syscall, dup
#include "stdio_impl.h"
#else
#include <wasi/api.h>
#endif
#include <fcntl.h>
#include <unistd.h>
#ifdef __wasilibc_unmodified_upstream // WASI has no syscall, dup
#else
// Move this below fcntl.h and unistd.h so that the __syscall macro doesn't
// cause trouble.
#include "stdio_impl.h"
#include <errno.h>
#endif

/* The basic idea of this implementation is to open a new FILE,
* hack the necessary parts of the new FILE into the old one, then
Expand All @@ -10,46 +21,70 @@
* lock, via flockfile or otherwise, when freopen is called, and in that
* case, freopen cannot act until the lock is released. */

int __wasilibc_fd_renumber(int fd, int newfd) {
__wasi_errno_t error = __wasi_fd_renumber(fd, newfd);
if (error != 0) {
errno = error;
return -1;
}
return 0;
}

FILE *freopen(const char *restrict filename, const char *restrict mode, FILE *restrict f)
{
int fl = __fmodeflags(mode);
FILE *f2;
int fl = __fmodeflags(mode);
FILE *f2;

FLOCK(f);
FLOCK(f);

fflush(f);
fflush(f);

if (!filename) {
#ifndef __EMSCRIPTEN__ // CLOEXEC makes no sense for a single process
if (fl&O_CLOEXEC)
__syscall(SYS_fcntl, f->fd, F_SETFD, FD_CLOEXEC);
if (!filename) {
if (fl&O_CLOEXEC)
#ifdef __wasilibc_unmodified_upstream // WASI has no syscall
__syscall(SYS_fcntl, f->fd, F_SETFD, FD_CLOEXEC);
#else
fcntl(f->fd, F_SETFD, FD_CLOEXEC);
#endif
fl &= ~(O_CREAT|O_EXCL|O_CLOEXEC);
#ifdef __wasilibc_unmodified_upstream // WASI has no syscall
if (syscall(SYS_fcntl, f->fd, F_SETFL, fl) < 0)
#else
if (fcntl(f->fd, F_SETFL, fl) < 0)
#endif
fl &= ~(O_CREAT|O_EXCL|O_CLOEXEC);
if (syscall(SYS_fcntl, f->fd, F_SETFL, fl) < 0)
goto fail;
} else {
f2 = fopen(filename, mode);
if (!f2) goto fail;
if (f2->fd == f->fd) f2->fd = -1; /* avoid closing in fclose */
else if (__dup3(f2->fd, f->fd, fl&O_CLOEXEC)<0) goto fail2;

f->flags = (f->flags & F_PERM) | f2->flags;
f->read = f2->read;
f->write = f2->write;
f->seek = f2->seek;
f->close = f2->close;

fclose(f2);
}

f->mode = 0;
f->locale = 0;
FUNLOCK(f);
return f;

fail2:
fclose(f2);
fail:
fclose(f);
return NULL;
goto fail;
} else {
f2 = fopen(filename, mode);
if (!f2) goto fail;
if (f2->fd == f->fd) f2->fd = -1; /* avoid closing in fclose */
#ifdef __wasilibc_unmodified_upstream // WASI has no dup
else if (__dup3(f2->fd, f->fd, fl&O_CLOEXEC)<0) goto fail2;
#else
// WASI doesn't have dup3, but does have a way to renumber
// an existing file descriptor.
else {
if (__wasilibc_fd_renumber(f2->fd, f->fd)<0) goto fail2;
f2->fd = -1; /* avoid closing in fclose */
}
#endif

f->flags = (f->flags & F_PERM) | f2->flags;
f->read = f2->read;
f->write = f2->write;
f->seek = f2->seek;
f->close = f2->close;

fclose(f2);
}

FUNLOCK(f);
return f;

fail2:
fclose(f2);
fail:
fclose(f);
return NULL;
}

weak_alias(freopen, freopen64);
Loading