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 
15 extern "C" int open(const char *fn, int flags, ...);
16 extern "C" int open64(const char *fn, int flags, ...);
17 extern "C" int openat(int dirfd, const char *pathname, int flags, ...);
18 
a()19 void a() {
20   open("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("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 
b()34 void b() {
35   open64("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("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 
c()49 void c() {
50   openat(0, "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(0, "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 
f()64 void f() {
65   open("filename", 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("filename", 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(0, "filename", 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("filename", flag);
86   // CHECK-MESSAGES-NOT: warning:
87   TEMP_FAILURE_RETRY(open("filename", flag));
88   // CHECK-MESSAGES-NOT: warning:
89   open64("filename", flag);
90   // CHECK-MESSAGES-NOT: warning:
91   TEMP_FAILURE_RETRY(open64("filename", flag));
92   // CHECK-MESSAGES-NOT: warning:
93   openat(0, "filename", flag);
94   // CHECK-MESSAGES-NOT: warning:
95   TEMP_FAILURE_RETRY(openat(0, "filename", flag));
96   // CHECK-MESSAGES-NOT: warning:
97 }
98 
99 namespace i {
100 int open(const char *pathname, int flags, ...);
101 int open64(const char *pathname, int flags, ...);
102 int openat(int dirfd, const char *pathname, int flags, ...);
103 
d()104 void d() {
105   open("filename", O_RDWR);
106   // CHECK-MESSAGES-NOT: warning:
107   TEMP_FAILURE_RETRY(open("filename", O_RDWR));
108   // CHECK-MESSAGES-NOT: warning:
109   open64("filename", O_RDWR);
110   // CHECK-MESSAGES-NOT: warning:
111   TEMP_FAILURE_RETRY(open64("filename", O_RDWR));
112   // CHECK-MESSAGES-NOT: warning:
113   openat(0, "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 
e()121 void e() {
122   open("filename", O_CLOEXEC);
123   // CHECK-MESSAGES-NOT: warning:
124   TEMP_FAILURE_RETRY(open("filename", O_CLOEXEC));
125   // CHECK-MESSAGES-NOT: warning:
126   open("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("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("filename", O_CLOEXEC);
135   // CHECK-MESSAGES-NOT: warning:
136   TEMP_FAILURE_RETRY(open64("filename", O_CLOEXEC));
137   // CHECK-MESSAGES-NOT: warning:
138   open64("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("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(0, "filename", O_CLOEXEC);
147   // CHECK-MESSAGES-NOT: warning:
148   TEMP_FAILURE_RETRY(openat(0, "filename", O_CLOEXEC));
149   // CHECK-MESSAGES-NOT: warning:
150   openat(0, "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(0, "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 
160 class G {
161 public:
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 
h()166   void h() {
167     open("filename", O_RDWR);
168     // CHECK-MESSAGES-NOT: warning:
169     TEMP_FAILURE_RETRY(open("filename", O_RDWR));
170     // CHECK-MESSAGES-NOT: warning:
171     open64("filename", O_RDWR);
172     // CHECK-MESSAGES-NOT: warning:
173     TEMP_FAILURE_RETRY(open64("filename", O_RDWR));
174     // CHECK-MESSAGES-NOT: warning:
175     openat(0, "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