#include <__stdio.h> #include // for EINVAL, errno #include // for O_WRONLY, O_CREAT, O_RDONLY, open, O_APPEND #include // for FILE, BUFSIZ, fopen, _IOLBF #include // for calloc, free, malloc #include // for strchr #include #include // for close __weak void __stdio_cleanup(void) { } FILE *fopen(const char *restrict pathname, const char *restrict mode) { int fd, flags, _mode; FILE *stream; _mode = 0; if (mode[0] == 'r') { flags = O_RDONLY; } else if (mode[0] == 'w') { flags = O_WRONLY | O_CREAT | O_TRUNC; } else if (mode[0] == 'a') { flags = O_WRONLY | O_CREAT | O_APPEND; _mode = 0666; } else { errno = EINVAL; return NULL; } if (strchr(mode, '+')) { flags = (flags & ~(O_RDONLY | O_WRONLY)) | O_RDWR; } fd = open(pathname, flags, _mode); if (fd < 0) return NULL; stream = calloc(1, sizeof(struct __FILE)); if (stream == NULL) return NULL; __FILE(stream)->fd = fd; __FILE(stream)->buf_size = BUFSIZ; __FILE(stream)->flags = flags; __FILE(stream)->type = _IOLBF; atomic_flag_clear(&__FILE(stream)->lock); __FILE(stream)->buf = malloc(BUFSIZ); if (__FILE(stream)->buf == NULL) { close(fd); free(stream); return NULL; } __libc_fadd(stream); return stream; }