Line | Branch | Exec | Source |
---|---|---|---|
1 | #ifndef UTIL_XSTDIO_H | ||
2 | #define UTIL_XSTDIO_H | ||
3 | |||
4 | #include <errno.h> | ||
5 | #include <stdarg.h> | ||
6 | #include <stdbool.h> | ||
7 | #include <stdio.h> | ||
8 | #include "debug.h" | ||
9 | #include "macros.h" | ||
10 | #include "xreadwrite.h" | ||
11 | |||
12 | // Convert fopen(3) mode string to equivalent open(3) flags | ||
13 | 8 | static inline int xfopen_mode_to_flags(const char *mode) | |
14 | { | ||
15 | 8 | BUG_ON(mode[0] == '\0'); | |
16 | 8 | bool plus = (mode[1] == '+'); | |
17 | 12 | BUG_ON(mode[plus ? 2 : 1] != '\0'); | |
18 | |||
19 |
3/4✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
8 | switch (mode[0]) { |
20 | 2 | case 'a': | |
21 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
2 | return (plus ? O_RDWR : O_WRONLY) | O_CREAT | O_APPEND; |
22 | 3 | case 'r': | |
23 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
|
3 | return (plus ? O_RDWR : O_RDONLY); |
24 | 3 | case 'w': | |
25 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
|
3 | return (plus ? O_RDWR : O_WRONLY) | O_CREAT | O_TRUNC; |
26 | } | ||
27 | |||
28 | − | BUG("Unknown fopen() mode string: '%s'", mode); | |
29 | return 0; | ||
30 | } | ||
31 | |||
32 | 8 | static inline FILE *xfopen(const char *path, const char *mode, int flags, mode_t mask) | |
33 | { | ||
34 | 8 | BUG_ON(flags != (flags & (O_CLOEXEC | O_NOCTTY | O_NOFOLLOW))); | |
35 | 8 | flags |= xfopen_mode_to_flags(mode); | |
36 | |||
37 | 8 | int fd = xopen(path, flags, mask); | |
38 |
1/2✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
|
8 | if (fd < 0) { |
39 | return NULL; | ||
40 | } | ||
41 | |||
42 | 8 | FILE *file = fdopen(fd, mode); | |
43 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | if (unlikely(!file)) { |
44 | ✗ | int e = errno; | |
45 | ✗ | xclose(fd); | |
46 | ✗ | errno = e; | |
47 | } | ||
48 | return file; | ||
49 | } | ||
50 | |||
51 | char *xfgets(char *restrict buf, int bufsize, FILE *restrict stream); | ||
52 | int xfputs(const char *restrict str, FILE *restrict stream); | ||
53 | int xfputc(int c, FILE *stream); | ||
54 | int xvfprintf(FILE *restrict stream, const char *restrict fmt, va_list ap) VPRINTF(2); | ||
55 | int xfprintf(FILE *restrict stream, const char *restrict fmt, ...) PRINTF(2); | ||
56 | int xfflush(FILE *stream); | ||
57 | |||
58 | #endif | ||
59 |