1 /* Copyright (c) 2002, 2005, 2007 Joerg Wunsch
2    All rights reserved.
3 
4    Portions of documentation Copyright (c) 1990, 1991, 1993
5    The Regents of the University of California.
6 
7    All rights reserved.
8 
9    Redistribution and use in source and binary forms, with or without
10    modification, are permitted provided that the following conditions are met:
11 
12    * Redistributions of source code must retain the above copyright
13      notice, this list of conditions and the following disclaimer.
14 
15    * Redistributions in binary form must reproduce the above copyright
16      notice, this list of conditions and the following disclaimer in
17      the documentation and/or other materials provided with the
18      distribution.
19 
20    * Neither the name of the copyright holders nor the names of
21      contributors may be used to endorse or promote products derived
22      from this software without specific prior written permission.
23 
24   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34   POSSIBILITY OF SUCH DAMAGE.
35 
36   $Id: stdio.h 2527 2016-10-27 20:41:22Z joerg_wunsch $
37 */
38 
39 #ifndef _STDIO_H_
40 #define	_STDIO_H_ 1
41 
42 #include <sys/cdefs.h>
43 #define __need_NULL
44 #define __need_size_t
45 #include <stddef.h>
46 #define __need___va_list
47 #include <stdarg.h>
48 #include <sys/_types.h>
49 
50 _BEGIN_STD_C
51 
52 /*
53  * This is an internal structure of the library that is subject to be
54  * changed without warnings at any time.  Please do *never* reference
55  * elements of it beyond by using the official interfaces provided.
56  */
57 
58 #ifdef ATOMIC_UNGETC
59 #if defined(__riscv) || defined(__MICROBLAZE__)
60 /*
61  * Use 32-bit ungetc storage when doing atomic ungetc on RISC-V and
62  * MicroBlaze, which have 4-byte swap intrinsics but not 2-byte swap
63  * intrinsics. This increases the size of the __file struct by four
64  * bytes.
65  */
66 #define __PICOLIBC_UNGETC_SIZE	4
67 #endif
68 #endif
69 
70 #ifndef __PICOLIBC_UNGETC_SIZE
71 #define __PICOLIBC_UNGETC_SIZE	2
72 #endif
73 
74 #if __PICOLIBC_UNGETC_SIZE == 4
75 typedef __uint32_t __ungetc_t;
76 #endif
77 
78 #if __PICOLIBC_UNGETC_SIZE == 2
79 typedef __uint16_t __ungetc_t;
80 #endif
81 
82 struct __file {
83 	__ungetc_t unget;	/* ungetc() buffer */
84 	__uint8_t  flags;	/* flags, see below */
85 #define __SRD	0x0001		/* OK to read */
86 #define __SWR	0x0002		/* OK to write */
87 #define __SERR	0x0004		/* found error */
88 #define __SEOF	0x0008		/* found EOF */
89 #define __SCLOSE 0x0010		/* struct is __file_close */
90 #define __SEXT  0x0020          /* struct is __file_ext */
91 #define __SBUF  0x0040          /* struct is __file_bufio */
92 #define __SWIDE 0x0080          /* wchar output mode */
93 	int	(*put)(char, struct __file *);	/* function to write one char to device */
94 	int	(*get)(struct __file *);	/* function to read one char from device */
95 	int	(*flush)(struct __file *);	/* function to flush output to device */
96 };
97 
98 /*
99  * This variant includes a 'close' function which is
100  * invoked from fclose when the __SCLOSE bit is set
101  */
102 struct __file_close {
103 	struct __file file;			/* main file struct */
104 	int	(*close)(struct __file *);	/* function to close file */
105 };
106 
107 #define FDEV_SETUP_CLOSE(put, get, flush, _close, rwflag) \
108         {                                                               \
109                 .file = FDEV_SETUP_STREAM(put, get, flush, (rwflag) | __SCLOSE),   \
110                 .close = (_close),                                      \
111         }
112 
113 struct __file_ext {
114         struct __file_close cfile;              /* close file struct */
115         __off_t (*seek)(struct __file *, __off_t offset, int whence);
116         int     (*setvbuf)(struct __file *, char *buf, int mode, size_t size);
117 };
118 
119 #define FDEV_SETUP_EXT(put, get, flush, close, _seek, _setvbuf, rwflag) \
120         {                                                               \
121                 .cfile = FDEV_SETUP_CLOSE(put, get, flush, close, (rwflag) | __SEXT), \
122                 .seek = (_seek),                                        \
123                 .setvbuf = (_setvbuf),                                  \
124         }
125 
126 /*@{*/
127 /**
128    \c FILE is the opaque structure that is passed around between the
129    various standard IO functions.
130 */
131 #ifndef ___FILE_DECLARED
132 typedef struct __file __FILE;
133 # define __FILE_DECLARED
134 #endif
135 
136 #ifndef _FILE_DECLARED
137 typedef __FILE FILE;
138 #define _FILE_DECLARED
139 #endif
140 
141 /**
142    This symbol is defined when stdin/stdout/stderr are global
143    variables. When undefined, the old __iob array is used which
144    contains the pointers instead
145 */
146 #define PICOLIBC_STDIO_GLOBALS
147 
148 extern FILE *const stdin;
149 extern FILE *const stdout;
150 extern FILE *const stderr;
151 
152 /* The stdin, stdout, and stderr symbols are described as macros in the C
153  * standard. */
154 #define stdin stdin
155 #define stdout stdout
156 #define stderr stderr
157 
158 #define EOF	(-1)
159 
160 #define	_IOFBF	0		/* setvbuf should set fully buffered */
161 #define	_IOLBF	1		/* setvbuf should set line buffered */
162 #define	_IONBF	2		/* setvbuf should set unbuffered */
163 
164 #define fdev_setup_stream(stream, p, g, fl, f)	\
165 	do { \
166 		(stream)->flags = f; \
167 		(stream)->put = p; \
168 		(stream)->get = g; \
169 		(stream)->flush = fl; \
170 	} while(0)
171 
172 #define _FDEV_SETUP_READ  __SRD	/**< fdev_setup_stream() with read intent */
173 #define _FDEV_SETUP_WRITE __SWR	/**< fdev_setup_stream() with write intent */
174 #define _FDEV_SETUP_RW    (__SRD|__SWR)	/**< fdev_setup_stream() with read/write intent */
175 
176 /**
177  * Return code for an error condition during device read.
178  *
179  * To be used in the get function of fdevopen().
180  */
181 #define _FDEV_ERR (-1)
182 
183 /**
184  * Return code for an end-of-file condition during device read.
185  *
186  * To be used in the get function of fdevopen().
187  */
188 #define _FDEV_EOF (-2)
189 
190 #define FDEV_SETUP_STREAM(p, g, fl, f)		\
191 	{ \
192                 .flags = (f),                   \
193                 .put = (p),                     \
194                 .get = (g),                     \
195                 .flush = (fl),                  \
196 	}
197 
198 FILE *fdevopen(int (*__put)(char, FILE*), int (*__get)(FILE*), int(*__flush)(FILE *));
199 int	fclose(FILE *__stream);
200 int	fflush(FILE *stream);
201 
202 # define fdev_close(f) (fflush(f))
203 
204 #ifdef _HAVE_FORMAT_ATTRIBUTE
205 #ifdef PICOLIBC_FLOAT_PRINTF_SCANF
206 #pragma GCC diagnostic ignored "-Wformat"
207 #define __FORMAT_ATTRIBUTE__(__a, __s, __f) __attribute__((__format__ (__a, __s, 0)))
208 #else
209 #define __FORMAT_ATTRIBUTE__(__a, __s, __f) __attribute__((__format__ (__a, __s, __f)))
210 #endif
211 #else
212 #define __FORMAT_ATTRIBUTE__(__a, __s, __f)
213 #endif
214 
215 #define __PRINTF_ATTRIBUTE__(__s, __f) __FORMAT_ATTRIBUTE__(printf, __s, __f)
216 #define __SCANF_ATTRIBUTE__(__s, _f) __FORMAT_ATTRIBUTE__(scanf, __s, __f)
217 
218 int	fputc(int __c, FILE *__stream);
219 int	putc(int __c, FILE *__stream);
220 int	putchar(int __c);
221 #define putc(__c, __stream) fputc(__c, __stream)
222 #define putchar(__c) fputc(__c, stdout)
223 
224 int	printf(const char *__fmt, ...) __PRINTF_ATTRIBUTE__(1, 2);
225 int	fprintf(FILE *__stream, const char *__fmt, ...) __PRINTF_ATTRIBUTE__(2, 3);
226 int	vprintf(const char *__fmt, __gnuc_va_list __ap) __PRINTF_ATTRIBUTE__(1, 0);
227 int	vfprintf(FILE *__stream, const char *__fmt, __gnuc_va_list __ap) __PRINTF_ATTRIBUTE__(2, 0);
228 int	sprintf(char *__s, const char *__fmt, ...) __PRINTF_ATTRIBUTE__(2, 3);
229 int	snprintf(char *__s, size_t __n, const char *__fmt, ...) __PRINTF_ATTRIBUTE__(3, 4);
230 int	vsprintf(char *__s, const char *__fmt, __gnuc_va_list ap) __PRINTF_ATTRIBUTE__(2, 0);
231 int	vsnprintf(char *__s, size_t __n, const char *__fmt, __gnuc_va_list ap) __PRINTF_ATTRIBUTE__(3, 0);
232 int     asprintf(char **strp, const char *fmt, ...) __PRINTF_ATTRIBUTE__(2,3);
233 int     vasprintf(char **strp, const char *fmt, __gnuc_va_list ap) __PRINTF_ATTRIBUTE__(2,0);
234 
235 int	fputs(const char *__str, FILE *__stream);
236 int	puts(const char *__str);
237 size_t	fwrite(const void *__ptr, size_t __size, size_t __nmemb,
238 		       FILE *__stream);
239 
240 int	fgetc(FILE *__stream);
241 int	getc(FILE *__stream);
242 int	getchar(void);
243 #define getc(__stream) fgetc(__stream)
244 #define getchar() fgetc(stdin)
245 int	ungetc(int __c, FILE *__stream);
246 
247 int	scanf(const char *__fmt, ...) __FORMAT_ATTRIBUTE__(scanf, 1, 2);
248 int	fscanf(FILE *__stream, const char *__fmt, ...) __FORMAT_ATTRIBUTE__(scanf, 2, 3);
249 int	vscanf(const char *__fmt, __gnuc_va_list __ap) __FORMAT_ATTRIBUTE__(scanf, 1, 0);
250 int	vfscanf(FILE *__stream, const char *__fmt, __gnuc_va_list __ap) __FORMAT_ATTRIBUTE__(scanf, 2, 0);
251 int	sscanf(const char *__buf, const char *__fmt, ...) __FORMAT_ATTRIBUTE__(scanf, 2, 3);
252 int	vsscanf(const char *__buf, const char *__fmt, __gnuc_va_list ap) __FORMAT_ATTRIBUTE__(scanf, 2, 0);
253 
254 char	*fgets(char *__str, int __size, FILE *__stream);
255 char	*gets(char *__str);
256 size_t	fread(void *__ptr, size_t __size, size_t __nmemb,
257 		      FILE *__stream);
258 
259 void	clearerr(FILE *__stream);
260 
261 /* fast inlined version of clearerr() */
262 #define clearerr(s) ((s)->flags &= ~(__SERR | __SEOF))
263 
264 int	feof(FILE *__stream);
265 
266 /* fast inlined version of feof() */
267 #define feof(s) ((s)->flags & __SEOF)
268 
269 int	ferror(FILE *__stream);
270 
271 /* fast inlined version of ferror() */
272 #define ferror(s) ((s)->flags & __SERR)
273 
274 #ifndef SEEK_SET
275 #define	SEEK_SET	0	/* set file offset to offset */
276 #endif
277 #ifndef SEEK_CUR
278 #define	SEEK_CUR	1	/* set file offset to current plus offset */
279 #endif
280 #ifndef SEEK_END
281 #define	SEEK_END	2	/* set file offset to EOF plus offset */
282 #endif
283 
284 /* only mentioned for libstdc++ support, not implemented in library */
285 #ifndef BUFSIZ
286 #define BUFSIZ 512
287 #endif
288 
289 /*
290  * We don't have any way of knowing any underlying POSIX limits,
291  * so just use a reasonably small values here
292  */
293 #ifndef FOPEN_MAX
294 #define FOPEN_MAX 32
295 #endif
296 #ifndef FILENAME_MAX
297 #define FILENAME_MAX 1024
298 #endif
299 
300 /*
301  * Declare required C types
302  *
303  * size_t comes from stddef.h (included from cdefs.h)
304  */
305 typedef _fpos_t fpos_t;
306 
307 #if __POSIX_VISIBLE
308 /*
309  * Declare required additional POSIX types.
310  */
311 
312 # ifndef _OFF_T_DECLARED
313 typedef	__off_t		off_t;		/* file offset */
314 #  define _OFF_T_DECLARED
315 # endif
316 
317 # ifndef _SSIZE_T_DECLARED
318 typedef _ssize_t ssize_t;
319 #  define _SSIZE_T_DECLARED
320 # endif
321 
322 /* This needs to agree with <stdarg.h> */
323 # ifdef __GNUC__
324 #  ifndef _VA_LIST_DEFINED
325 typedef __gnuc_va_list va_list;
326 #   define _VA_LIST_DEFINED
327 #  endif
328 # else
329 #  include <stdarg.h>
330 # endif
331 
332 #endif
333 
334 int fgetpos(FILE * __restrict stream, fpos_t * __restrict pos);
335 FILE *fopen(const char *path, const char *mode) __malloc_like_with_free(fclose, 1);
336 FILE *freopen(const char *path, const char *mode, FILE *stream);
337 FILE *fdopen(int, const char *) __malloc_like_with_free(fclose, 1);
338 FILE *fmemopen(void *buf, size_t size, const char *mode) __malloc_like_with_free(fclose, 1);
339 int fseek(FILE *stream, long offset, int whence);
340 int fseeko(FILE *stream, __off_t offset, int whence);
341 int fsetpos(FILE *stream, const fpos_t *pos);
342 long ftell(FILE *stream);
343 __off_t ftello(FILE *stream);
344 int fileno(FILE *);
345 void perror(const char *s);
346 int remove(const char *pathname);
347 int rename(const char *oldpath, const char *newpath);
348 void rewind(FILE *stream);
349 void setbuf(FILE *stream, char *buf);
350 void setbuffer(FILE *stream, char *buf, size_t size);
351 void setlinebuf(FILE *stream);
352 int setvbuf(FILE *stream, char *buf, int mode, size_t size);
353 FILE *tmpfile(void);
354 char *tmpnam (char *s);
355 _ssize_t getline(char **__restrict lineptr, size_t *__restrict n, FILE *__restrict stream);
356 _ssize_t getdelim(char **__restrict lineptr, size_t *__restrict  n, int delim, FILE *__restrict stream);
357 
358 #if __BSD_VISIBLE
359 FILE	*funopen (const void *cookie,
360 		_ssize_t (*readfn)(void *cookie, void *buf,
361 				size_t n),
362 		_ssize_t (*writefn)(void *cookie, const void *buf,
363 				 size_t n),
364 		__off_t (*seekfn)(void *cookie, __off_t off, int whence),
365 		int (*closefn)(void *cookie));
366 # define	fropen(__cookie, __fn) funopen(__cookie, __fn, NULL, NULL, NULL)
367 # define	fwopen(__cookie, __fn) funopen(__cookie, NULL, __fn, NULL, NULL)
368 #endif /*__BSD_VISIBLE */
369 
370 #if __POSIX_VISIBLE >= 199309L
371 int	getc_unlocked (FILE *);
372 int	getchar_unlocked (void);
373 void	flockfile (FILE *);
374 int	ftrylockfile (FILE *);
375 void	funlockfile (FILE *);
376 int	putc_unlocked (int, FILE *);
377 int	putchar_unlocked (int);
378 #define getc_unlocked(f) fgetc(f)
379 #define getchar_unlocked(f) fgetc(stdin)
380 #define putc_unlocked(c, f) fputc(c, f)
381 #define putchar_unlocked(c, f) fgetc(c, stdin)
382 #endif
383 
384 #if __STDC_WANT_LIB_EXT1__ == 1
385 #include <sys/_types.h>
386 
387 #ifndef _ERRNO_T_DEFINED
388 typedef __errno_t errno_t;
389 #define _ERRNO_T_DEFINED
390 #endif
391 
392 #ifndef _RSIZE_T_DEFINED
393 typedef __rsize_t rsize_t;
394 #define _RSIZE_T_DEFINED
395 #endif
396 
397 int sprintf_s(char *__restrict __s, rsize_t __bufsize,
398               const char *__restrict __format, ...);
399 #endif
400 
401 /*
402  * The format of tmpnam names is TXXXXXX, which works with mktemp
403  */
404 #define L_tmpnam        8
405 
406 /*
407  * tmpnam files are created in the current directory
408  */
409 #define P_tmpdir        ""
410 
411 /*
412  * We don't have any way of knowing any underlying POSIX limits,
413  * so just use a reasonably small value here
414  */
415 #ifndef TMP_MAX
416 #define TMP_MAX         32
417 #endif
418 
419 /*@}*/
420 
421 static __inline __uint32_t
__printf_float(float f)422 __printf_float(float f)
423 {
424 	union {
425 		float		f;
426 		__uint32_t	u;
427 	} u = { .f = f };
428 	return u.u;
429 }
430 
431 #if !defined(PICOLIBC_DOUBLE_PRINTF_SCANF) && \
432     !defined(PICOLIBC_FLOAT_PRINTF_SCANF) && \
433     !defined(PICOLIBC_LONG_LONG_PRINTF_SCANF) && \
434     !defined(PICOLIBC_INTEGER_PRINTF_SCANF) && \
435     !defined(PICOLIBC_MINIMAL_PRINTF_SCANF)
436 #if defined(_FORMAT_DEFAULT_FLOAT)
437 #define PICOLIBC_FLOAT_PRINTF_SCANF
438 #elif defined(_FORMAT_DEFAULT_LONG_LONG)
439 #define PICOLIBC_LONG_LONG_PRINTF_SCANF
440 #elif defined(_FORMAT_DEFAULT_INTEGER)
441 #define PICOLIBC_INTEGER_PRINTF_SCANF
442 #elif defined(_FORMAT_DEFAULT_MINIMAL)
443 #define PICOLIBC_MINIMAL_PRINTF_SCANF
444 #else
445 #define PICOLIBC_DOUBLE_PRINTF_SCANF
446 #endif
447 #endif
448 
449 #if defined(PICOLIBC_MINIMAL_PRINTF_SCANF)
450 # define printf_float(x) ((double) (x))
451 # if defined(_WANT_MINIMAL_IO_LONG_LONG) || __SIZEOF_LONG_LONG__ == __SIZEOF_LONG__
452 #  define _HAS_IO_LONG_LONG
453 # endif
454 # ifdef _WANT_IO_C99_FORMATS
455 #  define _HAS_IO_C99_FORMATS
456 # endif
457 #elif defined(PICOLIBC_INTEGER_PRINTF_SCANF)
458 # define printf_float(x) ((double) (x))
459 # if defined(_WANT_IO_LONG_LONG) || __SIZEOF_LONG_LONG__ == __SIZEOF_LONG__
460 #  define _HAS_IO_LONG_LONG
461 # endif
462 # ifdef _WANT_IO_POS_ARGS
463 #  define _HAS_IO_POS_ARGS
464 # endif
465 # ifdef _WANT_IO_C99_FORMATS
466 #  define _HAS_IO_C99_FORMATS
467 # endif
468 # ifdef _WANT_IO_PERCENT_B
469 #  define _HAS_IO_PERCENT_B
470 # endif
471 #elif defined(PICOLIBC_LONG_LONG_PRINTF_SCANF)
472 # define printf_float(x) ((double) (x))
473 # define _HAS_IO_LONG_LONG
474 # ifdef _WANT_IO_POS_ARGS
475 #  define _HAS_IO_POS_ARGS
476 # endif
477 # ifdef _WANT_IO_C99_FORMATS
478 #  define _HAS_IO_C99_FORMATS
479 # endif
480 # ifdef _WANT_IO_PERCENT_B
481 #  define _HAS_IO_PERCENT_B
482 # endif
483 #elif defined(PICOLIBC_FLOAT_PRINTF_SCANF)
484 # define printf_float(x) __printf_float(x)
485 # define _HAS_IO_LONG_LONG
486 # define _HAS_IO_POS_ARGS
487 # define _HAS_IO_C99_FORMATS
488 # ifdef _WANT_IO_PERCENT_B
489 #  define _HAS_IO_PERCENT_B
490 # endif
491 # define _HAS_IO_FLOAT
492 #else
493 # define printf_float(x) ((double) (x))
494 # define _HAS_IO_LONG_LONG
495 # define _HAS_IO_POS_ARGS
496 # define _HAS_IO_C99_FORMATS
497 # define _HAS_IO_DOUBLE
498 # if defined(_MB_CAPABLE) || defined(_WANT_IO_WCHAR)
499 #  define _HAS_IO_WCHAR
500 # endif
501 # ifdef _MB_CAPABLE
502 #  define _HAS_IO_MBCHAR
503 # endif
504 # ifdef _WANT_IO_PERCENT_B
505 #  define _HAS_IO_PERCENT_B
506 # endif
507 # ifdef _WANT_IO_LONG_DOUBLE
508 #  define _HAS_IO_LONG_DOUBLE
509 # endif
510 #endif
511 
512 _END_STD_C
513 
514 #if __SSP_FORTIFY_LEVEL > 0
515 #include <ssp/stdio.h>
516 #endif
517 
518 #endif /* _STDIO_H_ */
519