master
1/* Checking macros for fcntl functions.
2 Copyright (C) 2007-2025 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
26extern int __open_2 (const char *__path, int __oflag) __nonnull ((1));
27extern int __REDIRECT (__open_alias, (const char *__path, int __oflag, ...),
28 open) __nonnull ((1));
29#else
30extern int __REDIRECT (__open_2, (const char *__path, int __oflag),
31 __open64_2) __nonnull ((1));
32extern 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
43open (const char *__path, int __oflag, ...)
44{
45 if (__va_arg_pack_len () > 1)
46 __open_too_many_args ();
47
48 if (__builtin_constant_p (__oflag))
49 {
50 if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)
51 {
52 __open_missing_mode ();
53 return __open_2 (__path, __oflag);
54 }
55 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
65open (__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
73open (__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
82extern int __open64_2 (const char *__path, int __oflag) __nonnull ((1));
83extern 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
92open64 (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
114open64 (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
118open64 (__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
127open64 (__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
138extern int __openat_2 (int __fd, const char *__path, int __oflag)
139 __nonnull ((2));
140extern int __REDIRECT (__openat_alias, (int __fd, const char *__path,
141 int __oflag, ...), openat)
142 __nonnull ((2));
143# else
144extern int __REDIRECT (__openat_2, (int __fd, const char *__path,
145 int __oflag), __openat64_2)
146 __nonnull ((2));
147extern 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
159openat (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
181openat (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
185openat (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
195openat (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
204extern int __openat64_2 (int __fd, const char *__path, int __oflag)
205 __nonnull ((2));
206extern 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
216openat64 (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
238openat64 (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
242openat64 (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
252openat64 (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