1// RUN: %check_clang_tidy %s android-cloexec-open %t
2
3#define O_RDWR 1
4#define O_EXCL 2
5#define __O_CLOEXEC 3
6#define O_CLOEXEC __O_CLOEXEC
7#define TEMP_FAILURE_RETRY(exp) \
8 ({ \
9 int _rc; \
10 do { \
11 _rc = (exp); \
12 } while (_rc == -1); \
13 })
14
15extern "C" int open(const char *fn, int flags, ...);
16extern "C" int open64(const char *fn, int flags, ...);
17extern "C" int openat(int dirfd, const char *pathname, int flags, ...);
18
19void a() {
20 open(fn: "filename", O_RDWR);
21 // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'open' should use O_CLOEXEC where possible [android-cloexec-open]
22 // CHECK-FIXES: O_RDWR | O_CLOEXEC
23 TEMP_FAILURE_RETRY(open("filename", O_RDWR));
24 // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: 'open' should use O_CLOEXEC where
25 // CHECK-FIXES: O_RDWR | O_CLOEXEC
26 open(fn: "filename", O_RDWR | O_EXCL);
27 // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: 'open' should use O_CLOEXEC where
28 // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
29 TEMP_FAILURE_RETRY(open("filename", O_RDWR | O_EXCL));
30 // CHECK-MESSAGES: :[[@LINE-1]]:54: warning: 'open' should use O_CLOEXEC where
31 // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
32}
33
34void b() {
35 open64(fn: "filename", O_RDWR);
36 // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: 'open64' should use O_CLOEXEC where possible [android-cloexec-open]
37 // CHECK-FIXES: O_RDWR | O_CLOEXEC
38 TEMP_FAILURE_RETRY(open64("filename", O_RDWR));
39 // CHECK-MESSAGES: :[[@LINE-1]]:47: warning: 'open64' should use O_CLOEXEC where
40 // CHECK-FIXES: O_RDWR | O_CLOEXEC
41 open64(fn: "filename", O_RDWR | O_EXCL);
42 // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: 'open64' should use O_CLOEXEC where
43 // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
44 TEMP_FAILURE_RETRY(open64("filename", O_RDWR | O_EXCL));
45 // CHECK-MESSAGES: :[[@LINE-1]]:56: warning: 'open64' should use O_CLOEXEC where
46 // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
47}
48
49void c() {
50 openat(dirfd: 0, pathname: "filename", O_RDWR);
51 // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 'openat' should use O_CLOEXEC where possible [android-cloexec-open]
52 // CHECK-FIXES: O_RDWR | O_CLOEXEC
53 TEMP_FAILURE_RETRY(openat(0, "filename", O_RDWR));
54 // CHECK-MESSAGES: :[[@LINE-1]]:50: warning: 'openat' should use O_CLOEXEC where
55 // CHECK-FIXES: O_RDWR | O_CLOEXEC
56 openat(dirfd: 0, pathname: "filename", O_RDWR | O_EXCL);
57 // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: 'openat' should use O_CLOEXEC where
58 // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
59 TEMP_FAILURE_RETRY(openat(0, "filename", O_RDWR | O_EXCL));
60 // CHECK-MESSAGES: :[[@LINE-1]]:59: warning: 'openat' should use O_CLOEXEC where
61 // CHECK-FIXES: O_RDWR | O_EXCL | O_CLOEXEC
62}
63
64void f() {
65 open(fn: "filename", flags: 3);
66 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'open' should use O_CLOEXEC where possible [android-cloexec-open]
67 // CHECK-FIXES: 3 | O_CLOEXEC
68 TEMP_FAILURE_RETRY(open("filename", 3));
69 // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: 'open' should use O_CLOEXEC where
70 // CHECK-FIXES: 3 | O_CLOEXEC
71 open64(fn: "filename", flags: 3);
72 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'open64' should use O_CLOEXEC where possible [android-cloexec-open]
73 // CHECK-FIXES: 3 | O_CLOEXEC
74 TEMP_FAILURE_RETRY(open64("filename", 3));
75 // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: 'open64' should use O_CLOEXEC where
76 // CHECK-FIXES: 3 | O_CLOEXEC
77 openat(dirfd: 0, pathname: "filename", flags: 3);
78 // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'openat' should use O_CLOEXEC where possible [android-cloexec-open]
79 // CHECK-FIXES: 3 | O_CLOEXEC
80 TEMP_FAILURE_RETRY(openat(0, "filename", 3));
81 // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: 'openat' should use O_CLOEXEC where
82 // CHECK-FIXES: 3 | O_CLOEXEC
83
84 int flag = 3;
85 open(fn: "filename", flags: flag);
86 // CHECK-MESSAGES-NOT: warning:
87 TEMP_FAILURE_RETRY(open("filename", flag));
88 // CHECK-MESSAGES-NOT: warning:
89 open64(fn: "filename", flags: flag);
90 // CHECK-MESSAGES-NOT: warning:
91 TEMP_FAILURE_RETRY(open64("filename", flag));
92 // CHECK-MESSAGES-NOT: warning:
93 openat(dirfd: 0, pathname: "filename", flags: flag);
94 // CHECK-MESSAGES-NOT: warning:
95 TEMP_FAILURE_RETRY(openat(0, "filename", flag));
96 // CHECK-MESSAGES-NOT: warning:
97}
98
99namespace i {
100int open(const char *pathname, int flags, ...);
101int open64(const char *pathname, int flags, ...);
102int openat(int dirfd, const char *pathname, int flags, ...);
103
104void d() {
105 open(pathname: "filename", O_RDWR);
106 // CHECK-MESSAGES-NOT: warning:
107 TEMP_FAILURE_RETRY(open("filename", O_RDWR));
108 // CHECK-MESSAGES-NOT: warning:
109 open64(pathname: "filename", O_RDWR);
110 // CHECK-MESSAGES-NOT: warning:
111 TEMP_FAILURE_RETRY(open64("filename", O_RDWR));
112 // CHECK-MESSAGES-NOT: warning:
113 openat(dirfd: 0, pathname: "filename", O_RDWR);
114 // CHECK-MESSAGES-NOT: warning:
115 TEMP_FAILURE_RETRY(openat(0, "filename", O_RDWR));
116 // CHECK-MESSAGES-NOT: warning:
117}
118
119} // namespace i
120
121void e() {
122 open(fn: "filename", O_CLOEXEC);
123 // CHECK-MESSAGES-NOT: warning:
124 TEMP_FAILURE_RETRY(open("filename", O_CLOEXEC));
125 // CHECK-MESSAGES-NOT: warning:
126 open(fn: "filename", O_RDWR | O_CLOEXEC);
127 // CHECK-MESSAGES-NOT: warning:
128 TEMP_FAILURE_RETRY(open("filename", O_RDWR | O_CLOEXEC));
129 // CHECK-MESSAGES-NOT: warning:
130 open(fn: "filename", O_RDWR | O_CLOEXEC | O_EXCL);
131 // CHECK-MESSAGES-NOT: warning:
132 TEMP_FAILURE_RETRY(open("filename", O_RDWR | O_CLOEXEC | O_EXCL));
133 // CHECK-MESSAGES-NOT: warning:
134 open64(fn: "filename", O_CLOEXEC);
135 // CHECK-MESSAGES-NOT: warning:
136 TEMP_FAILURE_RETRY(open64("filename", O_CLOEXEC));
137 // CHECK-MESSAGES-NOT: warning:
138 open64(fn: "filename", O_RDWR | O_CLOEXEC);
139 // CHECK-MESSAGES-NOT: warning:
140 TEMP_FAILURE_RETRY(open64("filename", O_RDWR | O_CLOEXEC));
141 // CHECK-MESSAGES-NOT: warning:
142 open64(fn: "filename", O_RDWR | O_CLOEXEC | O_EXCL);
143 // CHECK-MESSAGES-NOT: warning:
144 TEMP_FAILURE_RETRY(open64("filename", O_RDWR | O_CLOEXEC | O_EXCL));
145 // CHECK-MESSAGES-NOT: warning:
146 openat(dirfd: 0, pathname: "filename", O_CLOEXEC);
147 // CHECK-MESSAGES-NOT: warning:
148 TEMP_FAILURE_RETRY(openat(0, "filename", O_CLOEXEC));
149 // CHECK-MESSAGES-NOT: warning:
150 openat(dirfd: 0, pathname: "filename", O_RDWR | O_CLOEXEC);
151 // CHECK-MESSAGES-NOT: warning:
152 TEMP_FAILURE_RETRY(openat(0, "filename", O_RDWR | O_CLOEXEC));
153 // CHECK-MESSAGES-NOT: warning:
154 openat(dirfd: 0, pathname: "filename", O_RDWR | O_CLOEXEC | O_EXCL);
155 // CHECK-MESSAGES-NOT: warning:
156 TEMP_FAILURE_RETRY(openat(0, "filename", O_RDWR | O_CLOEXEC | O_EXCL));
157 // CHECK-MESSAGES-NOT: warning:
158}
159
160class G {
161public:
162 int open(const char *pathname, int flags, ...);
163 int open64(const char *pathname, int flags, ...);
164 int openat(int dirfd, const char *pathname, int flags, ...);
165
166 void h() {
167 open(pathname: "filename", O_RDWR);
168 // CHECK-MESSAGES-NOT: warning:
169 TEMP_FAILURE_RETRY(open("filename", O_RDWR));
170 // CHECK-MESSAGES-NOT: warning:
171 open64(pathname: "filename", O_RDWR);
172 // CHECK-MESSAGES-NOT: warning:
173 TEMP_FAILURE_RETRY(open64("filename", O_RDWR));
174 // CHECK-MESSAGES-NOT: warning:
175 openat(dirfd: 0, pathname: "filename", O_RDWR);
176 // CHECK-MESSAGES-NOT: warning:
177 TEMP_FAILURE_RETRY(openat(0, "filename", O_RDWR));
178 // CHECK-MESSAGES-NOT: warning:
179 }
180};
181

source code of clang-tools-extra/test/clang-tidy/checkers/android/cloexec-open.cpp