| 3303 | } |
| 3304 | |
| 3305 | static FILE *freopen(const char *path, const char *mode, FILE *stream) |
| 3306 | { |
| 3307 | int flags = stdio_parse_mode(mode); |
| 3308 | if (flags < 0) |
| 3309 | { |
| 3310 | fclose(stream); |
| 3311 | errno = EINVAL; |
| 3312 | return NULL; |
| 3313 | } |
| 3314 | int fd = open(path, flags, |
| 3315 | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); |
| 3316 | if (fd < 0) |
| 3317 | { |
| 3318 | fclose(stream); |
| 3319 | return NULL; |
| 3320 | } |
| 3321 | int old_fd = -1; |
| 3322 | bool r = ((flags & O_ACCMODE) != O_WRONLY? true: false); |
| 3323 | bool w = ((flags & O_ACCMODE) != O_RDONLY? true: false); |
| 3324 | flags = (r? STDIO_FLAG_READ: 0) | (w? STDIO_FLAG_WRITE: 0); |
| 3325 | if (mutex_lock(&stream->mutex) < 0) |
| 3326 | { |
| 3327 | close(fd); |
| 3328 | return NULL; |
| 3329 | } |
| 3330 | (void)fflush_unlocked(stream); // Ignore errors |
| 3331 | old_fd = stream->fd; |
| 3332 | stream->fd = fd; |
| 3333 | stream->flags &= ~(STDIO_FLAG_READ | STDIO_FLAG_WRITE | |
| 3334 | STDIO_FLAG_READING | STDIO_FLAG_WRITING | |
| 3335 | STDIO_FLAG_EOF | STDIO_FLAG_ERROR); |
| 3336 | stream->flags |= flags; |
| 3337 | stream->read_ptr = stream->read_end = NULL; |
| 3338 | stream->write_ptr = stream->write_end = NULL; |
| 3339 | mutex_unlock(&stream->mutex); |
| 3340 | (void)close(old_fd); // Ignore errors |
| 3341 | return stream; |
| 3342 | } |
| 3343 | |
| 3344 | static void clearerr_unlocked(FILE *stream) |
| 3345 | { |
no test coverage detected