dte test coverage


Directory: ./
File: src/util/fd.c
Date: 2024-12-21 16:03:22
Exec Total Coverage
Lines: 28 50 56.0%
Functions: 5 5 100.0%
Branches: 6 48 12.5%

Line Branch Exec Source
1 #include "feature.h"
2 #include <sys/stat.h>
3 #include "fd.h"
4 #include "debug.h"
5 #include "xreadwrite.h"
6
7 32 int xpipe2(int fd[2], int flags)
8 {
9 32 BUG_ON((flags & (O_CLOEXEC | O_NONBLOCK)) != flags);
10
11 #if HAVE_PIPE2
12
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 if (likely(pipe2(fd, flags) == 0)) {
13 return 0;
14 }
15 // If pipe2() fails with ENOSYS, it means the function is just a stub
16 // and not actually supported. In that case, the pure POSIX fallback
17 // implementation should be tried instead. In other cases, the failure
18 // is probably caused by a normal error condition.
19 if (errno != ENOSYS) {
20 return -1;
21 }
22 #endif
23
24 // NOLINTNEXTLINE(android-cloexec-pipe)
25 if (unlikely(pipe(fd) != 0)) {
26 return -1;
27 }
28
29 if (flags & O_CLOEXEC) {
30 if (unlikely(!fd_set_cloexec(fd[0], true) || !fd_set_cloexec(fd[1], true))) {
31 goto error;
32 }
33 }
34 if (flags & O_NONBLOCK) {
35 if (unlikely(!fd_set_nonblock(fd[0], true) || !fd_set_nonblock(fd[1], true))) {
36 goto error;
37 }
38 }
39
40 return 0;
41
42 error:;
43 int e = errno;
44 xclose(fd[0]);
45 xclose(fd[1]);
46 errno = e;
47 return -1;
48 }
49
50 54 int xdup3(int oldfd, int newfd, int flags)
51 {
52 54 BUG_ON((flags & O_CLOEXEC) != flags);
53 54 int fd;
54
55 #if HAVE_DUP3
56 108 do {
57 54 fd = dup3(oldfd, newfd, flags);
58
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
54 } while (unlikely(fd < 0 && errno == EINTR));
59
60
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
54 if (fd != -1 || errno != ENOSYS) {
61 return fd;
62 }
63
64 // If execution reaches this point, dup3() failed with ENOSYS
65 // ("function not supported"), so we fall through to the pure
66 // POSIX implementation below.
67 #endif
68
69 if (unlikely(oldfd == newfd)) {
70 // Replicate dup3() behaviour:
71 errno = EINVAL;
72 return -1;
73 }
74
75 do {
76 fd = dup2(oldfd, newfd);
77 } while (unlikely(fd < 0 && errno == EINTR));
78
79 if (fd >= 0 && (flags & O_CLOEXEC)) {
80 (void)!fd_set_cloexec(fd, true);
81 }
82
83 return fd;
84 }
85
86 2 int xfchown(int fd, uid_t owner, gid_t group)
87 {
88 2 int r;
89 4 do {
90 2 r = fchown(fd, owner, group);
91
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 } while (unlikely(r != 0 && errno == EINTR));
92 2 return r;
93 }
94
95 16 int xfchmod(int fd, mode_t mode)
96 {
97 16 int r;
98 32 do {
99 16 r = fchmod(fd, mode);
100
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
16 } while (unlikely(r != 0 && errno == EINTR));
101 16 return r;
102 }
103
104 16 int xftruncate(int fd, off_t length)
105 {
106 16 int r;
107 32 do {
108 16 r = ftruncate(fd, length);
109
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
16 } while (unlikely(r != 0 && errno == EINTR));
110 16 return r;
111 }
112