Line data Source code
1 : /* Checking macros for fcntl functions.
2 : Copyright (C) 2007-2026 Free Software Foundation, Inc.
3 : This file is part of the GNU C Library.
4 :
5 : The GNU C Library is free software; you can redistribute it and/or
6 : modify it under the terms of the GNU Lesser General Public
7 : License as published by the Free Software Foundation; either
8 : version 2.1 of the License, or (at your option) any later version.
9 :
10 : The GNU C Library is distributed in the hope that it will be useful,
11 : but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 : Lesser General Public License for more details.
14 :
15 : You should have received a copy of the GNU Lesser General Public
16 : License along with the GNU C Library; if not, see
17 : <https://www.gnu.org/licenses/>. */
18 :
19 : #ifndef _FCNTL_H
20 : # error "Never include <bits/fcntl2.h> directly; use <fcntl.h> instead."
21 : #endif
22 :
23 : /* Check that calls to open and openat with O_CREAT or O_TMPFILE set have an
24 : appropriate third/fourth parameter. */
25 : #ifndef __USE_FILE_OFFSET64
26 : extern int __open_2 (const char *__path, int __oflag) __nonnull ((1));
27 : extern int __REDIRECT (__open_alias, (const char *__path, int __oflag, ...),
28 : open) __nonnull ((1));
29 : #else
30 : extern int __REDIRECT (__open_2, (const char *__path, int __oflag),
31 : __open64_2) __nonnull ((1));
32 : extern int __REDIRECT (__open_alias, (const char *__path, int __oflag, ...),
33 : open64) __nonnull ((1));
34 : #endif
35 :
36 : #ifdef __va_arg_pack_len
37 : __errordecl (__open_too_many_args,
38 : "open can be called either with 2 or 3 arguments, not more");
39 : __errordecl (__open_missing_mode,
40 : "open with O_CREAT or O_TMPFILE in second argument needs 3 arguments");
41 :
42 : __fortify_function int
43 0 : open (const char *__path, int __oflag, ...)
44 : {
45 0 : if (__va_arg_pack_len () > 1)
46 : __open_too_many_args ();
47 :
48 0 : if (__builtin_constant_p (__oflag))
49 : {
50 0 : if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)
51 : {
52 : __open_missing_mode ();
53 : return __open_2 (__path, __oflag);
54 : }
55 0 : return __open_alias (__path, __oflag, __va_arg_pack ());
56 : }
57 :
58 : if (__va_arg_pack_len () < 1)
59 : return __open_2 (__path, __oflag);
60 :
61 : return __open_alias (__path, __oflag, __va_arg_pack ());
62 : }
63 : #elif __fortify_use_clang
64 : __fortify_function __attribute_overloadable__ int
65 : open (__fortify_clang_overload_arg (const char *, ,__path), int __oflag)
66 : __fortify_clang_error (__OPEN_NEEDS_MODE (__oflag),
67 : "open with O_CREAT or O_TMPFILE in second argument needs 3 arguments")
68 : {
69 : return __open_2 (__path, __oflag);
70 : }
71 :
72 : __fortify_function __attribute_overloadable__ int
73 : open (__fortify_clang_overload_arg (const char *, ,__path), int __oflag,
74 : mode_t __mode)
75 : {
76 : return __open_alias (__path, __oflag, __mode);
77 : }
78 : #endif
79 :
80 :
81 : #ifdef __USE_LARGEFILE64
82 : extern int __open64_2 (const char *__path, int __oflag) __nonnull ((1));
83 : extern int __REDIRECT (__open64_alias, (const char *__path, int __oflag,
84 : ...), open64) __nonnull ((1));
85 : # ifdef __va_arg_pack_len
86 : __errordecl (__open64_too_many_args,
87 : "open64 can be called either with 2 or 3 arguments, not more");
88 : __errordecl (__open64_missing_mode,
89 : "open64 with O_CREAT or O_TMPFILE in second argument needs 3 arguments");
90 :
91 : __fortify_function int
92 : open64 (const char *__path, int __oflag, ...)
93 : {
94 : if (__va_arg_pack_len () > 1)
95 : __open64_too_many_args ();
96 :
97 : if (__builtin_constant_p (__oflag))
98 : {
99 : if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)
100 : {
101 : __open64_missing_mode ();
102 : return __open64_2 (__path, __oflag);
103 : }
104 : return __open64_alias (__path, __oflag, __va_arg_pack ());
105 : }
106 :
107 : if (__va_arg_pack_len () < 1)
108 : return __open64_2 (__path, __oflag);
109 :
110 : return __open64_alias (__path, __oflag, __va_arg_pack ());
111 : }
112 : # elif __fortify_use_clang
113 : __fortify_function_error_function __attribute_overloadable__ int
114 : open64 (const char *__path, int __oflag, mode_t __mode, ...)
115 : __fortify_clang_unavailable ("open64 can be called either with 2 or 3 arguments, not more");
116 :
117 : __fortify_function __attribute_overloadable__ int
118 : open64 (__fortify_clang_overload_arg (const char *, ,__path), int __oflag)
119 : __fortify_clang_prefer_this_overload
120 : __fortify_clang_error (__OPEN_NEEDS_MODE (__oflag),
121 : "open64 with O_CREAT or O_TMPFILE in second argument needs 3 arguments")
122 : {
123 : return __open64_2 (__path, __oflag);
124 : }
125 :
126 : __fortify_function __attribute_overloadable__ int
127 : open64 (__fortify_clang_overload_arg (const char *, ,__path), int __oflag,
128 : mode_t __mode)
129 : {
130 : return __open64_alias (__path, __oflag, __mode);
131 : }
132 : # endif
133 : #endif
134 :
135 :
136 : #ifdef __USE_ATFILE
137 : # ifndef __USE_FILE_OFFSET64
138 : extern int __openat_2 (int __fd, const char *__path, int __oflag)
139 : __nonnull ((2));
140 : extern int __REDIRECT (__openat_alias, (int __fd, const char *__path,
141 : int __oflag, ...), openat)
142 : __nonnull ((2));
143 : # else
144 : extern int __REDIRECT (__openat_2, (int __fd, const char *__path,
145 : int __oflag), __openat64_2)
146 : __nonnull ((2));
147 : extern int __REDIRECT (__openat_alias, (int __fd, const char *__path,
148 : int __oflag, ...), openat64)
149 : __nonnull ((2));
150 : # endif
151 :
152 : # ifdef __va_arg_pack_len
153 : __errordecl (__openat_too_many_args,
154 : "openat can be called either with 3 or 4 arguments, not more");
155 : __errordecl (__openat_missing_mode,
156 : "openat with O_CREAT or O_TMPFILE in third argument needs 4 arguments");
157 :
158 : __fortify_function int
159 : openat (int __fd, const char *__path, int __oflag, ...)
160 : {
161 : if (__va_arg_pack_len () > 1)
162 : __openat_too_many_args ();
163 :
164 : if (__builtin_constant_p (__oflag))
165 : {
166 : if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)
167 : {
168 : __openat_missing_mode ();
169 : return __openat_2 (__fd, __path, __oflag);
170 : }
171 : return __openat_alias (__fd, __path, __oflag, __va_arg_pack ());
172 : }
173 :
174 : if (__va_arg_pack_len () < 1)
175 : return __openat_2 (__fd, __path, __oflag);
176 :
177 : return __openat_alias (__fd, __path, __oflag, __va_arg_pack ());
178 : }
179 : # elif __fortify_use_clang
180 : __fortify_function_error_function __attribute_overloadable__ int
181 : openat (int __fd, const char *__path, int __oflag, mode_t __mode, ...)
182 : __fortify_clang_unavailable ("openat can be called either with 3 or 4 arguments, not more");
183 :
184 : __fortify_function __attribute_overloadable__ int
185 : openat (int __fd, __fortify_clang_overload_arg (const char *, ,__path),
186 : int __oflag)
187 : __fortify_clang_prefer_this_overload
188 : __fortify_clang_error (__OPEN_NEEDS_MODE (__oflag),
189 : "openat with O_CREAT or O_TMPFILE in third argument needs 4 arguments")
190 : {
191 : return __openat_2 (__fd, __path, __oflag);
192 : }
193 :
194 : __fortify_function __attribute_overloadable__ int
195 : openat (int __fd, __fortify_clang_overload_arg (const char *, ,__path),
196 : int __oflag, mode_t __mode)
197 : {
198 : return __openat_alias (__fd, __path, __oflag, __mode);
199 : }
200 : # endif
201 :
202 :
203 : # ifdef __USE_LARGEFILE64
204 : extern int __openat64_2 (int __fd, const char *__path, int __oflag)
205 : __nonnull ((2));
206 : extern int __REDIRECT (__openat64_alias, (int __fd, const char *__path,
207 : int __oflag, ...), openat64)
208 : __nonnull ((2));
209 : __errordecl (__openat64_too_many_args,
210 : "openat64 can be called either with 3 or 4 arguments, not more");
211 : __errordecl (__openat64_missing_mode,
212 : "openat64 with O_CREAT or O_TMPFILE in third argument needs 4 arguments");
213 :
214 : # ifdef __va_arg_pack_len
215 : __fortify_function int
216 : openat64 (int __fd, const char *__path, int __oflag, ...)
217 : {
218 : if (__va_arg_pack_len () > 1)
219 : __openat64_too_many_args ();
220 :
221 : if (__builtin_constant_p (__oflag))
222 : {
223 : if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)
224 : {
225 : __openat64_missing_mode ();
226 : return __openat64_2 (__fd, __path, __oflag);
227 : }
228 : return __openat64_alias (__fd, __path, __oflag, __va_arg_pack ());
229 : }
230 :
231 : if (__va_arg_pack_len () < 1)
232 : return __openat64_2 (__fd, __path, __oflag);
233 :
234 : return __openat64_alias (__fd, __path, __oflag, __va_arg_pack ());
235 : }
236 : # elif __fortify_use_clang
237 : __fortify_function_error_function __attribute_overloadable__ int
238 : openat64 (int __fd, const char *__path, int __oflag, mode_t __mode, ...)
239 : __fortify_clang_unavailable ("openat64 can be called either with 3 or 4 arguments, not more");
240 :
241 : __fortify_function __attribute_overloadable__ int
242 : openat64 (int __fd, __fortify_clang_overload_arg (const char *, ,__path),
243 : int __oflag)
244 : __fortify_clang_prefer_this_overload
245 : __fortify_clang_error (__OPEN_NEEDS_MODE (__oflag),
246 : "openat64 with O_CREAT or O_TMPFILE in third argument needs 4 arguments")
247 : {
248 : return __openat64_2 (__fd, __path, __oflag);
249 : }
250 :
251 : __fortify_function __attribute_overloadable__ int
252 : openat64 (int __fd, __fortify_clang_overload_arg (const char *, ,__path),
253 : int __oflag, mode_t __mode)
254 : {
255 : return __openat64_alias (__fd, __path, __oflag, __mode);
256 : }
257 : # endif
258 : # endif
259 : #endif
|