summaryrefslogtreecommitdiff
path: root/libc/sysdeps
diff options
context:
space:
mode:
authorManuel Novoa III <mjn3@codepoet.org>2002-03-12 01:18:50 +0000
committerManuel Novoa III <mjn3@codepoet.org>2002-03-12 01:18:50 +0000
commit03e039820dc5092e27e81f3671652f25da7f25f1 (patch)
tree37bddad6951b8a6aa5d75184353705f672217812 /libc/sysdeps
parentff3e48d94097ed02480bb0df538620b221ccd72f (diff)
Swap in the new stdio code.
Diffstat (limited to 'libc/sysdeps')
-rw-r--r--libc/sysdeps/linux/common/bits/uClibc_stdio.h494
1 files changed, 494 insertions, 0 deletions
diff --git a/libc/sysdeps/linux/common/bits/uClibc_stdio.h b/libc/sysdeps/linux/common/bits/uClibc_stdio.h
new file mode 100644
index 000000000..87d4b99ae
--- /dev/null
+++ b/libc/sysdeps/linux/common/bits/uClibc_stdio.h
@@ -0,0 +1,494 @@
+/* Copyright (C) 2002 Manuel Novoa III
+ * Header for my stdio library for linux and (soon) elks.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION!
+ *
+ * This code is currently under development. Also, I plan to port
+ * it to elks which is a 16-bit environment with a fairly limited
+ * compiler. Therefore, please refrain from modifying this code
+ * and, instead, pass any bug-fixes, etc. to me. Thanks. Manuel
+ *
+ * ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! */
+
+#ifndef _STDIO_H
+#error Always include <stdio.h> rather than <bits/uClibc_stdio.h>
+#endif
+
+/**********************************************************************/
+#ifdef __UCLIBC__
+
+#ifdef __UCLIBC_HAS_THREADS__
+#define __STDIO_THREADSAFE
+#endif
+
+#ifdef __UCLIBC_HAVE_LFS__
+#define __STDIO_LARGE_FILES
+#endif /* __UCLIBC_HAVE_LFS__ */
+
+/* Make sure defines related to large files are consistent. */
+#ifdef _LIBC
+
+#ifdef __UCLIBC_HAVE_LFS__
+#undef __USE_LARGEFILE
+#undef __USE_LARGEFILE64
+#undef __USE_FILE_OFFSET64
+/* if we're actually building uClibc with large file support, only define... */
+#define __USE_LARGEFILE64 1
+#endif /* __UCLIBC_HAVE_LFS__ */
+
+#else /* not _LIBC */
+
+#ifndef __UCLIBC_HAVE_LFS__
+#if defined(__LARGEFILE64_SOURCE) || defined(__USE_LARGEFILE64) \
+ || defined(__USE_FILE_OFFSET64)
+#error Sorry... uClibc was built without large file support!
+#endif
+#endif /* __UCLIBC_HAVE_LFS__ */
+
+#endif /* _LIBC */
+
+#endif /* __UCLIBC__ */
+/**********************************************************************/
+/* These are the stdio configuration options. Keep them here until
+ uClibc's configuration process gets reworked. */
+
+/* #define __STDIO_WIDE */
+#ifdef __STDIO_WIDE
+typedef int __wchar_t; /* TODO: temporary, as not currently uClibc */
+#endif
+
+#define __STDIO_BUFFERS
+#define __STDIO_GETC_MACRO
+#define __STDIO_PUTC_MACRO
+
+/* For uClibc, these are currently handled above. */
+/* #define __STDIO_LARGE_FILES */
+#define __STDIO_THREADSAFE
+
+/* L mode extension for fopen. */
+#define __STDIO_FOPEN_LARGEFILE_MODE
+
+/* size of builtin buf -- only tested with 0 */
+#define _STDIO_BUILTIN_BUF_SIZE 0
+
+/* TODO - enable features based on __STDIO_GLIBC_FEATURES */
+
+/* #define __STDIO_GLIBC_FEATURES */
+#define __STDIO_AUTO_RW_TRANSITION
+#define __STDIO_FOPEN_EXCLUSIVE_MODE
+#define __STDIO_PRINTF_M_SPEC
+#define __STDIO_GLIBC_CUSTOM_STREAMS
+
+
+/* ANSI/ISO mandate at least 256. */
+#define _STDIO_BUFSIZ 256
+
+/* Currently unimplemented/untested */
+/* #define __STDIO_FLEXIBLE_SETVBUF */
+
+/**********************************************************************/
+/* TODO -- posix or gnu -- belongs in limits.h and >= 9 for sus */
+/* NOTE: for us it is currently _always_ 9 */
+#define NL_ARGMAX 9
+
+/* TODO -- where should this go? */
+#ifndef O_LARGEFILE
+#define O_LARGEFILE 0100000
+#endif
+
+/**********************************************************************/
+
+/* These are consistency checks on the different options */
+
+#ifndef __STDIO_BUFFERS
+#undef __STDIO_GETC_MACRO
+#undef __STDIO_PUTC_MACRO
+#endif
+
+#ifdef __BCC__
+#undef __STDIO_LARGE_FILES
+#endif
+
+#ifndef __STDIO_LARGE_FILES
+#undef __STDIO_FOPEN_LARGEFILE_MODE
+#endif
+
+/**********************************************************************/
+
+#ifdef __STDIO_THREADSAFE
+/* Need this for pthread_mutex_t. */
+#include <bits/pthreadtypes.h>
+
+#define __STDIO_THREADLOCK(STREAM) \
+ if ((STREAM)->user_locking == 0) { \
+ pthread_mutex_lock(&(STREAM)->lock); \
+ }
+
+#define __STDIO_THREADUNLOCK(STREAM) \
+ if ((STREAM)->user_locking == 0) { \
+ pthread_mutex_unlock(&(STREAM)->lock); \
+ }
+
+#define __STDIO_THREADTRYLOCK(STREAM) \
+ if ((STREAM)->user_locking == 0) { \
+ pthread_mutex_trylock(&(STREAM)->lock); \
+ }
+
+#else /* __STDIO_THREADSAFE */
+
+#define __STDIO_THREADLOCK(STREAM)
+#define __STDIO_THREADUNLOCK(STREAM)
+#define __STDIO_THREADTRYLOCK(STREAM)
+
+#endif /* __STDIO_THREADSAFE */
+
+/* This file may eventually have two personalities:
+ 1) core stuff (similar to glibc's libio.h)
+ 2) extern inlines (for glibc's bits/stdio.h)
+ Right now, only (1) is implemented. */
+
+#define _STDIO_IOFBF 0 /* Fully buffered. */
+#define _STDIO_IOLBF 1 /* Line buffered. */
+#define _STDIO_IONBF 2 /* No buffering. */
+
+typedef struct {
+ __off_t __pos;
+/* __mbstate_t __state; */
+} __stdio_fpos_t;
+
+typedef struct {
+ __off64_t __pos;
+/* __mbstate_t __state; */
+} __stdio_fpos64_t;
+
+
+/**********************************************************************/
+#ifdef __STDIO_LARGE_FILES
+typedef __off64_t __offmax_t; /* TODO -- rename this? */
+#else
+typedef __off_t __offmax_t; /* TODO -- rename this? */
+#endif
+
+/**********************************************************************/
+
+#ifdef __STDIO_GLIBC_CUSTOM_STREAMS
+
+typedef __ssize_t __io_read_fn(void *cookie,
+ char *buf, size_t bufsize);
+typedef __ssize_t __io_write_fn(void *cookie,
+ const char *buf, size_t bufsize);
+/* NOTE: GLIBC difference!!! -- fopencookie seek function
+ * For glibc, the type of pos is always (__off64_t *) but in our case
+ * it is type (__off_t *) when the lib is built without large file support.
+ */
+typedef int __io_seek_fn(void *cookie,
+ __offmax_t *pos, int whence);
+typedef int __io_close_fn(void *cookie);
+
+typedef struct {
+ __io_read_fn *read;
+ __io_write_fn *write;
+ __io_seek_fn *seek;
+ __io_close_fn *close;
+} _IO_cookie_io_functions_t;
+
+#if defined(_LIBC) || defined(_GNU_SOURCE)
+typedef __io_read_fn cookie_read_function_t;
+typedef __io_write_fn cookie_write_function_t;
+typedef __io_seek_fn cookie_seek_function_t;
+typedef __io_close_fn cookie_close_function_t;
+
+typedef _IO_cookie_io_functions_t cookie_io_functions_t;
+#endif /* _GNU_SOURCE */
+
+#endif /* __STDIO_GLIBC_CUSTOM_STREAMS */
+
+/*
+ * ungot scheme:
+ * 0 0 none
+ * 0 1 one user (unused ungot is 1) or one scanf (unused ungot is 0)
+ * 1 0 must be scanf[0] and user[1]
+ * 1 1 illegal -- could be used to signal safe for setbuf
+ */
+
+#ifdef __UCLIBC__
+#define __stdio_file_struct _UC_FILE
+#endif
+
+struct __stdio_file_struct {
+ unsigned short modeflags;
+ /* There could be a hole here, but modeflags is used most.*/
+#ifdef __STDIO_WIDE
+ unsigned char ungot_width[2];
+ __wchar_t ungot[2];
+#else /* __STDIO_WIDE */
+ unsigned char ungot[2];
+#endif /* __STDIO_WIDE */
+ int filedes;
+#if defined(__STDIO_BUFFERS) || defined(__STDIO_GLIBC_CUSTOM_STREAMS)
+ struct __stdio_file_struct *nextopen;
+#endif /* defined(__STDIO_BUFFERS) || defined(__STDIO_GLIBC_CUSTOM_STREAMS) */
+#ifdef __STDIO_BUFFERS
+ unsigned char *bufstart; /* pointer to buffer */
+ unsigned char *bufend; /* pointer to 1 past end of buffer */
+ unsigned char *bufwpos; /* pointer to 1 past last buffered */
+ unsigned char *bufrpos; /* pointer to next readable buffered */
+#ifdef __STDIO_GETC_MACRO
+ unsigned char *bufgetc; /* 1 past last readable by getc */
+#endif /* __STDIO_GETC_MACRO */
+#ifdef __STDIO_PUTC_MACRO
+ unsigned char *bufputc; /* 1 past last writeable by putc */
+#endif /* __STDIO_PUTC_MACRO */
+#endif /* __STDIO_BUFFERS */
+#ifdef __STDIO_GLIBC_CUSTOM_STREAMS
+ void *cookie;
+ _IO_cookie_io_functions_t gcs;
+#endif /* __STDIO_GLIBC_CUSTOM_STREAMS */
+#ifdef __STDIO_THREADSAFE
+ int user_locking;
+ pthread_mutex_t lock;
+#endif
+/* Everything after this is unimplemented... and may be trashed. */
+#if __STDIO_BUILTIN_BUF_SIZE > 0
+ unsigned char builtinbuf[__STDIO_BUILTIN_BUF_SIZE];
+#endif /* __STDIO_BUILTIN_BUF_SIZE > 0 */
+};
+
+
+/***********************************************************************/
+
+#define __MASK_UNGOT (0x0002|0x0001)
+#define __MASK_UNGOT1 0x0001
+#define __MASK_UNGOT2 0x0002
+#define __FLAG_EOF 0x0004 /* EOF reached? */
+#define __FLAG_ERROR 0x0008 /* stream in error state? */
+#define __FLAG_WRITEONLY 0x0010 /* unreadable */
+#define __FLAG_READONLY 0x0020 /* unwriteable */
+#define __FLAG_FREEFILE 0x0040 /* free FILE struct after use */
+#define __FLAG_NARROW 0x0080
+
+#define __FLAG_FBF 0 /* convenience value */
+#define __FLAG_LBF 0x0100
+#define __FLAG_NBF 0x0200
+#define __MASK_BUFMODE 0x0300
+
+#define __FLAG_APPEND 0x0400
+#define __FLAG_WIDE 0x0800
+
+#define __FLAG_READING 0x1000
+#define __FLAG_WRITING 0x2000
+
+#define __FLAG_FREEBUF 0x4000 /* free buffer after use */
+#define __FLAG_LARGEFILE 0x8000
+
+/**********************************************************************/
+
+#ifdef __STDIO_GLIBC_CUSTOM_STREAMS
+extern __ssize_t _cs_read(void *cookie, char *buf, size_t bufsize);
+extern __ssize_t _cs_write(void *cookie, const char *buf, size_t bufsize);
+extern int _cs_seek(void *cookie, __offmax_t *pos, int whence);
+extern int _cs_close(void *cookie);
+#endif /* __STDIO_GLIBC_CUSTOM_STREAMS */
+
+/**********************************************************************/
+
+/* TODO -- thread safety issues */
+#define __CLEARERR(stream) \
+ ((stream)->modeflags &= ~(__FLAG_EOF|__FLAG_ERROR), (void)0)
+#define __FEOF(stream) ((stream)->modeflags & __FLAG_EOF)
+#define __FERROR(stream) ((stream)->modeflags & __FLAG_ERROR)
+
+#define __FEOF_OR_FERROR(stream) \
+ ((stream)->modeflags & (__FLAG_EOF|__FLAG_ERROR))
+
+
+/* TODO: check this
+ * If we want to implement the getc and putc macros, we need to take
+ * into account wide streams. So... would need two additional variables
+ * if we have wide streams (bufread and bufwrite), and one otherwise
+ * (bufwrite). getc would be effective for FBF streams. It isn't for
+ * LBF streams because other LBF streams need to be flushed. putc
+ * thouch is only effective for FBF streams. Of course, to support
+ * threads, we have to use functions.
+ */
+
+#ifdef __STDIO_GETC_MACRO
+#define __GETC(stream) ( ((stream)->bufrpos < (stream)->bufgetc) \
+ ? (*(stream)->bufrpos++) \
+ : fgetc_unlocked(stream) )
+#else /* __STDIO_GETC_MACRO */
+#define __GETC(stream) fgetc_unlocked(stream)
+#endif /* __STDIO_GETC_MACRO */
+
+#ifdef __STDIO_PUTC_MACRO
+#define __PUTC(c, stream) ( ((stream)->bufwpos < (stream)->bufputc) \
+ ? (*(stream)->bufwpos++) = (c) \
+ : fputc_unlocked((c),(stream)) )
+#else /* __STDIO_PUTC_MACRO */
+#define __PUTC(c, stream) fputc_unlocked(c, stream);
+#endif /* __STDIO_PUTC_MACRO */
+
+
+#if 0
+/* TODO: disabled for now */
+/* Masking macros for the above _are_ allowed by the standard. */
+#define clearerr(stream) __CLEARERR(stream)
+#define feof(stream) __FEOF(stream)
+#define ferror(stream) __FERROR(stream)
+#endif
+
+#if 0
+/* TODO -- what about custom streams!!! */
+/* Only use the macro below if you know fp is a valid FILE for a valid fd. */
+#define __fileno(fp) ((fp)->filedes)
+#endif
+
+/**********************************************************************
+ * PROTOTYPES OF INTERNAL FUNCTIONS
+ **********************************************************************/
+
+extern FILE *_stdio_openlist;
+
+#ifdef __STDIO_THREADSAFE
+extern pthread_mutex_t _stdio_openlist_lock;
+extern void __stdio_init_mutex(pthread_mutex_t *m);
+#endif
+
+extern int _stdio_adjpos(FILE * __restrict stream, __offmax_t * pos);
+extern int _stdio_lseek(FILE *stream, __offmax_t *pos, int whence);
+/* TODO: beware of signals with _stdio_fwrite!!!! */
+extern size_t _stdio_fwrite(const unsigned char *buffer, size_t bytes,
+ FILE *stream);
+extern size_t _stdio_fread(unsigned char *buffer, size_t bytes,
+ FILE *stream);
+
+extern FILE *_stdio_fopen(const char * __restrict filename,
+ const char * __restrict mode,
+ FILE * __restrict stream, int filedes);
+
+extern FILE *_stdio_fsfopen(const char * __restrict filename,
+ const char * __restrict mode,
+ register FILE * __restrict stream);
+
+extern void _stdio_init(void);
+extern void _stdio_term(void);
+
+#ifndef NDEBUG
+extern void __stdio_validate_FILE(FILE *stream);
+#else
+#define __stdio_validate_FILE(stream) ((void)0)
+#endif
+
+/**********************************************************************
+ * UTILITY functions
+ **********************************************************************/
+#ifdef _STDIO_UTILITY
+
+#include <features.h>
+#include <limits.h>
+#include <stdint.h>
+
+#if UINTMAX_MAX <= 4294967295UL
+#define __UIM_BUFLEN 12 /* 10 digits + 1 nul + 1 sign */
+#elif UINTMAX_MAX <= 18446744073709551615ULL
+#define __UIM_BUFLEN 22 /* 20 digits + 1 nul + 1 sign */
+#else
+#error unknown number of digits for intmax_t!
+#endif
+
+#ifdef ULLONG_MAX /* --------------- */
+#if ULLONG_MAX <= 4294967295UL
+#define __UIM_BUFLEN_LLONG 12 /* 10 digits + 1 nul + 1 sign */
+#elif ULLONG_MAX <= 18446744073709551615ULL
+#define __UIM_BUFLEN_LLONG 22 /* 20 digits + 1 nul + 1 sign */
+#else
+#error unknown number of digits for long long!
+#endif
+#endif /* ULLONG_MAX ----------------------------- */
+
+#if ULONG_MAX <= 4294967295UL
+#define __UIM_BUFLEN_LONG 12 /* 10 digits + 1 nul + 1 sign */
+#elif ULONG_MAX <= 18446744073709551615ULL
+#define __UIM_BUFLEN_LONG 22 /* 20 digits + 1 nul + 1 sign */
+#else
+#error unknown number of digits for long!
+#endif
+
+#if UINT_MAX <= 65536U
+#define __UIM_BUFLEN_INT 7 /* 10 digits + 1 nul + 1 sign */
+#elif UINT_MAX <= 4294967295UL
+#define __UIM_BUFLEN_INT 12 /* 10 digits + 1 nul + 1 sign */
+#else
+#error unknown number of digits for int!
+#endif
+
+typedef enum {
+ __UIM_DECIMAL = 0,
+ __UIM_LOWER = 'a' - 10,
+ __UIM_UPPER = 'A' - 10,
+} __UIM_CASE;
+
+/* Write a NULL-terminated list of "char *" args to file descriptor fd.
+ * For an example of usage, see __assert.c.
+ */
+extern void _stdio_fdout(int fd, ...);
+
+/* Convert the int val to a string in base abs(base). val is treated as
+ * an unsigned ??? int type if base > 0, and signed if base < 0. This
+ * is an internal function with _no_ error checking done unless assert()s
+ * are enabled.
+ *
+ * Note: bufend is a pointer to the END of the buffer passed.
+ * Call like this:
+ * char buf[SIZE], *p;
+ * p = _xltostr(buf + sizeof(buf) - 1, {unsigned int}, 10, __UIM_DECIMAL)
+ * p = _xltostr(buf + sizeof(buf) - 1, {int}, -10, __UIM_DECIMAL)
+ *
+ * WARNING: If base > 10, case _must_be_ either __UIM_LOWER or __UIM_UPPER
+ * for lower and upper case alphas respectively.
+ * WARNING: If val is really a signed type, make sure base is negative!
+ * Otherwise, you could overflow your buffer.
+ */
+extern char *_uintmaxtostr(char * __restrict bufend, uintmax_t uval,
+ int base, __UIM_CASE alphacase);
+
+/* TODO -- make this either a (possibly inline) function? */
+#ifndef __BCC__
+#define _int10tostr(bufend, intval) \
+ _uintmaxtostr((bufend), (intval), -10, __UIM_DECIMAL)
+#else /* bcc doesn't do prototypes, we need to explicitly cast */
+#define _int10tostr(bufend, intval) \
+ _uintmaxtostr((bufend), (uintmax_t)(intval), -10, __UIM_DECIMAL)
+#endif
+
+#define __BUFLEN_INT10TOSTR __UIM_BUFLEN_INT
+
+#endif /* _STDIO_UTILITY */
+/**********************************************************************/
+/* uClibc translations */
+/**********************************************************************/
+
+/* TODO: note done above.. typedef struct __stdio_file_struct _UC_FILE; */
+typedef __stdio_fpos_t _UC_fpos_t;
+typedef __stdio_fpos64_t _UC_fpos64_t;
+
+#define _UC_IOFBF _STDIO_IOFBF /* Fully buffered. */
+#define _UC_IOLBF _STDIO_IOLBF /* Line buffered. */
+#define _UC_IONBF _STDIO_IONBF /* No buffering. */
+
+#define _UC_BUFSIZ _STDIO_BUFSIZ