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