dte test coverage


Directory: ./
File: src/util/fd.c
Date: 2025-02-14 16:55: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 42 int xpipe2(int fd[2], int flags)
8 {
9 42 BUG_ON((flags & (O_CLOEXEC | O_NONBLOCK)) != flags);
10
11 #if HAVE_PIPE2
12
1/2
✗ Branch 0 (5→6) not taken.
✓ Branch 1 (5→24) taken 42 times.
42 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 63 int xdup3(int oldfd, int newfd, int flags)
51 {
52 63 BUG_ON((flags & O_CLOEXEC) != flags);
53 63 int fd;
54
55 #if HAVE_DUP3
56 126 do {
57 63 fd = dup3(oldfd, newfd, flags);
58
1/4
✗ Branch 0 (5→6) not taken.
✓ Branch 1 (5→7) taken 63 times.
✗ Branch 2 (6→4) not taken.
✗ Branch 3 (6→7) not taken.
63 } while (unlikely(fd < 0 && errno == EINTR));
59
60
1/4
✗ Branch 0 (7→8) not taken.
✓ Branch 1 (7→17) taken 63 times.
✗ Branch 2 (8→9) not taken.
✗ Branch 3 (8→17) not taken.
63 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 (4→5) not taken.
✓ Branch 1 (4→6) taken 2 times.
✗ Branch 2 (5→3) not taken.
✗ Branch 3 (5→6) not taken.
2 } while (unlikely(r != 0 && errno == EINTR));
92 2 return r;
93 }
94
95 21 int xfchmod(int fd, mode_t mode)
96 {
97 21 int r;
98 42 do {
99 21 r = fchmod(fd, mode);
100
1/4
✗ Branch 0 (4→5) not taken.
✓ Branch 1 (4→6) taken 21 times.
✗ Branch 2 (5→3) not taken.
✗ Branch 3 (5→6) not taken.
21 } while (unlikely(r != 0 && errno == EINTR));
101 21 return r;
102 }
103
104 21 int xftruncate(int fd, off_t length)
105 {
106 21 int r;
107 42 do {
108 21 r = ftruncate(fd, length);
109
1/4
✗ Branch 0 (4→5) not taken.
✓ Branch 1 (4→6) taken 21 times.
✗ Branch 2 (5→3) not taken.
✗ Branch 3 (5→6) not taken.
21 } while (unlikely(r != 0 && errno == EINTR));
110 21 return r;
111 }
112