1#ifdef __wasilibc_unmodified_upstream // WASI has no syscall
 2#else
 3#include <unistd.h>
 4#include <wasi/libc.h>
 5#endif
 6#include "stdio_impl.h"
 7#include <fcntl.h>
 8#include <string.h>
 9#include <errno.h>
10
11FILE *fopen(const char *restrict filename, const char *restrict mode)
12{
13	FILE *f;
14	int fd;
15	int flags;
16
17	/* Check for valid initial mode character */
18	if (!strchr("rwa", *mode)) {
19		errno = EINVAL;
20		return 0;
21	}
22
23	/* Compute the flags to pass to open() */
24	flags = __fmodeflags(mode);
25
26#ifdef __wasilibc_unmodified_upstream // WASI has no sys_open
27	fd = sys_open(filename, flags, 0666);
28#else
29	// WASI libc ignores the mode parameter anyway, so skip the varargs.
30	fd = __wasilibc_open_nomode(filename, flags);
31#endif
32	if (fd < 0) return 0;
33#ifdef __wasilibc_unmodified_upstream // WASI has no syscall
34	if (flags & O_CLOEXEC)
35		__syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC);
36#else
37	/* Avoid __syscall, but also, FD_CLOEXEC is not supported in WASI. */
38#endif
39
40	f = __fdopen(fd, mode);
41	if (f) return f;
42
43#ifdef __wasilibc_unmodified_upstream // WASI has no syscall
44	__syscall(SYS_close, fd);
45#else
46	close(fd);
47#endif
48	return 0;
49}
50
51weak_alias(fopen, fopen64);