1 // Copyright 2019 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 // A binary that tests for opened or closed file descriptors as specified.
16
17 #include <fcntl.h>
18 #include <linux/fs.h>
19
20 #include <cerrno>
21 #include <cstdio>
22 #include <cstdlib>
23 #include <cstring>
24
25 // The fd provided should not be open.
TestClosedFd(int fd)26 void TestClosedFd(int fd) {
27 int ret = fcntl(fd, F_GETFD);
28 if (ret != -1) {
29 printf("FAILURE: FD:%d is not closed\n", fd);
30 exit(EXIT_FAILURE);
31 }
32 if (errno != EBADF) {
33 printf(
34 "FAILURE: fcntl(%d) returned errno=%d (%s), should have "
35 "errno=EBADF/%d (%s)\n",
36 fd, errno, strerror(errno), EBADF, strerror(EBADF));
37 exit(EXIT_FAILURE);
38 }
39 }
40
41 // The fd provided should be open.
TestOpenFd(int fd)42 void TestOpenFd(int fd) {
43 int ret = fcntl(fd, F_GETFD);
44 if (ret == -1) {
45 printf("FAILURE: fcntl(%d) returned -1 with errno=%d (%s)\n", fd, errno,
46 strerror(errno));
47 exit(EXIT_FAILURE);
48 }
49 }
50
main(int argc,char * argv[])51 int main(int argc, char* argv[]) {
52 // Disable caching.
53 setbuf(stdin, nullptr);
54 setbuf(stdout, nullptr);
55 setbuf(stderr, nullptr);
56
57 for (int i = 0; i <= INR_OPEN_MAX; i++) {
58 bool should_be_closed = true;
59 for (int j = 0; j < argc; j++) {
60 errno = 0;
61 int cur_fd = strtol(argv[j], nullptr, 10); // NOLINT
62 if (errno != 0) {
63 printf("FAILURE: strtol('%s') failed\n", argv[j]);
64 exit(EXIT_FAILURE);
65 }
66 if (i == cur_fd) {
67 should_be_closed = false;
68 }
69 }
70
71 printf("%d:%c ", i, should_be_closed ? 'C' : 'O');
72
73 if (should_be_closed) {
74 TestClosedFd(i);
75 } else {
76 TestOpenFd(i);
77 }
78 }
79
80 printf("OK: All tests went OK\n");
81 return EXIT_SUCCESS;
82 }
83