1#ifndef _STDIO_H
2#define _STDIO_H
3
4#ifdef __cplusplus
5extern "C" {
6#endif
7
8#include <features.h>
9#include <stdint.h>
10
11#define __NEED_FILE
12#define __NEED___isoc_va_list
13#define __NEED_size_t
14
15#if __STDC_VERSION__ < 201112L
16#define __NEED_struct__IO_FILE
17#endif
18
19#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
20 || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
21 || defined(_BSD_SOURCE)
22#define __NEED_ssize_t
23#define __NEED_off_t
24#define __NEED_va_list
25#endif
26
27#include <bits/alltypes.h>
28
29#ifdef __cplusplus
30#define NULL 0L
31#else
32#define NULL ((void*)0)
33#endif
34
35#undef EOF
36#define EOF (-1)
37
38#undef SEEK_SET
39#undef SEEK_CUR
40#undef SEEK_END
41#define SEEK_SET 0
42#define SEEK_CUR 1
43#define SEEK_END 2
44
45#define _IOFBF 0
46#define _IOLBF 1
47#define _IONBF 2
48
49#define BUFSIZ 1024
50#define FILENAME_MAX 4096
51#define FOPEN_MAX 1000
52#define TMP_MAX 10000
53#define L_tmpnam 20
54
55typedef union _G_fpos64_t {
56	char __opaque[16];
57	long long __lldata;
58	double __align;
59} fpos_t;
60
61extern FILE *const stdin;
62extern FILE *const stdout;
63extern FILE *const stderr;
64
65#define stdin  (stdin)
66#define stdout (stdout)
67#define stderr (stderr)
68
69FILE *fopen(const char *__restrict, const char *__restrict);
70FILE *freopen(const char *__restrict, const char *__restrict, FILE *__restrict);
71int fclose(FILE *);
72
73int remove(const char *);
74int rename(const char *, const char *);
75
76int feof(FILE *);
77int ferror(FILE *);
78int fflush(FILE *);
79void clearerr(FILE *);
80
81int fseek(FILE *, long, int);
82long ftell(FILE *);
83void rewind(FILE *);
84
85int fgetpos(FILE *__restrict, fpos_t *__restrict);
86int fsetpos(FILE *, const fpos_t *);
87
88size_t fread(void *__restrict, size_t, size_t, FILE *__restrict);
89size_t fwrite(const void *__restrict, size_t, size_t, FILE *__restrict);
90
91int fgetc(FILE *);
92int getc(FILE *);
93int getchar(void);
94int ungetc(int, FILE *);
95
96int fputc(int, FILE *);
97int putc(int, FILE *);
98int putchar(int);
99
100char *fgets(char *__restrict, int, FILE *__restrict);
101#if __STDC_VERSION__ < 201112L
102char *gets(char *);
103#endif
104
105int fputs(const char *__restrict, FILE *__restrict);
106int puts(const char *);
107
108int printf(const char *__restrict, ...);
109int fprintf(FILE *__restrict, const char *__restrict, ...);
110int sprintf(char *__restrict, const char *__restrict, ...);
111int snprintf(char *__restrict, size_t, const char *__restrict, ...);
112
113int vprintf(const char *__restrict, __isoc_va_list);
114int vfprintf(FILE *__restrict, const char *__restrict, __isoc_va_list);
115int vsprintf(char *__restrict, const char *__restrict, __isoc_va_list);
116int vsnprintf(char *__restrict, size_t, const char *__restrict, __isoc_va_list);
117
118int scanf(const char *__restrict, ...);
119int fscanf(FILE *__restrict, const char *__restrict, ...);
120int sscanf(const char *__restrict, const char *__restrict, ...);
121int vscanf(const char *__restrict, __isoc_va_list);
122int vfscanf(FILE *__restrict, const char *__restrict, __isoc_va_list);
123int vsscanf(const char *__restrict, const char *__restrict, __isoc_va_list);
124
125void perror(const char *);
126
127int setvbuf(FILE *__restrict, char *__restrict, int, size_t);
128void setbuf(FILE *__restrict, char *__restrict);
129
130char *tmpnam(char *);
131FILE *tmpfile(void);
132
133#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
134 || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
135 || defined(_BSD_SOURCE)
136FILE *fmemopen(void *__restrict, size_t, const char *__restrict);
137FILE *open_memstream(char **, size_t *);
138FILE *fdopen(int, const char *);
139FILE *popen(const char *, const char *);
140int pclose(FILE *);
141int fileno(FILE *);
142int fseeko(FILE *, off_t, int);
143off_t ftello(FILE *);
144int dprintf(int, const char *__restrict, ...);
145int vdprintf(int, const char *__restrict, __isoc_va_list);
146void flockfile(FILE *);
147int ftrylockfile(FILE *);
148void funlockfile(FILE *);
149int getc_unlocked(FILE *);
150int getchar_unlocked(void);
151int putc_unlocked(int, FILE *);
152int putchar_unlocked(int);
153ssize_t getdelim(char **__restrict, size_t *__restrict, int, FILE *__restrict);
154ssize_t getline(char **__restrict, size_t *__restrict, FILE *__restrict);
155int renameat(int, const char *, int, const char *);
156#define RENAME_NOREPLACE (1 << 0)
157#define RENAME_EXCHANGE  (1 << 1)
158#define RENAME_WHITEOUT  (1 << 2)
159int renameat2(int, const char *, int, const char *, unsigned int);
160char *ctermid(char *);
161#define L_ctermid 20
162#endif
163
164
165#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
166 || defined(_BSD_SOURCE)
167#define P_tmpdir "/tmp"
168char *tempnam(const char *, const char *);
169#endif
170
171#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
172#define L_cuserid 20
173void setlinebuf(FILE *);
174void setbuffer(FILE *, char *, size_t);
175int fgetc_unlocked(FILE *);
176int fputc_unlocked(int, FILE *);
177int fflush_unlocked(FILE *);
178size_t fread_unlocked(void *, size_t, size_t, FILE *);
179size_t fwrite_unlocked(const void *, size_t, size_t, FILE *);
180void clearerr_unlocked(FILE *);
181int feof_unlocked(FILE *);
182int ferror_unlocked(FILE *);
183int fileno_unlocked(FILE *);
184int putw(int, FILE *);
185char *fgetln(FILE *, size_t *);
186int asprintf(char **, const char *, ...);
187int vasprintf(char **, const char *, __isoc_va_list);
188#endif
189
190#ifdef _GNU_SOURCE
191char *fgets_unlocked(char *, int, FILE *);
192int fputs_unlocked(const char *, FILE *);
193
194typedef ssize_t (cookie_read_function_t)(void *, char *, size_t);
195typedef ssize_t (cookie_write_function_t)(void *, const char *, size_t);
196typedef int (cookie_seek_function_t)(void *, off_t *, int);
197typedef int (cookie_close_function_t)(void *);
198
199typedef struct _IO_cookie_io_functions_t {
200	cookie_read_function_t *read;
201	cookie_write_function_t *write;
202	cookie_seek_function_t *seek;
203	cookie_close_function_t *close;
204} cookie_io_functions_t;
205FILE *fopencookie(void *, const char *, cookie_io_functions_t);
206#endif
207
208#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
209#define tmpfile64 tmpfile
210#define fopen64 fopen
211#define freopen64 freopen
212#define fseeko64 fseeko
213#define ftello64 ftello
214#define fgetpos64 fgetpos
215#define fsetpos64 fsetpos
216#define fpos64_t fpos_t
217#define off64_t off_t
218#endif
219
220/**
221 * @brief Enumerates fd owner type.
222 *
223 * @since 12
224 */
225enum fdsan_owner_type {
226    /* Default type value */
227    FDSAN_OWNER_TYPE_DEFAULT = 0,
228    /* Max value */
229    FDSAN_OWNER_TYPE_MAX = 255,
230    /* File */
231    FDSAN_OWNER_TYPE_FILE = 1,
232    /* Directory */
233    FDSAN_OWNER_TYPE_DIRECTORY = 2,
234    /* Unique fd */
235    FDSAN_OWNER_TYPE_UNIQUE_FD = 3,
236    /* Zip archive */
237    FDSAN_OWNER_TYPE_ZIP_ARCHIVE = 4,
238};
239
240/**
241 * @brief Create an owner tag using specified fdsan_owner_type and at least 56 bits tag value.
242 *
243 * @param type: Indicate the specified fdsan_owner_type.
244 * @param tag: Indicate the specified tag value, at least 56 bits, usually specified as sturct address such as FILE*.
245 * @return Return the created tag, which can be used to exchange.
246 * @since 12
247 */
248uint64_t fdsan_create_owner_tag(enum fdsan_owner_type type, uint64_t tag);
249
250/**
251 * @brief Exchange owner tag for specified fd.
252 *
253 * This method will check if param expected_tag is euqal to current owner tag, fdsan error will occur if not.
254 *
255 * @param fd: Specified fd.
256 * @param expected_tag: Used to check if equal to current owner tag.
257 * @param new_tag: Used to exchange the specified fd owner tag.
258 * @since 12
259 */
260void fdsan_exchange_owner_tag(int fd, uint64_t expected_tag, uint64_t new_tag);
261
262/**
263 * @brief Check fd owner tag and close fd.
264 *
265 * This method will check if param tag is euqal to current owner tag, fdsan error will occur if not,
266 * then call syscall to close fd.
267 *
268 * @param fd: Specified fd.
269 * @param tag: Used to check if equal to current owner tag.
270 * @return Return close result, 0 success and -1 if fail.
271 * @since 12
272 */
273int fdsan_close_with_tag(int fd, uint64_t tag);
274
275/**
276 * @brief Get specified fd's owner tag.
277 *
278 * @param fd: Specified fd.
279 * @return Return tag value of specified fd, return 0 if fd is not in fd table.
280 * @since 12
281 */
282uint64_t fdsan_get_owner_tag(int fd);
283
284/**
285 * @brief Get owner fd type
286 *
287 * @param tag: Specified tag, which usually comes from {@link fdsan_get_owner_tag}
288 * @return Return type value of tag, possible value: FILE*, DIR*, unique_fd, ZipArchive, unknown type and so on.
289 * @since 12
290 */
291const char* fdsan_get_tag_type(uint64_t tag);
292
293/**
294 * @brief Get owner fd tag value.
295 *
296 * @param tag: Specified tag, which usually comes from {@link fdsan_get_owner_tag}
297 * @return Return value of tag, last 56 bits are valid.
298 * @since 12
299 */
300uint64_t fdsan_get_tag_value(uint64_t tag);
301
302/**
303 * @brief Enumerates fdsan error level.
304 *
305 * @since 12
306 */
307enum fdsan_error_level {
308    /* Do nothing if fdsan error occurs. */
309    FDSAN_ERROR_LEVEL_DISABLED,
310    /* Warning once if fdsan error occurs, and then downgrade to FDSAN_ERROR_LEVEL_DISABLED. */
311    FDSAN_ERROR_LEVEL_WARN_ONCE,
312    /* Keep warning only if fdsan error occurs. */
313    FDSAN_ERROR_LEVEL_WARN_ALWAYS,
314    /* Abort on fdsan error. */
315    FDSAN_ERROR_LEVEL_FATAL,
316};
317
318/**
319 * @brief Get fdsan error level.
320 *
321 * @return Return fdsan error level enumerate value.
322 * @since 12
323 */
324enum fdsan_error_level fdsan_get_error_level();
325
326/**
327 * @brief Set fdsan error level.
328 *
329 * @param new_level: Used to set fdsan error level.
330 * @return Return old fdsan error level enumerate value.
331 * @since 12
332 */
333enum fdsan_error_level fdsan_set_error_level(enum fdsan_error_level new_level);
334
335#include <fortify/stdio.h>
336
337#ifdef __cplusplus
338}
339#endif
340
341#endif
342