xref: /linux/tools/include/nolibc/stdio.h (revision a1ff5a7d78a036d6c2178ee5acd6ba4946243800)
14e383a66SWilly Tarreau /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
24e383a66SWilly Tarreau /*
34e383a66SWilly Tarreau  * minimal stdio function definitions for NOLIBC
44e383a66SWilly Tarreau  * Copyright (C) 2017-2021 Willy Tarreau <w@1wt.eu>
54e383a66SWilly Tarreau  */
64e383a66SWilly Tarreau 
74e383a66SWilly Tarreau #ifndef _NOLIBC_STDIO_H
84e383a66SWilly Tarreau #define _NOLIBC_STDIO_H
94e383a66SWilly Tarreau 
104e383a66SWilly Tarreau #include "std.h"
114e383a66SWilly Tarreau #include "arch.h"
1245a794bfSWilly Tarreau #include "errno.h"
134e383a66SWilly Tarreau #include "types.h"
144e383a66SWilly Tarreau #include "sys.h"
15b56a9492SThomas Weißschuh #include "stdarg.h"
164e383a66SWilly Tarreau #include "stdlib.h"
174e383a66SWilly Tarreau #include "string.h"
184e383a66SWilly Tarreau 
194e383a66SWilly Tarreau #ifndef EOF
204e383a66SWilly Tarreau #define EOF (-1)
214e383a66SWilly Tarreau #endif
224e383a66SWilly Tarreau 
234893c22eSRyan Roberts /* Buffering mode used by setvbuf.  */
244893c22eSRyan Roberts #define _IOFBF 0	/* Fully buffered. */
254893c22eSRyan Roberts #define _IOLBF 1	/* Line buffered. */
264893c22eSRyan Roberts #define _IONBF 2	/* No buffering. */
274893c22eSRyan Roberts 
285df28c15SThomas Weißschuh /* just define FILE as a non-empty type. The value of the pointer gives
295df28c15SThomas Weißschuh  * the FD: FILE=~fd for fd>=0 or NULL for fd<0. This way positive FILE
305df28c15SThomas Weißschuh  * are immediately identified as abnormal entries (i.e. possible copies
315df28c15SThomas Weißschuh  * of valid pointers to something else).
325df28c15SThomas Weißschuh  */
3399b037cbSWilly Tarreau typedef struct FILE {
3499b037cbSWilly Tarreau 	char dummy[1];
3599b037cbSWilly Tarreau } FILE;
3699b037cbSWilly Tarreau 
375df28c15SThomas Weißschuh static __attribute__((unused)) FILE* const stdin  = (FILE*)(intptr_t)~STDIN_FILENO;
385df28c15SThomas Weißschuh static __attribute__((unused)) FILE* const stdout = (FILE*)(intptr_t)~STDOUT_FILENO;
395df28c15SThomas Weißschuh static __attribute__((unused)) FILE* const stderr = (FILE*)(intptr_t)~STDERR_FILENO;
405df28c15SThomas Weißschuh 
415df28c15SThomas Weißschuh /* provides a FILE* equivalent of fd. The mode is ignored. */
425df28c15SThomas Weißschuh static __attribute__((unused))
fdopen(int fd,const char * mode)435df28c15SThomas Weißschuh FILE *fdopen(int fd, const char *mode __attribute__((unused)))
445df28c15SThomas Weißschuh {
455df28c15SThomas Weißschuh 	if (fd < 0) {
465df28c15SThomas Weißschuh 		SET_ERRNO(EBADF);
475df28c15SThomas Weißschuh 		return NULL;
485df28c15SThomas Weißschuh 	}
495df28c15SThomas Weißschuh 	return (FILE*)(intptr_t)~fd;
505df28c15SThomas Weißschuh }
515df28c15SThomas Weißschuh 
525df28c15SThomas Weißschuh /* provides the fd of stream. */
535df28c15SThomas Weißschuh static __attribute__((unused))
fileno(FILE * stream)545df28c15SThomas Weißschuh int fileno(FILE *stream)
555df28c15SThomas Weißschuh {
565df28c15SThomas Weißschuh 	intptr_t i = (intptr_t)stream;
575df28c15SThomas Weißschuh 
585df28c15SThomas Weißschuh 	if (i >= 0) {
595df28c15SThomas Weißschuh 		SET_ERRNO(EBADF);
605df28c15SThomas Weißschuh 		return -1;
615df28c15SThomas Weißschuh 	}
625df28c15SThomas Weißschuh 	return ~i;
635df28c15SThomas Weißschuh }
645df28c15SThomas Weißschuh 
655df28c15SThomas Weißschuh /* flush a stream. */
665df28c15SThomas Weißschuh static __attribute__((unused))
fflush(FILE * stream)675df28c15SThomas Weißschuh int fflush(FILE *stream)
685df28c15SThomas Weißschuh {
695df28c15SThomas Weißschuh 	intptr_t i = (intptr_t)stream;
705df28c15SThomas Weißschuh 
715df28c15SThomas Weißschuh 	/* NULL is valid here. */
725df28c15SThomas Weißschuh 	if (i > 0) {
735df28c15SThomas Weißschuh 		SET_ERRNO(EBADF);
745df28c15SThomas Weißschuh 		return -1;
755df28c15SThomas Weißschuh 	}
765df28c15SThomas Weißschuh 
775df28c15SThomas Weißschuh 	/* Don't do anything, nolibc does not support buffering. */
785df28c15SThomas Weißschuh 	return 0;
795df28c15SThomas Weißschuh }
805df28c15SThomas Weißschuh 
815df28c15SThomas Weißschuh /* flush a stream. */
825df28c15SThomas Weißschuh static __attribute__((unused))
fclose(FILE * stream)835df28c15SThomas Weißschuh int fclose(FILE *stream)
845df28c15SThomas Weißschuh {
855df28c15SThomas Weißschuh 	intptr_t i = (intptr_t)stream;
865df28c15SThomas Weißschuh 
875df28c15SThomas Weißschuh 	if (i >= 0) {
885df28c15SThomas Weißschuh 		SET_ERRNO(EBADF);
895df28c15SThomas Weißschuh 		return -1;
905df28c15SThomas Weißschuh 	}
915df28c15SThomas Weißschuh 
925df28c15SThomas Weißschuh 	if (close(~i))
935df28c15SThomas Weißschuh 		return EOF;
945df28c15SThomas Weißschuh 
955df28c15SThomas Weißschuh 	return 0;
965df28c15SThomas Weißschuh }
9799b037cbSWilly Tarreau 
9899b037cbSWilly Tarreau /* getc(), fgetc(), getchar() */
9999b037cbSWilly Tarreau 
10099b037cbSWilly Tarreau #define getc(stream) fgetc(stream)
10199b037cbSWilly Tarreau 
10299b037cbSWilly Tarreau static __attribute__((unused))
fgetc(FILE * stream)10399b037cbSWilly Tarreau int fgetc(FILE* stream)
10499b037cbSWilly Tarreau {
10599b037cbSWilly Tarreau 	unsigned char ch;
10699b037cbSWilly Tarreau 
1075df28c15SThomas Weißschuh 	if (read(fileno(stream), &ch, 1) <= 0)
10899b037cbSWilly Tarreau 		return EOF;
10999b037cbSWilly Tarreau 	return ch;
11099b037cbSWilly Tarreau }
11199b037cbSWilly Tarreau 
1124e383a66SWilly Tarreau static __attribute__((unused))
getchar(void)1134e383a66SWilly Tarreau int getchar(void)
1144e383a66SWilly Tarreau {
11599b037cbSWilly Tarreau 	return fgetc(stdin);
11699b037cbSWilly Tarreau }
1174e383a66SWilly Tarreau 
11899b037cbSWilly Tarreau 
11999b037cbSWilly Tarreau /* putc(), fputc(), putchar() */
12099b037cbSWilly Tarreau 
12199b037cbSWilly Tarreau #define putc(c, stream) fputc(c, stream)
12299b037cbSWilly Tarreau 
12399b037cbSWilly Tarreau static __attribute__((unused))
fputc(int c,FILE * stream)12499b037cbSWilly Tarreau int fputc(int c, FILE* stream)
12599b037cbSWilly Tarreau {
12699b037cbSWilly Tarreau 	unsigned char ch = c;
12799b037cbSWilly Tarreau 
1285df28c15SThomas Weißschuh 	if (write(fileno(stream), &ch, 1) <= 0)
1294e383a66SWilly Tarreau 		return EOF;
1304e383a66SWilly Tarreau 	return ch;
1314e383a66SWilly Tarreau }
1324e383a66SWilly Tarreau 
1334e383a66SWilly Tarreau static __attribute__((unused))
putchar(int c)1344e383a66SWilly Tarreau int putchar(int c)
1354e383a66SWilly Tarreau {
13699b037cbSWilly Tarreau 	return fputc(c, stdout);
1374e383a66SWilly Tarreau }
1384e383a66SWilly Tarreau 
13999b037cbSWilly Tarreau 
140e3e19052SWilly Tarreau /* fwrite(), puts(), fputs(). Note that puts() emits '\n' but not fputs(). */
14199b037cbSWilly Tarreau 
142e3e19052SWilly Tarreau /* internal fwrite()-like function which only takes a size and returns 0 on
143e3e19052SWilly Tarreau  * success or EOF on error. It automatically retries on short writes.
144e3e19052SWilly Tarreau  */
1454e383a66SWilly Tarreau static __attribute__((unused))
_fwrite(const void * buf,size_t size,FILE * stream)146e3e19052SWilly Tarreau int _fwrite(const void *buf, size_t size, FILE *stream)
1474e383a66SWilly Tarreau {
1484e383a66SWilly Tarreau 	ssize_t ret;
1495df28c15SThomas Weißschuh 	int fd = fileno(stream);
1504e383a66SWilly Tarreau 
151e3e19052SWilly Tarreau 	while (size) {
152e3e19052SWilly Tarreau 		ret = write(fd, buf, size);
1534e383a66SWilly Tarreau 		if (ret <= 0)
1544e383a66SWilly Tarreau 			return EOF;
155e3e19052SWilly Tarreau 		size -= ret;
156e3e19052SWilly Tarreau 		buf += ret;
1574e383a66SWilly Tarreau 	}
15899b037cbSWilly Tarreau 	return 0;
15999b037cbSWilly Tarreau }
16099b037cbSWilly Tarreau 
16199b037cbSWilly Tarreau static __attribute__((unused))
fwrite(const void * s,size_t size,size_t nmemb,FILE * stream)162e3e19052SWilly Tarreau size_t fwrite(const void *s, size_t size, size_t nmemb, FILE *stream)
163e3e19052SWilly Tarreau {
164e3e19052SWilly Tarreau 	size_t written;
165e3e19052SWilly Tarreau 
166e3e19052SWilly Tarreau 	for (written = 0; written < nmemb; written++) {
167e3e19052SWilly Tarreau 		if (_fwrite(s, size, stream) != 0)
168e3e19052SWilly Tarreau 			break;
169e3e19052SWilly Tarreau 		s += size;
170e3e19052SWilly Tarreau 	}
171e3e19052SWilly Tarreau 	return written;
172e3e19052SWilly Tarreau }
173e3e19052SWilly Tarreau 
174e3e19052SWilly Tarreau static __attribute__((unused))
fputs(const char * s,FILE * stream)175e3e19052SWilly Tarreau int fputs(const char *s, FILE *stream)
176e3e19052SWilly Tarreau {
177e3e19052SWilly Tarreau 	return _fwrite(s, strlen(s), stream);
178e3e19052SWilly Tarreau }
179e3e19052SWilly Tarreau 
180e3e19052SWilly Tarreau static __attribute__((unused))
puts(const char * s)18199b037cbSWilly Tarreau int puts(const char *s)
18299b037cbSWilly Tarreau {
18399b037cbSWilly Tarreau 	if (fputs(s, stdout) == EOF)
18499b037cbSWilly Tarreau 		return EOF;
1854e383a66SWilly Tarreau 	return putchar('\n');
1864e383a66SWilly Tarreau }
1874e383a66SWilly Tarreau 
18899b037cbSWilly Tarreau 
18999b037cbSWilly Tarreau /* fgets() */
19099b037cbSWilly Tarreau static __attribute__((unused))
fgets(char * s,int size,FILE * stream)19199b037cbSWilly Tarreau char *fgets(char *s, int size, FILE *stream)
19299b037cbSWilly Tarreau {
19399b037cbSWilly Tarreau 	int ofs;
19499b037cbSWilly Tarreau 	int c;
19599b037cbSWilly Tarreau 
19699b037cbSWilly Tarreau 	for (ofs = 0; ofs + 1 < size;) {
19799b037cbSWilly Tarreau 		c = fgetc(stream);
19899b037cbSWilly Tarreau 		if (c == EOF)
19999b037cbSWilly Tarreau 			break;
20099b037cbSWilly Tarreau 		s[ofs++] = c;
20199b037cbSWilly Tarreau 		if (c == '\n')
20299b037cbSWilly Tarreau 			break;
20399b037cbSWilly Tarreau 	}
20499b037cbSWilly Tarreau 	if (ofs < size)
20599b037cbSWilly Tarreau 		s[ofs] = 0;
20699b037cbSWilly Tarreau 	return ofs ? s : NULL;
20799b037cbSWilly Tarreau }
20899b037cbSWilly Tarreau 
2097e4346f4SWilly Tarreau 
2107e4346f4SWilly Tarreau /* minimal vfprintf(). It supports the following formats:
211bd845a19SWilly Tarreau  *  - %[l*]{d,u,c,x,p}
2127e4346f4SWilly Tarreau  *  - %s
2137e4346f4SWilly Tarreau  *  - unknown modifiers are ignored.
2147e4346f4SWilly Tarreau  */
215dece8476SThomas Weißschuh static __attribute__((unused, format(printf, 2, 0)))
vfprintf(FILE * stream,const char * fmt,va_list args)2167e4346f4SWilly Tarreau int vfprintf(FILE *stream, const char *fmt, va_list args)
2177e4346f4SWilly Tarreau {
2187e4346f4SWilly Tarreau 	char escape, lpref, c;
2197e4346f4SWilly Tarreau 	unsigned long long v;
2207e4346f4SWilly Tarreau 	unsigned int written;
2217e4346f4SWilly Tarreau 	size_t len, ofs;
2227e4346f4SWilly Tarreau 	char tmpbuf[21];
2237e4346f4SWilly Tarreau 	const char *outstr;
2247e4346f4SWilly Tarreau 
2257e4346f4SWilly Tarreau 	written = ofs = escape = lpref = 0;
2267e4346f4SWilly Tarreau 	while (1) {
2277e4346f4SWilly Tarreau 		c = fmt[ofs++];
2287e4346f4SWilly Tarreau 
2297e4346f4SWilly Tarreau 		if (escape) {
2307e4346f4SWilly Tarreau 			/* we're in an escape sequence, ofs == 1 */
2317e4346f4SWilly Tarreau 			escape = 0;
232bd845a19SWilly Tarreau 			if (c == 'c' || c == 'd' || c == 'u' || c == 'x' || c == 'p') {
233bd845a19SWilly Tarreau 				char *out = tmpbuf;
234bd845a19SWilly Tarreau 
235bd845a19SWilly Tarreau 				if (c == 'p')
236bd845a19SWilly Tarreau 					v = va_arg(args, unsigned long);
237bd845a19SWilly Tarreau 				else if (lpref) {
2387e4346f4SWilly Tarreau 					if (lpref > 1)
2397e4346f4SWilly Tarreau 						v = va_arg(args, unsigned long long);
2407e4346f4SWilly Tarreau 					else
2417e4346f4SWilly Tarreau 						v = va_arg(args, unsigned long);
2427e4346f4SWilly Tarreau 				} else
2437e4346f4SWilly Tarreau 					v = va_arg(args, unsigned int);
2447e4346f4SWilly Tarreau 
2457e4346f4SWilly Tarreau 				if (c == 'd') {
2467e4346f4SWilly Tarreau 					/* sign-extend the value */
2477e4346f4SWilly Tarreau 					if (lpref == 0)
2487e4346f4SWilly Tarreau 						v = (long long)(int)v;
2497e4346f4SWilly Tarreau 					else if (lpref == 1)
2507e4346f4SWilly Tarreau 						v = (long long)(long)v;
2517e4346f4SWilly Tarreau 				}
2527e4346f4SWilly Tarreau 
2537e4346f4SWilly Tarreau 				switch (c) {
254bd845a19SWilly Tarreau 				case 'c':
255bd845a19SWilly Tarreau 					out[0] = v;
256bd845a19SWilly Tarreau 					out[1] = 0;
257bd845a19SWilly Tarreau 					break;
2587e4346f4SWilly Tarreau 				case 'd':
259bd845a19SWilly Tarreau 					i64toa_r(v, out);
2607e4346f4SWilly Tarreau 					break;
2617e4346f4SWilly Tarreau 				case 'u':
262bd845a19SWilly Tarreau 					u64toa_r(v, out);
2637e4346f4SWilly Tarreau 					break;
264bd845a19SWilly Tarreau 				case 'p':
265bd845a19SWilly Tarreau 					*(out++) = '0';
266bd845a19SWilly Tarreau 					*(out++) = 'x';
267bd845a19SWilly Tarreau 					/* fall through */
268bd845a19SWilly Tarreau 				default: /* 'x' and 'p' above */
269bd845a19SWilly Tarreau 					u64toh_r(v, out);
2707e4346f4SWilly Tarreau 					break;
2717e4346f4SWilly Tarreau 				}
2727e4346f4SWilly Tarreau 				outstr = tmpbuf;
2737e4346f4SWilly Tarreau 			}
2747e4346f4SWilly Tarreau 			else if (c == 's') {
2757e4346f4SWilly Tarreau 				outstr = va_arg(args, char *);
276170b230dSWilly Tarreau 				if (!outstr)
277170b230dSWilly Tarreau 					outstr="(null)";
2787e4346f4SWilly Tarreau 			}
2797e4346f4SWilly Tarreau 			else if (c == '%') {
2807e4346f4SWilly Tarreau 				/* queue it verbatim */
2817e4346f4SWilly Tarreau 				continue;
2827e4346f4SWilly Tarreau 			}
2837e4346f4SWilly Tarreau 			else {
2847e4346f4SWilly Tarreau 				/* modifiers or final 0 */
2857e4346f4SWilly Tarreau 				if (c == 'l') {
2867e4346f4SWilly Tarreau 					/* long format prefix, maintain the escape */
2877e4346f4SWilly Tarreau 					lpref++;
2887e4346f4SWilly Tarreau 				}
2897e4346f4SWilly Tarreau 				escape = 1;
2907e4346f4SWilly Tarreau 				goto do_escape;
2917e4346f4SWilly Tarreau 			}
2927e4346f4SWilly Tarreau 			len = strlen(outstr);
2937e4346f4SWilly Tarreau 			goto flush_str;
2947e4346f4SWilly Tarreau 		}
2957e4346f4SWilly Tarreau 
2967e4346f4SWilly Tarreau 		/* not an escape sequence */
2977e4346f4SWilly Tarreau 		if (c == 0 || c == '%') {
2987e4346f4SWilly Tarreau 			/* flush pending data on escape or end */
2997e4346f4SWilly Tarreau 			escape = 1;
3007e4346f4SWilly Tarreau 			lpref = 0;
3017e4346f4SWilly Tarreau 			outstr = fmt;
3027e4346f4SWilly Tarreau 			len = ofs - 1;
3037e4346f4SWilly Tarreau 		flush_str:
3047e4346f4SWilly Tarreau 			if (_fwrite(outstr, len, stream) != 0)
3057e4346f4SWilly Tarreau 				break;
3067e4346f4SWilly Tarreau 
3077e4346f4SWilly Tarreau 			written += len;
3087e4346f4SWilly Tarreau 		do_escape:
3097e4346f4SWilly Tarreau 			if (c == 0)
3107e4346f4SWilly Tarreau 				break;
3117e4346f4SWilly Tarreau 			fmt += ofs;
3127e4346f4SWilly Tarreau 			ofs = 0;
3137e4346f4SWilly Tarreau 			continue;
3147e4346f4SWilly Tarreau 		}
3157e4346f4SWilly Tarreau 
3167e4346f4SWilly Tarreau 		/* literal char, just queue it */
3177e4346f4SWilly Tarreau 	}
3187e4346f4SWilly Tarreau 	return written;
3197e4346f4SWilly Tarreau }
3207e4346f4SWilly Tarreau 
321dece8476SThomas Weißschuh static __attribute__((unused, format(printf, 1, 0)))
vprintf(const char * fmt,va_list args)322322759f9SMark Brown int vprintf(const char *fmt, va_list args)
323322759f9SMark Brown {
324322759f9SMark Brown 	return vfprintf(stdout, fmt, args);
325322759f9SMark Brown }
326322759f9SMark Brown 
3274f2c9703SAlviro Iskandar Setiawan static __attribute__((unused, format(printf, 2, 3)))
fprintf(FILE * stream,const char * fmt,...)3287e4346f4SWilly Tarreau int fprintf(FILE *stream, const char *fmt, ...)
3297e4346f4SWilly Tarreau {
3307e4346f4SWilly Tarreau 	va_list args;
3317e4346f4SWilly Tarreau 	int ret;
3327e4346f4SWilly Tarreau 
3337e4346f4SWilly Tarreau 	va_start(args, fmt);
3347e4346f4SWilly Tarreau 	ret = vfprintf(stream, fmt, args);
3357e4346f4SWilly Tarreau 	va_end(args);
3367e4346f4SWilly Tarreau 	return ret;
3377e4346f4SWilly Tarreau }
3387e4346f4SWilly Tarreau 
3394f2c9703SAlviro Iskandar Setiawan static __attribute__((unused, format(printf, 1, 2)))
printf(const char * fmt,...)3407e4346f4SWilly Tarreau int printf(const char *fmt, ...)
3417e4346f4SWilly Tarreau {
3427e4346f4SWilly Tarreau 	va_list args;
3437e4346f4SWilly Tarreau 	int ret;
3447e4346f4SWilly Tarreau 
3457e4346f4SWilly Tarreau 	va_start(args, fmt);
3467e4346f4SWilly Tarreau 	ret = vfprintf(stdout, fmt, args);
3477e4346f4SWilly Tarreau 	va_end(args);
3487e4346f4SWilly Tarreau 	return ret;
3497e4346f4SWilly Tarreau }
3507e4346f4SWilly Tarreau 
351acab7bcdSWilly Tarreau static __attribute__((unused))
perror(const char * msg)352acab7bcdSWilly Tarreau void perror(const char *msg)
353acab7bcdSWilly Tarreau {
354acab7bcdSWilly Tarreau 	fprintf(stderr, "%s%serrno=%d\n", (msg && *msg) ? msg : "", (msg && *msg) ? ": " : "", errno);
355acab7bcdSWilly Tarreau }
356acab7bcdSWilly Tarreau 
3574893c22eSRyan Roberts static __attribute__((unused))
setvbuf(FILE * stream,char * buf,int mode,size_t size)358809145f8SThomas Weißschuh int setvbuf(FILE *stream __attribute__((unused)),
359809145f8SThomas Weißschuh 	    char *buf __attribute__((unused)),
360809145f8SThomas Weißschuh 	    int mode,
361809145f8SThomas Weißschuh 	    size_t size __attribute__((unused)))
3624893c22eSRyan Roberts {
3634893c22eSRyan Roberts 	/*
3644893c22eSRyan Roberts 	 * nolibc does not support buffering so this is a nop. Just check mode
3654893c22eSRyan Roberts 	 * is valid as required by the spec.
3664893c22eSRyan Roberts 	 */
3674893c22eSRyan Roberts 	switch (mode) {
3684893c22eSRyan Roberts 	case _IOFBF:
3694893c22eSRyan Roberts 	case _IOLBF:
3704893c22eSRyan Roberts 	case _IONBF:
3714893c22eSRyan Roberts 		break;
3724893c22eSRyan Roberts 	default:
3734893c22eSRyan Roberts 		return EOF;
3744893c22eSRyan Roberts 	}
3754893c22eSRyan Roberts 
3764893c22eSRyan Roberts 	return 0;
3774893c22eSRyan Roberts }
3784893c22eSRyan Roberts 
379*d20d0b10SThomas Weißschuh static __attribute__((unused))
strerror(int errno)380*d20d0b10SThomas Weißschuh const char *strerror(int errno)
381*d20d0b10SThomas Weißschuh {
382*d20d0b10SThomas Weißschuh 	static char buf[18] = "errno=";
383*d20d0b10SThomas Weißschuh 
384*d20d0b10SThomas Weißschuh 	i64toa_r(errno, &buf[6]);
385*d20d0b10SThomas Weißschuh 
386*d20d0b10SThomas Weißschuh 	return buf;
387*d20d0b10SThomas Weißschuh }
388*d20d0b10SThomas Weißschuh 
38955abdd1fSWilly Tarreau /* make sure to include all global symbols */
39055abdd1fSWilly Tarreau #include "nolibc.h"
39155abdd1fSWilly Tarreau 
3924e383a66SWilly Tarreau #endif /* _NOLIBC_STDIO_H */
393