1 #ifndef _STDIO_IMPL_H 2 #define _STDIO_IMPL_H 3 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include "syscall.h" 7 8 #define UNGET 8 9 10 #define FFINALLOCK(f) ((f)->lock>=0 ? __lockfile((f)) : 0) 11 #define FLOCK(f) int __need_unlock = ((f)->lock>=0 ? __lockfile((f)) : 0) 12 #define FUNLOCK(f) do { if (__need_unlock) __unlockfile((f)); } while (0) 13 14 #define F_PERM 1 15 #define F_NORD 4 16 #define F_NOWR 8 17 #define F_EOF 16 18 #define F_ERR 32 19 #define F_SVB 64 20 #define F_APP 128 21 #define F_NOBUF 256 22 #define F_PBUF 512 23 24 25 #define FILE_LIST_NEXT(fl) (fl->next) 26 #define FILE_LIST_HEAD(head) (head) 27 #define FILE_LIST_EMPTY(head) ((head) == NULL) 28 #define FILE_SAVELINK(name, link) void **name = (void *)&(link) 29 #define INVALID_LINK(x) do {(x) = (void *)-1;} while (0) 30 31 #define FILE_LIST_CHECK_NEXT(fl) do { \ 32 if (FILE_LIST_NEXT(fl) != NULL && FILE_LIST_NEXT(fl)->prev != &fl->next) { \ 33 abort(); \ 34 } \ 35 } while(0) 36 37 #define FILE_LIST_CHECK_PREV(fl) do { \ 38 if (*fl->prev != fl) { \ 39 abort();\ 40 } \ 41 } while(0) 42 43 #define FILE_LIST_CHECK_HEAD(head) do { \ 44 if (FILE_LIST_HEAD(head) != NULL && \ 45 FILE_LIST_HEAD(head)->prev != &FILE_LIST_HEAD(head)) {\ 46 abort();\ 47 } \ 48 } while(0) 49 50 51 #define FILE_LIST_INSERT_HEAD(head, fl) do { \ 52 FILE_LIST_CHECK_HEAD((head)); \ 53 if ((FILE_LIST_NEXT((fl)) = FILE_LIST_HEAD((head))) != NULL) { \ 54 FILE_LIST_HEAD((head))->prev = &FILE_LIST_NEXT((fl)); \ 55 } \ 56 FILE_LIST_HEAD(head) = (fl); \ 57 (fl)->prev = &FILE_LIST_HEAD((head)); \ 58 } while(0) 59 60 #define FILE_LIST_REMOVE(fl) do { \ 61 FILE_SAVELINK(oldnext, (fl)->next); \ 62 FILE_SAVELINK(oldprev, (fl)->prev); \ 63 FILE_LIST_CHECK_NEXT(fl); \ 64 FILE_LIST_CHECK_PREV(fl); \ 65 if (FILE_LIST_NEXT(fl) != NULL) { \ 66 FILE_LIST_NEXT(fl)->prev = fl->prev; \ 67 } \ 68 *fl->prev = FILE_LIST_NEXT(fl); \ 69 INVALID_LINK(*oldnext); \ 70 INVALID_LINK(*oldprev); \ 71 } while(0) 72 73 struct _IO_FILE { 74 unsigned flags; 75 unsigned char *rpos, *rend; 76 int (*close)(FILE *); 77 unsigned char *wend, *wpos; 78 unsigned char *mustbezero_1; 79 unsigned char *wbase; 80 size_t (*read)(FILE *, unsigned char *, size_t); 81 size_t (*readx)(FILE *, unsigned char *, size_t); 82 size_t (*write)(FILE *, const unsigned char *, size_t); 83 off_t (*seek)(FILE *, off_t, int); 84 unsigned char *buf; 85 size_t buf_size; 86 /* when allocating buffer dynamically, base == buf - UNGET, 87 * free base when calling fclose. 88 * otherwise, base == NULL, cases: 89 * 1. in stdout, stdin, stdout, base is static array. 90 * 2. call setvbuf to set buffer or non-buffer. 91 * 3. call fmemopen, base == NULL && buf_size != 0. 92 */ 93 unsigned char *base; 94 FILE **prev, *next; 95 int fd; 96 int pipe_pid; 97 long lockcount; 98 int mode; 99 volatile int lock; 100 int lbf; 101 void *cookie; 102 off_t off; 103 char *getln_buf; 104 void *mustbezero_2; 105 unsigned char *shend; 106 off_t shlim, shcnt; 107 FILE *prev_locked, *next_locked; 108 struct __locale_struct *locale; 109 }; 110 111 extern hidden FILE *volatile __stdin_used; 112 extern hidden FILE *volatile __stdout_used; 113 extern hidden FILE *volatile __stderr_used; 114 115 hidden int __lockfile(FILE *); 116 hidden void __unlockfile(FILE *); 117 118 hidden size_t __stdio_read(FILE *, unsigned char *, size_t); 119 hidden size_t __stdio_readx(FILE *, unsigned char *, size_t); 120 hidden size_t __stdio_write(FILE *, const unsigned char *, size_t); 121 hidden size_t __stdout_write(FILE *, const unsigned char *, size_t); 122 hidden off_t __stdio_seek(FILE *, off_t, int); 123 hidden int __stdio_close(FILE *); 124 125 hidden int __fill_buffer(FILE *f); 126 hidden ssize_t __flush_buffer(FILE *f); 127 128 hidden int __toread(FILE *); 129 hidden int __towrite(FILE *); 130 hidden int __falloc_buf(FILE *); 131 132 hidden void __stdio_exit(void); 133 hidden void __stdio_exit_needed(void); 134 135 #if defined(__PIC__) && (100*__GNUC__+__GNUC_MINOR__ >= 303) 136 __attribute__((visibility("protected"))) 137 #endif 138 int __overflow(FILE *, int), __uflow(FILE *); 139 140 hidden int __fseeko(FILE *, off_t, int); 141 hidden int __fseeko_unlocked(FILE *, off_t, int); 142 hidden off_t __ftello(FILE *); 143 hidden off_t __ftello_unlocked(FILE *); 144 hidden size_t __fwritex(const unsigned char *, size_t, FILE *); 145 hidden int __putc_unlocked(int, FILE *); 146 147 hidden FILE *__fdopen(int, const char *); 148 hidden FILE *__fdopenx(int, int); 149 hidden int __fmodeflags(const char *, int *); 150 151 hidden FILE *__ofl_add(FILE *f); 152 hidden FILE **__ofl_lock(void); 153 hidden void __ofl_unlock(void); 154 hidden void __ofl_free(FILE *f); 155 hidden FILE *__ofl_alloc(); 156 157 struct __pthread; 158 hidden void __register_locked_file(FILE *, struct __pthread *); 159 hidden void __unlist_locked_file(FILE *); 160 hidden void __do_orphaned_stdio_locks(void); 161 162 #define MAYBE_WAITERS 0x40000000 163 164 hidden void __getopt_msg(const char *, const char *, const char *, size_t); 165 166 #define feof(f) ((f)->flags & F_EOF) 167 #define ferror(f) ((f)->flags & F_ERR) 168 169 #define getc_unlocked(f) \ 170 ( ((f)->rpos != (f)->rend) ? *(f)->rpos++ : __uflow((f)) ) 171 172 #define putc_unlocked(c, f) \ 173 ( (((unsigned char)(c)!=(f)->lbf && (f)->wpos!=(f)->wend)) \ 174 ? *(f)->wpos++ = (unsigned char)(c) \ 175 : __overflow((f),(unsigned char)(c)) ) 176 177 /* Caller-allocated FILE * operations */ 178 hidden FILE *__fopen_rb_ca(const char *, FILE *, unsigned char *, size_t); 179 hidden int __fclose_ca(FILE *); 180 181 #endif 182