mirror of
https://github.com/fluencelabs/musl
synced 2025-05-28 23:21:34 +00:00
commit 58165923890865a6ac042fafce13f440ee986fd9 added these optional cancellation points on the basis that cancellable stdio could be useful, to unblock threads stuck on stdio operations that will never complete. however, the only way to ensure that cancellation can achieve this is to violate the rules for side effects when cancellation is acted upon, discarding knowledge of any partial data transfer already completed. our implementation exhibited this behavior and was thus non-conforming. in addition to improving correctness, removing these cancellation points moderately reduces code size, and should significantly improve performance on i386, where sysenter/syscall instructions can be used instead of "int $128" for non-cancellable syscalls.
34 lines
605 B
C
34 lines
605 B
C
#include "stdio_impl.h"
|
|
#include <fcntl.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
|
|
FILE *fopen(const char *restrict filename, const char *restrict mode)
|
|
{
|
|
FILE *f;
|
|
int fd;
|
|
int flags;
|
|
|
|
/* Check for valid initial mode character */
|
|
if (!strchr("rwa", *mode)) {
|
|
errno = EINVAL;
|
|
return 0;
|
|
}
|
|
|
|
/* Compute the flags to pass to open() */
|
|
flags = __fmodeflags(mode);
|
|
|
|
fd = sys_open(filename, flags, 0666);
|
|
if (fd < 0) return 0;
|
|
if (flags & O_CLOEXEC)
|
|
__syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC);
|
|
|
|
f = __fdopen(fd, mode);
|
|
if (f) return f;
|
|
|
|
__syscall(SYS_close, fd);
|
|
return 0;
|
|
}
|
|
|
|
LFS64(fopen);
|