From 000d24f6812f1c336ae64897d19d68f880c93059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sun, 23 Mar 2003 23:49:22 +0000 Subject: [PATCH] Initial revision git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3005 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kernel/libroot/posix/glibc/libio/Jamfile | 116 ++ .../libroot/posix/glibc/libio/_G_config.h | 146 ++ .../libroot/posix/glibc/libio/bits/stdio.h | 169 ++ .../libroot/posix/glibc/libio/clearerr.c | 34 + .../libroot/posix/glibc/libio/clearerr_u.c | 28 + .../libroot/posix/glibc/libio/fcloseall.c | 40 + src/kernel/libroot/posix/glibc/libio/feof.c | 50 + src/kernel/libroot/posix/glibc/libio/feof_u.c | 39 + src/kernel/libroot/posix/glibc/libio/ferror.c | 50 + .../libroot/posix/glibc/libio/ferror_u.c | 39 + .../libroot/posix/glibc/libio/filedoalloc.c | 124 ++ src/kernel/libroot/posix/glibc/libio/fileno.c | 53 + .../libroot/posix/glibc/libio/fileops.c | 1650 +++++++++++++++++ .../libroot/posix/glibc/libio/fmemopen.c | 243 +++ src/kernel/libroot/posix/glibc/libio/fputc.c | 49 + .../libroot/posix/glibc/libio/fputc_u.c | 40 + src/kernel/libroot/posix/glibc/libio/fputwc.c | 47 + .../libroot/posix/glibc/libio/fputwc_u.c | 42 + .../libroot/posix/glibc/libio/freopen.c | 89 + .../libroot/posix/glibc/libio/freopen64.c | 78 + src/kernel/libroot/posix/glibc/libio/fseek.c | 46 + src/kernel/libroot/posix/glibc/libio/fseeko.c | 45 + .../libroot/posix/glibc/libio/fseeko64.c | 51 + src/kernel/libroot/posix/glibc/libio/ftello.c | 66 + .../libroot/posix/glibc/libio/ftello64.c | 64 + src/kernel/libroot/posix/glibc/libio/fwide.c | 56 + .../libroot/posix/glibc/libio/fwprintf.c | 38 + .../libroot/posix/glibc/libio/fwscanf.c | 36 + src/kernel/libroot/posix/glibc/libio/genops.c | 1269 +++++++++++++ src/kernel/libroot/posix/glibc/libio/getc.c | 58 + src/kernel/libroot/posix/glibc/libio/getc_u.c | 41 + .../libroot/posix/glibc/libio/getchar.c | 49 + .../libroot/posix/glibc/libio/getchar_u.c | 37 + src/kernel/libroot/posix/glibc/libio/getwc.c | 53 + .../libroot/posix/glibc/libio/getwc_u.c | 41 + .../libroot/posix/glibc/libio/getwchar.c | 44 + .../libroot/posix/glibc/libio/getwchar_u.c | 37 + .../libroot/posix/glibc/libio/iofclose.c | 98 + .../libroot/posix/glibc/libio/iofdopen.c | 184 ++ .../libroot/posix/glibc/libio/iofflush.c | 58 + .../libroot/posix/glibc/libio/iofflush_u.c | 43 + .../libroot/posix/glibc/libio/iofgetpos.c | 82 + .../libroot/posix/glibc/libio/iofgetpos64.c | 75 + .../libroot/posix/glibc/libio/iofgets.c | 74 + .../libroot/posix/glibc/libio/iofgets_u.c | 62 + .../libroot/posix/glibc/libio/iofgetws.c | 64 + .../libroot/posix/glibc/libio/iofgetws_u.c | 61 + .../libroot/posix/glibc/libio/iofopen.c | 113 ++ .../libroot/posix/glibc/libio/iofopen64.c | 48 + .../libroot/posix/glibc/libio/iofopncook.c | 256 +++ .../libroot/posix/glibc/libio/iofputs.c | 57 + .../libroot/posix/glibc/libio/iofputs_u.c | 44 + .../libroot/posix/glibc/libio/iofputws.c | 47 + .../libroot/posix/glibc/libio/iofputws_u.c | 45 + .../libroot/posix/glibc/libio/iofread.c | 58 + .../libroot/posix/glibc/libio/iofread_u.c | 48 + .../libroot/posix/glibc/libio/iofsetpos.c | 67 + .../libroot/posix/glibc/libio/iofsetpos64.c | 72 + .../libroot/posix/glibc/libio/ioftell.c | 70 + .../libroot/posix/glibc/libio/iofwide.c | 498 +++++ .../libroot/posix/glibc/libio/iofwrite.c | 63 + .../libroot/posix/glibc/libio/iofwrite_u.c | 54 + .../libroot/posix/glibc/libio/iogetdelim.c | 131 ++ .../libroot/posix/glibc/libio/iogetline.c | 122 ++ src/kernel/libroot/posix/glibc/libio/iogets.c | 81 + .../libroot/posix/glibc/libio/iogetwline.c | 127 ++ .../libroot/posix/glibc/libio/iolibio.h | 101 + src/kernel/libroot/posix/glibc/libio/iopadn.c | 73 + .../libroot/posix/glibc/libio/iopopen.c | 338 ++++ src/kernel/libroot/posix/glibc/libio/ioputs.c | 53 + .../libroot/posix/glibc/libio/ioseekoff.c | 91 + .../libroot/posix/glibc/libio/ioseekpos.c | 70 + .../libroot/posix/glibc/libio/iosetbuffer.c | 53 + .../libroot/posix/glibc/libio/iosetvbuf.c | 107 ++ .../libroot/posix/glibc/libio/ioungetc.c | 49 + .../libroot/posix/glibc/libio/ioungetwc.c | 48 + .../libroot/posix/glibc/libio/iovdprintf.c | 69 + .../libroot/posix/glibc/libio/iovsprintf.c | 54 + .../libroot/posix/glibc/libio/iovsscanf.c | 52 + .../libroot/posix/glibc/libio/iovswscanf.c | 50 + .../libroot/posix/glibc/libio/iowpadn.c | 78 + src/kernel/libroot/posix/glibc/libio/libio.h | 522 ++++++ src/kernel/libroot/posix/glibc/libio/libioP.h | 973 ++++++++++ .../libroot/posix/glibc/libio/memstream.c | 226 +++ .../libroot/posix/glibc/libio/obprintf.c | 191 ++ .../libroot/posix/glibc/libio/oldfileops.c | 793 ++++++++ .../libroot/posix/glibc/libio/oldiofclose.c | 79 + .../libroot/posix/glibc/libio/oldiofdopen.c | 142 ++ .../libroot/posix/glibc/libio/oldiofgetpos.c | 68 + .../posix/glibc/libio/oldiofgetpos64.c | 73 + .../libroot/posix/glibc/libio/oldiofopen.c | 72 + .../libroot/posix/glibc/libio/oldiofsetpos.c | 66 + .../posix/glibc/libio/oldiofsetpos64.c | 72 + .../libroot/posix/glibc/libio/oldiopopen.c | 316 ++++ .../libroot/posix/glibc/libio/oldpclose.c | 50 + .../libroot/posix/glibc/libio/oldstdfiles.c | 96 + .../libroot/posix/glibc/libio/oldtmpfile.c | 55 + src/kernel/libroot/posix/glibc/libio/pclose.c | 46 + src/kernel/libroot/posix/glibc/libio/peekc.c | 45 + src/kernel/libroot/posix/glibc/libio/putc.c | 49 + src/kernel/libroot/posix/glibc/libio/putc_u.c | 31 + .../libroot/posix/glibc/libio/putchar.c | 41 + .../libroot/posix/glibc/libio/putchar_u.c | 30 + src/kernel/libroot/posix/glibc/libio/putwc.c | 36 + .../libroot/posix/glibc/libio/putwc_u.c | 30 + .../libroot/posix/glibc/libio/putwchar.c | 34 + .../libroot/posix/glibc/libio/putwchar_u.c | 28 + src/kernel/libroot/posix/glibc/libio/rewind.c | 43 + src/kernel/libroot/posix/glibc/libio/setbuf.c | 37 + .../libroot/posix/glibc/libio/setlinebuf.c | 38 + .../libroot/posix/glibc/libio/stdfiles.c | 74 + src/kernel/libroot/posix/glibc/libio/stdio.c | 54 + src/kernel/libroot/posix/glibc/libio/stdio.h | 683 +++++++ .../libroot/posix/glibc/libio/strfile.h | 65 + src/kernel/libroot/posix/glibc/libio/strops.c | 332 ++++ .../libroot/posix/glibc/libio/swprintf.c | 36 + .../libroot/posix/glibc/libio/swscanf.c | 35 + .../libroot/posix/glibc/libio/vasprintf.c | 93 + src/kernel/libroot/posix/glibc/libio/vscanf.c | 43 + .../libroot/posix/glibc/libio/vsnprintf.c | 140 ++ .../libroot/posix/glibc/libio/vswprintf.c | 142 ++ .../libroot/posix/glibc/libio/vwprintf.c | 31 + .../libroot/posix/glibc/libio/vwscanf.c | 37 + .../libroot/posix/glibc/libio/wfiledoalloc.c | 119 ++ .../libroot/posix/glibc/libio/wfileops.c | 931 ++++++++++ .../libroot/posix/glibc/libio/wgenops.c | 746 ++++++++ .../libroot/posix/glibc/libio/wprintf.c | 36 + src/kernel/libroot/posix/glibc/libio/wscanf.c | 37 + .../libroot/posix/glibc/libio/wstrops.c | 333 ++++ 129 files changed, 17494 insertions(+) create mode 100644 src/kernel/libroot/posix/glibc/libio/Jamfile create mode 100644 src/kernel/libroot/posix/glibc/libio/_G_config.h create mode 100644 src/kernel/libroot/posix/glibc/libio/bits/stdio.h create mode 100644 src/kernel/libroot/posix/glibc/libio/clearerr.c create mode 100644 src/kernel/libroot/posix/glibc/libio/clearerr_u.c create mode 100644 src/kernel/libroot/posix/glibc/libio/fcloseall.c create mode 100644 src/kernel/libroot/posix/glibc/libio/feof.c create mode 100644 src/kernel/libroot/posix/glibc/libio/feof_u.c create mode 100644 src/kernel/libroot/posix/glibc/libio/ferror.c create mode 100644 src/kernel/libroot/posix/glibc/libio/ferror_u.c create mode 100644 src/kernel/libroot/posix/glibc/libio/filedoalloc.c create mode 100644 src/kernel/libroot/posix/glibc/libio/fileno.c create mode 100644 src/kernel/libroot/posix/glibc/libio/fileops.c create mode 100644 src/kernel/libroot/posix/glibc/libio/fmemopen.c create mode 100644 src/kernel/libroot/posix/glibc/libio/fputc.c create mode 100644 src/kernel/libroot/posix/glibc/libio/fputc_u.c create mode 100644 src/kernel/libroot/posix/glibc/libio/fputwc.c create mode 100644 src/kernel/libroot/posix/glibc/libio/fputwc_u.c create mode 100644 src/kernel/libroot/posix/glibc/libio/freopen.c create mode 100644 src/kernel/libroot/posix/glibc/libio/freopen64.c create mode 100644 src/kernel/libroot/posix/glibc/libio/fseek.c create mode 100644 src/kernel/libroot/posix/glibc/libio/fseeko.c create mode 100644 src/kernel/libroot/posix/glibc/libio/fseeko64.c create mode 100644 src/kernel/libroot/posix/glibc/libio/ftello.c create mode 100644 src/kernel/libroot/posix/glibc/libio/ftello64.c create mode 100644 src/kernel/libroot/posix/glibc/libio/fwide.c create mode 100644 src/kernel/libroot/posix/glibc/libio/fwprintf.c create mode 100644 src/kernel/libroot/posix/glibc/libio/fwscanf.c create mode 100644 src/kernel/libroot/posix/glibc/libio/genops.c create mode 100644 src/kernel/libroot/posix/glibc/libio/getc.c create mode 100644 src/kernel/libroot/posix/glibc/libio/getc_u.c create mode 100644 src/kernel/libroot/posix/glibc/libio/getchar.c create mode 100644 src/kernel/libroot/posix/glibc/libio/getchar_u.c create mode 100644 src/kernel/libroot/posix/glibc/libio/getwc.c create mode 100644 src/kernel/libroot/posix/glibc/libio/getwc_u.c create mode 100644 src/kernel/libroot/posix/glibc/libio/getwchar.c create mode 100644 src/kernel/libroot/posix/glibc/libio/getwchar_u.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iofclose.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iofdopen.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iofflush.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iofflush_u.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iofgetpos.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iofgetpos64.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iofgets.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iofgets_u.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iofgetws.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iofgetws_u.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iofopen.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iofopen64.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iofopncook.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iofputs.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iofputs_u.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iofputws.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iofputws_u.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iofread.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iofread_u.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iofsetpos.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iofsetpos64.c create mode 100644 src/kernel/libroot/posix/glibc/libio/ioftell.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iofwide.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iofwrite.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iofwrite_u.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iogetdelim.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iogetline.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iogets.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iogetwline.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iolibio.h create mode 100644 src/kernel/libroot/posix/glibc/libio/iopadn.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iopopen.c create mode 100644 src/kernel/libroot/posix/glibc/libio/ioputs.c create mode 100644 src/kernel/libroot/posix/glibc/libio/ioseekoff.c create mode 100644 src/kernel/libroot/posix/glibc/libio/ioseekpos.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iosetbuffer.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iosetvbuf.c create mode 100644 src/kernel/libroot/posix/glibc/libio/ioungetc.c create mode 100644 src/kernel/libroot/posix/glibc/libio/ioungetwc.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iovdprintf.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iovsprintf.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iovsscanf.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iovswscanf.c create mode 100644 src/kernel/libroot/posix/glibc/libio/iowpadn.c create mode 100644 src/kernel/libroot/posix/glibc/libio/libio.h create mode 100644 src/kernel/libroot/posix/glibc/libio/libioP.h create mode 100644 src/kernel/libroot/posix/glibc/libio/memstream.c create mode 100644 src/kernel/libroot/posix/glibc/libio/obprintf.c create mode 100644 src/kernel/libroot/posix/glibc/libio/oldfileops.c create mode 100644 src/kernel/libroot/posix/glibc/libio/oldiofclose.c create mode 100644 src/kernel/libroot/posix/glibc/libio/oldiofdopen.c create mode 100644 src/kernel/libroot/posix/glibc/libio/oldiofgetpos.c create mode 100644 src/kernel/libroot/posix/glibc/libio/oldiofgetpos64.c create mode 100644 src/kernel/libroot/posix/glibc/libio/oldiofopen.c create mode 100644 src/kernel/libroot/posix/glibc/libio/oldiofsetpos.c create mode 100644 src/kernel/libroot/posix/glibc/libio/oldiofsetpos64.c create mode 100644 src/kernel/libroot/posix/glibc/libio/oldiopopen.c create mode 100644 src/kernel/libroot/posix/glibc/libio/oldpclose.c create mode 100644 src/kernel/libroot/posix/glibc/libio/oldstdfiles.c create mode 100644 src/kernel/libroot/posix/glibc/libio/oldtmpfile.c create mode 100644 src/kernel/libroot/posix/glibc/libio/pclose.c create mode 100644 src/kernel/libroot/posix/glibc/libio/peekc.c create mode 100644 src/kernel/libroot/posix/glibc/libio/putc.c create mode 100644 src/kernel/libroot/posix/glibc/libio/putc_u.c create mode 100644 src/kernel/libroot/posix/glibc/libio/putchar.c create mode 100644 src/kernel/libroot/posix/glibc/libio/putchar_u.c create mode 100644 src/kernel/libroot/posix/glibc/libio/putwc.c create mode 100644 src/kernel/libroot/posix/glibc/libio/putwc_u.c create mode 100644 src/kernel/libroot/posix/glibc/libio/putwchar.c create mode 100644 src/kernel/libroot/posix/glibc/libio/putwchar_u.c create mode 100644 src/kernel/libroot/posix/glibc/libio/rewind.c create mode 100644 src/kernel/libroot/posix/glibc/libio/setbuf.c create mode 100644 src/kernel/libroot/posix/glibc/libio/setlinebuf.c create mode 100644 src/kernel/libroot/posix/glibc/libio/stdfiles.c create mode 100644 src/kernel/libroot/posix/glibc/libio/stdio.c create mode 100644 src/kernel/libroot/posix/glibc/libio/stdio.h create mode 100644 src/kernel/libroot/posix/glibc/libio/strfile.h create mode 100644 src/kernel/libroot/posix/glibc/libio/strops.c create mode 100644 src/kernel/libroot/posix/glibc/libio/swprintf.c create mode 100644 src/kernel/libroot/posix/glibc/libio/swscanf.c create mode 100644 src/kernel/libroot/posix/glibc/libio/vasprintf.c create mode 100644 src/kernel/libroot/posix/glibc/libio/vscanf.c create mode 100644 src/kernel/libroot/posix/glibc/libio/vsnprintf.c create mode 100644 src/kernel/libroot/posix/glibc/libio/vswprintf.c create mode 100644 src/kernel/libroot/posix/glibc/libio/vwprintf.c create mode 100644 src/kernel/libroot/posix/glibc/libio/vwscanf.c create mode 100644 src/kernel/libroot/posix/glibc/libio/wfiledoalloc.c create mode 100644 src/kernel/libroot/posix/glibc/libio/wfileops.c create mode 100644 src/kernel/libroot/posix/glibc/libio/wgenops.c create mode 100644 src/kernel/libroot/posix/glibc/libio/wprintf.c create mode 100644 src/kernel/libroot/posix/glibc/libio/wscanf.c create mode 100644 src/kernel/libroot/posix/glibc/libio/wstrops.c diff --git a/src/kernel/libroot/posix/glibc/libio/Jamfile b/src/kernel/libroot/posix/glibc/libio/Jamfile new file mode 100644 index 0000000000..4d22fa49ed --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/Jamfile @@ -0,0 +1,116 @@ +SubDir OBOS_TOP src kernel libroot posix glibc libio ; + +SubDirHdrs $(OBOS_TOP) src kernel libroot posix glibc include arch $(OBOS_ARCH) ; +SubDirHdrs $(OBOS_TOP) src kernel libroot posix glibc stdio-common ; +SubDirHdrs $(OBOS_TOP) src kernel libroot posix glibc libio ; +SubDirHdrs $(OBOS_TOP) src kernel libroot posix glibc include ; +SubDirHdrs $(OBOS_TOP) src kernel libroot posix glibc locale ; +SubDirHdrs $(OBOS_TOP) src kernel libroot posix glibc ; + +SubDirCcFlags -imacrolibc-symbols.h ; + +# ToDo: for now, all wide character functions are disabled + +KernelMergeObject posix_gnu_libio.o : + <$(SOURCE_GRIST)>clearerr.c + <$(SOURCE_GRIST)>clearerr_u.c + <$(SOURCE_GRIST)>fcloseall.c + <$(SOURCE_GRIST)>feof.c + <$(SOURCE_GRIST)>feof_u.c + <$(SOURCE_GRIST)>ferror.c + <$(SOURCE_GRIST)>ferror_u.c + <$(SOURCE_GRIST)>fileno.c + <$(SOURCE_GRIST)>filedoalloc.c + <$(SOURCE_GRIST)>fileops.c + <$(SOURCE_GRIST)>fputc.c + <$(SOURCE_GRIST)>fputc_u.c +# <$(SOURCE_GRIST)>fputwc.c +# <$(SOURCE_GRIST)>fputwc_u.c +# <$(SOURCE_GRIST)>freopen.c + <$(SOURCE_GRIST)>fseek.c + <$(SOURCE_GRIST)>fseeko.c + <$(SOURCE_GRIST)>ftello.c + <$(SOURCE_GRIST)>fwide.c + <$(SOURCE_GRIST)>fwprintf.c +# <$(SOURCE_GRIST)>fwscanf.c + <$(SOURCE_GRIST)>genops.c + <$(SOURCE_GRIST)>getc.c + <$(SOURCE_GRIST)>getc_u.c + <$(SOURCE_GRIST)>getchar.c + <$(SOURCE_GRIST)>getchar_u.c +# <$(SOURCE_GRIST)>getwc.c +# <$(SOURCE_GRIST)>getwc_u.c + <$(SOURCE_GRIST)>iofclose.c + <$(SOURCE_GRIST)>iofdopen.c + <$(SOURCE_GRIST)>iofflush.c +# <$(SOURCE_GRIST)>iofgetpos.c + <$(SOURCE_GRIST)>iofgets.c + <$(SOURCE_GRIST)>iofgets_u.c + <$(SOURCE_GRIST)>iofopen.c + <$(SOURCE_GRIST)>iofputs.c + <$(SOURCE_GRIST)>iofputs_u.c +# <$(SOURCE_GRIST)>iofputws.c +# <$(SOURCE_GRIST)>iofputws_u.c + <$(SOURCE_GRIST)>iofread.c + <$(SOURCE_GRIST)>iofread_u.c +# <$(SOURCE_GRIST)>iofsetpos.c + <$(SOURCE_GRIST)>ioftell.c + <$(SOURCE_GRIST)>iofwrite.c + <$(SOURCE_GRIST)>iofwrite_u.c +# <$(SOURCE_GRIST)>iofwide.c + <$(SOURCE_GRIST)>iogetline.c +# <$(SOURCE_GRIST)>iogets.c + <$(SOURCE_GRIST)>iogetwline.c + <$(SOURCE_GRIST)>iopadn.c + <$(SOURCE_GRIST)>ioputs.c + <$(SOURCE_GRIST)>ioseekoff.c + <$(SOURCE_GRIST)>ioseekpos.c + <$(SOURCE_GRIST)>iosetbuffer.c + <$(SOURCE_GRIST)>iosetvbuf.c + <$(SOURCE_GRIST)>ioungetc.c +# <$(SOURCE_GRIST)>ioungetwc.c + <$(SOURCE_GRIST)>iovdprintf.c + <$(SOURCE_GRIST)>iovsprintf.c + <$(SOURCE_GRIST)>iovsscanf.c +# <$(SOURCE_GRIST)>iovswscanf.c +# <$(SOURCE_GRIST)>iowpadn.c + <$(SOURCE_GRIST)>obprintf.c + <$(SOURCE_GRIST)>peekc.c + <$(SOURCE_GRIST)>putc.c + <$(SOURCE_GRIST)>putc_u.c + <$(SOURCE_GRIST)>putchar.c + <$(SOURCE_GRIST)>putchar_u.c +# <$(SOURCE_GRIST)>putwc.c +# <$(SOURCE_GRIST)>putwc_u.c +# <$(SOURCE_GRIST)>putwchar.c +# <$(SOURCE_GRIST)>putwchar_u.c + <$(SOURCE_GRIST)>rewind.c + <$(SOURCE_GRIST)>setbuf.c + <$(SOURCE_GRIST)>setlinebuf.c + <$(SOURCE_GRIST)>stdfiles.c + <$(SOURCE_GRIST)>stdio.c + <$(SOURCE_GRIST)>strops.c +# <$(SOURCE_GRIST)>swprintf.c +# <$(SOURCE_GRIST)>swscanf.c + <$(SOURCE_GRIST)>vasprintf.c + <$(SOURCE_GRIST)>vscanf.c + <$(SOURCE_GRIST)>vsnprintf.c +# <$(SOURCE_GRIST)>vswprintf.c +# <$(SOURCE_GRIST)>vwprintf.c +# <$(SOURCE_GRIST)>vwscanf.c +# <$(SOURCE_GRIST)>wfiledoalloc.c +# <$(SOURCE_GRIST)>wfileops.c +# <$(SOURCE_GRIST)>wgenops.c +# <$(SOURCE_GRIST)>wprintf.c +# <$(SOURCE_GRIST)>wscanf.c +# <$(SOURCE_GRIST)>wstrops.c + : + -fPIC -DPIC + ; + +#KernelMergeObject kernel_posix_stdio.o : +# <$(SOURCE_GRIST)>kvsprintf.c +# : +# -fPIC -DPIC +# ; +# diff --git a/src/kernel/libroot/posix/glibc/libio/_G_config.h b/src/kernel/libroot/posix/glibc/libio/_G_config.h new file mode 100644 index 0000000000..5d9d36c76a --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/_G_config.h @@ -0,0 +1,146 @@ +/* This file is needed by libio to define various configuration parameters. + These are always the same in the GNU C library. */ + +#ifndef _G_config_h +#define _G_config_h 1 + +#include +#include + +#define _GLIBCPP_USE_THREADS +//#define _GLIBCPP_USE_WCHAR_T + +#define _IO_MTSAFE_IO + +/* Define types for libio in terms of the standard internal type names. */ + +#include +#define __need_size_t +#define __need_wchar_t +#define __need_wint_t +#define __need_NULL +#define __need_ptrdiff_t +#ifdef __cplusplus +# include +#else +# include +#endif + +#include + +#ifndef _WINT_T +/* Integral type unchanged by default argument promotions that can + hold any value corresponding to members of the extended character + set, as well as at least one value that does not correspond to any + member of the extended character set. */ +# define _WINT_T +typedef unsigned int wint_t; +#endif + +/* For use as part of glibc (native) or as part of libstdc++ (maybe + not glibc) */ +#ifndef __c_mbstate_t_defined +# define __c_mbstate_t_defined 1 +/*# ifdef _GLIBCPP_USE_WCHAR_T*/ +typedef struct +{ + int count; + wint_t value; +} __c_mbstate_t; +/*# endif*/ +#endif +#undef __need_mbstate_t + +typedef size_t _G_size_t; + + +#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T +typedef struct +{ + off_t __pos; + __c_mbstate_t __state; +} _G_fpos_t; + +typedef struct +{ + off_t __pos; + __c_mbstate_t __state; +} _G_fpos64_t; +#else +typedef off_t _G_fpos_t; +typedef off_t _G_fpos64_t; +#endif +#define __off_t off_t +#define _G_ssize_t ssize_t +#define _G_off_t off_t +#define _G_off64_t off_t +#define _G_pid_t pid_t +#define _G_uid_t uid_t +#define _G_wchar_t wchar_t +#define _G_wint_t wint_t +#define _G_stat64 stat + +#include +typedef union +{ + struct __gconv_info __cd; + struct + { + struct __gconv_info __cd; + struct __gconv_step_data __data; + } __combined; +} _G_iconv_t; + + +typedef int _G_int16_t __attribute__ ((__mode__ (__HI__))); +typedef int _G_int32_t __attribute__ ((__mode__ (__SI__))); +typedef unsigned int _G_uint16_t __attribute__ ((__mode__ (__HI__))); +typedef unsigned int _G_uint32_t __attribute__ ((__mode__ (__SI__))); + +#define _G_HAVE_BOOL 1 + + +/* These library features are always available in the GNU C library. */ +#define _G_HAVE_ATEXIT 1 +#define _G_HAVE_SYS_CDEFS 1 +#define _G_HAVE_SYS_WAIT 1 +#define _G_NEED_STDARG_H 1 +#define _G_va_list __gnuc_va_list + +#define _G_HAVE_PRINTF_FP 1 +//#define _G_HAVE_MMAP 1 +#define _G_HAVE_LONG_DOUBLE_IO 1 +#define _G_HAVE_IO_FILE_OPEN 1 +#define _G_HAVE_IO_GETLINE_INFO 1 + +#define _G_IO_IO_FILE_VERSION 0x20001 + +//#define _G_OPEN64 __open64 +//#define _G_LSEEK64 __lseek64 +//#define _G_FSTAT64(fd,buf) __fxstat64 (_STAT_VER, fd, buf) + +/* This is defined by if `st_blksize' exists. */ +/*#define _G_HAVE_ST_BLKSIZE defined (_STATBUF_ST_BLKSIZE)*/ + +#define _G_BUFSIZ 8192 + +/* These are the vtbl details for ELF. */ +#define _G_NAMES_HAVE_UNDERSCORE 0 +#define _G_VTABLE_LABEL_HAS_LENGTH 1 +#ifndef _G_USING_THUNKS +# define _G_USING_THUNKS 1 +#endif /* _G_USING_THUNKS */ +#define _G_VTABLE_LABEL_PREFIX "__vt_" +#define _G_VTABLE_LABEL_PREFIX_ID __vt_ + +#define _G_INTERNAL_CCS "UCS4" +#define _G_HAVE_WEAK_SYMBOL 1 +#define _G_STDIO_USES_LIBIO 1 + +#if defined __cplusplus || defined __STDC__ +# define _G_ARGS(ARGLIST) ARGLIST +#else +# define _G_ARGS(ARGLIST) () +#endif + +#endif /* _G_config.h */ diff --git a/src/kernel/libroot/posix/glibc/libio/bits/stdio.h b/src/kernel/libroot/posix/glibc/libio/bits/stdio.h new file mode 100644 index 0000000000..118118adce --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/bits/stdio.h @@ -0,0 +1,169 @@ +/* Optimizing macros and inline functions for stdio functions. + Copyright (C) 1998, 2000, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _STDIO_H +# error "Never include directly; use instead." +#endif + +#ifdef __cplusplus +# define __STDIO_INLINE inline +#else +# define __STDIO_INLINE extern __inline +#endif + + +#ifdef __USE_EXTERN_INLINES +/* Write formatted output to stdout from argument list ARG. */ +__STDIO_INLINE int +vprintf (__const char *__restrict __fmt, _G_va_list __arg) __THROW +{ + return vfprintf (stdout, __fmt, __arg); +} + +/* Read a character from stdin. */ +__STDIO_INLINE int +getchar (void) __THROW +{ + return _IO_getc (stdin); +} + + +# if defined __USE_POSIX || defined __USE_MISC +/* This is defined in POSIX.1:1996. */ +__STDIO_INLINE int +getc_unlocked (FILE *__fp) __THROW +{ + return _IO_getc_unlocked (__fp); +} + +/* This is defined in POSIX.1:1996. */ +__STDIO_INLINE int +getchar_unlocked (void) __THROW +{ + return _IO_getc_unlocked (stdin); +} +# endif /* POSIX || misc */ + + +/* Write a character to stdout. */ +__STDIO_INLINE int +putchar (int __c) __THROW +{ + return _IO_putc (__c, stdout); +} + + +# ifdef __USE_MISC +/* Faster version when locking is not necessary. */ +__STDIO_INLINE int +fputc_unlocked (int __c, FILE *__stream) __THROW +{ + return _IO_putc_unlocked (__c, __stream); +} +# endif /* misc */ + + +# if defined __USE_POSIX || defined __USE_MISC +/* This is defined in POSIX.1:1996. */ +__STDIO_INLINE int +putc_unlocked (int __c, FILE *__stream) __THROW +{ + return _IO_putc_unlocked (__c, __stream); +} + +/* This is defined in POSIX.1:1996. */ +__STDIO_INLINE int +putchar_unlocked (int __c) __THROW +{ + return _IO_putc_unlocked (__c, stdout); +} +# endif /* POSIX || misc */ + + +# ifdef __USE_GNU +/* Like `getdelim', but reads up to a newline. */ +__STDIO_INLINE _IO_ssize_t +getline (char **__lineptr, size_t *__n, FILE *__stream) __THROW +{ + return __getdelim (__lineptr, __n, '\n', __stream); +} +# endif /* GNU */ + + +# ifdef __USE_MISC +/* Faster versions when locking is not required. */ +__STDIO_INLINE int +feof_unlocked (FILE *__stream) __THROW +{ + return _IO_feof_unlocked (__stream); +} + +/* Faster versions when locking is not required. */ +__STDIO_INLINE int +ferror_unlocked (FILE *__stream) __THROW +{ + return _IO_ferror_unlocked (__stream); +} +# endif /* misc */ + +#endif /* Use extern inlines. */ + + +#if defined __USE_MISC && defined __GNUC__ && defined __OPTIMIZE__ +/* Perform some simple optimizations. */ +# define fread_unlocked(ptr, size, n, stream) \ + (__extension__ ((__builtin_constant_p (size) && __builtin_constant_p (n) \ + && (size_t) ((size) * (n)) <= 8 && (size) != 0) \ + ? ({ char *__ptr = (char *) (ptr); \ + FILE *__stream = (stream); \ + size_t __cnt; \ + for (__cnt = (size) * (n); __cnt > 0; --__cnt) \ + { \ + int __c = _IO_getc_unlocked (__stream); \ + if (__c == EOF) \ + break; \ + *__ptr++ = __c; \ + } \ + ((size_t) ((size) * (n)) - __cnt) / (size); }) \ + : (((__builtin_constant_p (size) && (size) == 0) \ + || (__builtin_constant_p (n) && (n) == 0)) \ + /* Evaluate all parameters once. */ \ + ? ((void) (ptr), (void) (stream), (void) (size), \ + (void) (n), 0) \ + : fread_unlocked (ptr, size, n, stream)))) + +# define fwrite_unlocked(ptr, size, n, stream) \ + (__extension__ ((__builtin_constant_p (size) && __builtin_constant_p (n) \ + && (size_t) ((size) * (n)) <= 8 && (size) != 0) \ + ? ({ const char *__ptr = (const char *) (ptr); \ + FILE *__stream = (stream); \ + size_t __cnt; \ + for (__cnt = (size) * (n); __cnt > 0; --__cnt) \ + if (_IO_putc_unlocked (*__ptr++, __stream) == EOF) \ + break; \ + ((size_t) ((size) * (n)) - __cnt) / (size); }) \ + : (((__builtin_constant_p (size) && (size) == 0) \ + || (__builtin_constant_p (n) && (n) == 0)) \ + /* Evaluate all parameters once. */ \ + ? ((void) (ptr), (void) (stream), (void) (size), n) \ + : fwrite_unlocked (ptr, size, n, stream)))) +#endif + +/* Define helper macro. */ +#undef __STDIO_INLINE diff --git a/src/kernel/libroot/posix/glibc/libio/clearerr.c b/src/kernel/libroot/posix/glibc/libio/clearerr.c new file mode 100644 index 0000000000..c61c5a40d6 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/clearerr.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "libioP.h" +#include "stdio.h" + +void +clearerr (fp) + FILE *fp; +{ + CHECK_FILE (fp, /*nothing*/); + _IO_flockfile (fp); + _IO_clearerr (fp); + _IO_funlockfile (fp); +} + +#if defined weak_alias && !defined _IO_MTSAFE_IO +weak_alias (clearerr, clearerr_unlocked) +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/clearerr_u.c b/src/kernel/libroot/posix/glibc/libio/clearerr_u.c new file mode 100644 index 0000000000..7f8ec75324 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/clearerr_u.c @@ -0,0 +1,28 @@ +/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "libioP.h" +#include "stdio.h" + +void +clearerr_unlocked (fp) + FILE *fp; +{ + CHECK_FILE (fp, /*nothing*/); + _IO_clearerr (fp); +} diff --git a/src/kernel/libroot/posix/glibc/libio/fcloseall.c b/src/kernel/libroot/posix/glibc/libio/fcloseall.c new file mode 100644 index 0000000000..ae1f0b4a1f --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/fcloseall.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +int +__fcloseall () +{ + /* Close all streams. */ + return _IO_cleanup (); +} + +#ifdef weak_alias +weak_alias (__fcloseall, fcloseall) +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/feof.c b/src/kernel/libroot/posix/glibc/libio/feof.c new file mode 100644 index 0000000000..d4409814cd --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/feof.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +int +_IO_feof (fp) + _IO_FILE* fp; +{ + int result; + CHECK_FILE (fp, EOF); + _IO_flockfile (fp); + result = _IO_feof_unlocked (fp); + _IO_funlockfile (fp); + return result; +} + +#ifdef weak_alias +weak_alias (_IO_feof, feof) + +#ifndef _IO_MTSAFE_IO +#undef feof_unlocked +weak_alias (_IO_feof, feof_unlocked) +#endif +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/feof_u.c b/src/kernel/libroot/posix/glibc/libio/feof_u.c new file mode 100644 index 0000000000..02e08f67ae --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/feof_u.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +#undef feof_unlocked + +int +feof_unlocked (fp) + _IO_FILE* fp; +{ + CHECK_FILE (fp, EOF); + return _IO_feof_unlocked (fp); +} diff --git a/src/kernel/libroot/posix/glibc/libio/ferror.c b/src/kernel/libroot/posix/glibc/libio/ferror.c new file mode 100644 index 0000000000..6d9169c191 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/ferror.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +int +_IO_ferror (fp) + _IO_FILE* fp; +{ + int result; + CHECK_FILE (fp, EOF); + _IO_flockfile (fp); + result = _IO_ferror_unlocked (fp); + _IO_funlockfile (fp); + return result; +} + +#ifdef weak_alias +weak_alias (_IO_ferror, ferror) + +#ifndef _IO_MTSAFE_IO +#undef ferror_unlocked +weak_alias (_IO_ferror, ferror_unlocked) +#endif +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/ferror_u.c b/src/kernel/libroot/posix/glibc/libio/ferror_u.c new file mode 100644 index 0000000000..e9ce67c404 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/ferror_u.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +#undef ferror_unlocked + +int +ferror_unlocked (fp) + _IO_FILE* fp; +{ + CHECK_FILE (fp, EOF); + return _IO_ferror_unlocked (fp); +} diff --git a/src/kernel/libroot/posix/glibc/libio/filedoalloc.c b/src/kernel/libroot/posix/glibc/libio/filedoalloc.c new file mode 100644 index 0000000000..ca02dbeb34 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/filedoalloc.c @@ -0,0 +1,124 @@ +/* Copyright (C) 1993, 1997, 2001, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +/* + Copyright (C) 1990 The Regents of the University of California. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 4. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE.*/ + +/* Modified for GNU iostream by Per Bothner 1991, 1992. */ + +#ifndef _POSIX_SOURCE +# define _POSIX_SOURCE +#endif +#include "libioP.h" +#include +#include +#ifdef __STDC__ +#include +#include +#endif + +#ifdef _LIBC +# undef isatty +# define isatty(Fd) __isatty (Fd) + +# include +#endif + +/* + * Allocate a file buffer, or switch to unbuffered I/O. + * Per the ANSI C standard, ALL tty devices default to line buffered. + * + * As a side effect, we set __SOPT or __SNPT (en/dis-able fseek + * optimisation) right after the _fstat() that finds the buffer size. + */ + +int +_IO_file_doallocate (fp) + _IO_FILE *fp; +{ + _IO_size_t size; + char *p; + struct _G_stat64 st; + +#ifndef _LIBC + /* If _IO_cleanup_registration_needed is non-zero, we should call the + function it points to. This is to make sure _IO_cleanup gets called + on exit. We call it from _IO_file_doallocate, since that is likely + to get called by any program that does buffered I/O. */ + if (__builtin_expect (_IO_cleanup_registration_needed != NULL, 0)) + (*_IO_cleanup_registration_needed) (); +#endif + + size = _IO_BUFSIZ; + if (fp->_fileno >= 0 && __builtin_expect (_IO_SYSSTAT (fp, &st), 0) >= 0) + { + if (S_ISCHR (st.st_mode)) + { + /* Possibly a tty. */ + if ( +#ifdef DEV_TTY_P + DEV_TTY_P (&st) || +#endif + isatty (fp->_fileno)) + fp->_flags |= _IO_LINE_BUF; + } +#if _IO_HAVE_ST_BLKSIZE + if (st.st_blksize > 0) + size = st.st_blksize; +#endif + } + ALLOC_BUF (p, size, EOF); + INTUSE(_IO_setb) (fp, p, p + size, 1); + return 1; +} +INTDEF(_IO_file_doallocate) diff --git a/src/kernel/libroot/posix/glibc/libio/fileno.c b/src/kernel/libroot/posix/glibc/libio/fileno.c new file mode 100644 index 0000000000..cee6971b9a --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/fileno.c @@ -0,0 +1,53 @@ +/* Copyright (C) 1993,95,96,97,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +int +fileno (fp) + _IO_FILE* fp; +{ + CHECK_FILE (fp, EOF); + + if (!(fp->_flags & _IO_IS_FILEBUF) || _IO_fileno (fp) < 0) + { + __set_errno (EBADF); + return -1; + } + + return _IO_fileno (fp); +} +libc_hidden_def (fileno) + +#ifdef weak_alias +/* The fileno implementation for libio does not require locking because + it only accesses once a single variable and this is already atomic + (at least at thread level). Therefore we don't test _IO_MTSAFE_IO here. */ + +weak_alias (fileno, fileno_unlocked) +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/fileops.c b/src/kernel/libroot/posix/glibc/libio/fileops.c new file mode 100644 index 0000000000..ffe1590f43 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/fileops.c @@ -0,0 +1,1650 @@ +/* Copyright (C) 1993, 1995, 1997-2002, 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Per Bothner . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + + +#ifndef _POSIX_SOURCE +# define _POSIX_SOURCE +#endif +#include "libioP.h" +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __STDC__ +#include +#endif +#if _LIBC +# include "../wcsmbs/wcsmbsload.h" +# include "../iconv/gconv_charset.h" +# include "../iconv/gconv_int.h" +# include +#endif +#ifndef errno +extern int errno; +#endif +#ifndef __set_errno +# define __set_errno(Val) errno = (Val) +#endif + + +#ifdef _LIBC +# define open(Name, Flags, Prot) __open (Name, Flags, Prot) +# define close(FD) __close (FD) +# define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence) +# define read(FD, Buf, NBytes) __read (FD, Buf, NBytes) +# define write(FD, Buf, NBytes) __write (FD, Buf, NBytes) +# define _IO_do_write _IO_new_do_write /* For macro uses. */ +#else +# define _IO_new_do_write _IO_do_write +# define _IO_new_file_attach _IO_file_attach +# define _IO_new_file_close_it _IO_file_close_it +# define _IO_new_file_finish _IO_file_finish +# define _IO_new_file_fopen _IO_file_fopen +# define _IO_new_file_init _IO_file_init +# define _IO_new_file_setbuf _IO_file_setbuf +# define _IO_new_file_sync _IO_file_sync +# define _IO_new_file_overflow _IO_file_overflow +# define _IO_new_file_seekoff _IO_file_seekoff +# define _IO_new_file_underflow _IO_file_underflow +# define _IO_new_file_write _IO_file_write +# define _IO_new_file_xsputn _IO_file_xsputn +#endif + + +#ifdef _LIBC +extern struct __gconv_trans_data __libio_translit attribute_hidden; +#endif + + +/* An fstream can be in at most one of put mode, get mode, or putback mode. + Putback mode is a variant of get mode. + + In a filebuf, there is only one current position, instead of two + separate get and put pointers. In get mode, the current position + is that of gptr(); in put mode that of pptr(). + + The position in the buffer that corresponds to the position + in external file system is normally _IO_read_end, except in putback + mode, when it is _IO_save_end. + If the field _fb._offset is >= 0, it gives the offset in + the file as a whole corresponding to eGptr(). (?) + + PUT MODE: + If a filebuf is in put mode, then all of _IO_read_ptr, _IO_read_end, + and _IO_read_base are equal to each other. These are usually equal + to _IO_buf_base, though not necessarily if we have switched from + get mode to put mode. (The reason is to maintain the invariant + that _IO_read_end corresponds to the external file position.) + _IO_write_base is non-NULL and usually equal to _IO_base_base. + We also have _IO_write_end == _IO_buf_end, but only in fully buffered mode. + The un-flushed character are those between _IO_write_base and _IO_write_ptr. + + GET MODE: + If a filebuf is in get or putback mode, eback() != egptr(). + In get mode, the unread characters are between gptr() and egptr(). + The OS file position corresponds to that of egptr(). + + PUTBACK MODE: + Putback mode is used to remember "excess" characters that have + been sputbackc'd in a separate putback buffer. + In putback mode, the get buffer points to the special putback buffer. + The unread characters are the characters between gptr() and egptr() + in the putback buffer, as well as the area between save_gptr() + and save_egptr(), which point into the original reserve buffer. + (The pointers save_gptr() and save_egptr() are the values + of gptr() and egptr() at the time putback mode was entered.) + The OS position corresponds to that of save_egptr(). + + LINE BUFFERED OUTPUT: + During line buffered output, _IO_write_base==base() && epptr()==base(). + However, ptr() may be anywhere between base() and ebuf(). + This forces a call to filebuf::overflow(int C) on every put. + If there is more space in the buffer, and C is not a '\n', + then C is inserted, and pptr() incremented. + + UNBUFFERED STREAMS: + If a filebuf is unbuffered(), the _shortbuf[1] is used as the buffer. +*/ + +#define CLOSED_FILEBUF_FLAGS \ + (_IO_IS_FILEBUF+_IO_NO_READS+_IO_NO_WRITES+_IO_TIED_PUT_GET) + + +void +_IO_new_file_init (fp) + struct _IO_FILE_plus *fp; +{ + /* POSIX.1 allows another file handle to be used to change the position + of our file descriptor. Hence we actually don't know the actual + position before we do the first fseek (and until a following fflush). */ + fp->file._offset = _IO_pos_BAD; + fp->file._IO_file_flags |= CLOSED_FILEBUF_FLAGS; + + INTUSE(_IO_link_in) (fp); + fp->file._fileno = -1; +} +INTDEF2(_IO_new_file_init, _IO_file_init) + +int +_IO_new_file_close_it (fp) + _IO_FILE *fp; +{ + int write_status, close_status; + if (!_IO_file_is_open (fp)) + return EOF; + + if ((fp->_flags & _IO_NO_WRITES) == 0 + && (fp->_flags & _IO_CURRENTLY_PUTTING) != 0) + write_status = _IO_do_flush (fp); + else + write_status = 0; + + INTUSE(_IO_unsave_markers) (fp); + + close_status = _IO_SYSCLOSE (fp); + + /* Free buffer. */ + if (fp->_mode <= 0) + { + INTUSE(_IO_setb) (fp, NULL, NULL, 0); + _IO_setg (fp, NULL, NULL, NULL); + _IO_setp (fp, NULL, NULL); + } +#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T + else + { + if (_IO_have_wbackup (fp)) + INTUSE(_IO_free_wbackup_area) (fp); + INTUSE(_IO_wsetb) (fp, NULL, NULL, 0); + _IO_wsetg (fp, NULL, NULL, NULL); + _IO_wsetp (fp, NULL, NULL); + } +#endif + + INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp); + fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS; + fp->_fileno = -1; + fp->_offset = _IO_pos_BAD; + + return close_status ? close_status : write_status; +} +INTDEF2(_IO_new_file_close_it, _IO_file_close_it) + +void +_IO_new_file_finish (fp, dummy) + _IO_FILE *fp; + int dummy; +{ + if (_IO_file_is_open (fp)) + { + _IO_do_flush (fp); + if (!(fp->_flags & _IO_DELETE_DONT_CLOSE)) + _IO_SYSCLOSE (fp); + } + INTUSE(_IO_default_finish) (fp, 0); +} +INTDEF2(_IO_new_file_finish, _IO_file_finish) + +#if defined __GNUC__ && __GNUC__ >= 2 +__inline__ +#endif +_IO_FILE * +_IO_file_open (fp, filename, posix_mode, prot, read_write, is32not64) + _IO_FILE *fp; + const char *filename; + int posix_mode; + int prot; + int read_write; + int is32not64; +{ + int fdesc; +#ifdef _G_OPEN64 + fdesc = (is32not64 + ? open (filename, posix_mode, prot) + : _G_OPEN64 (filename, posix_mode, prot)); +#else + fdesc = open (filename, posix_mode, prot); +#endif + if (fdesc < 0) + return NULL; + fp->_fileno = fdesc; + _IO_mask_flags (fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); + if ((read_write & _IO_IS_APPENDING) && (read_write & _IO_NO_READS)) + if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_end, _IOS_INPUT|_IOS_OUTPUT) + == _IO_pos_BAD && errno != ESPIPE) + { + close (fdesc); + return NULL; + } + INTUSE(_IO_link_in) ((struct _IO_FILE_plus *) fp); + return fp; +} +libc_hidden_def (_IO_file_open) + +_IO_FILE * +_IO_new_file_fopen (fp, filename, mode, is32not64) + _IO_FILE *fp; + const char *filename; + const char *mode; + int is32not64; +{ + int oflags = 0, omode; + int read_write; + int oprot = 0666; + int i; + _IO_FILE *result; +#ifdef _LIBC + const char *cs; + const char *last_recognized; +#endif + + if (_IO_file_is_open (fp)) + return 0; + switch (*mode) + { + case 'r': + omode = O_RDONLY; + read_write = _IO_NO_WRITES; + break; + case 'w': + omode = O_WRONLY; + oflags = O_CREAT|O_TRUNC; + read_write = _IO_NO_READS; + break; + case 'a': + omode = O_WRONLY; + oflags = O_CREAT|O_APPEND; + read_write = _IO_NO_READS|_IO_IS_APPENDING; + break; + default: + __set_errno (EINVAL); + return NULL; + } +#ifdef _LIBC + last_recognized = mode; +#endif + for (i = 1; i < 5; ++i) + { + switch (*++mode) + { + case '\0': + break; + case '+': + omode = O_RDWR; + read_write &= _IO_IS_APPENDING; +#ifdef _LIBC + last_recognized = mode; +#endif + continue; + case 'x': + oflags |= O_EXCL; +#ifdef _LIBC + last_recognized = mode; +#endif + continue; + case 'b': +#ifdef _LIBC + last_recognized = mode; +#endif + continue; + case 'm': + fp->_flags2 |= _IO_FLAGS2_MMAP; + continue; + default: + /* Ignore. */ + continue; + } + break; + } + + result = _IO_file_open (fp, filename, omode|oflags, oprot, read_write, + is32not64); + + +#ifdef _LIBC + if (result != NULL) + { + /* Test whether the mode string specifies the conversion. */ + cs = strstr (last_recognized + 1, ",ccs="); + if (cs != NULL) + { + /* Yep. Load the appropriate conversions and set the orientation + to wide. */ + struct gconv_fcts fcts; + struct _IO_codecvt *cc; + char *endp = __strchrnul (cs + 5, ','); + char ccs[endp - (cs + 5) + 3]; + + *((char *) __mempcpy (ccs, cs + 5, endp - (cs + 5))) = '\0'; + strip (ccs, ccs); + + if (__wcsmbs_named_conv (&fcts, ccs[2] == '\0' + ? upstr (ccs, cs + 5) : ccs) != 0) + { + /* Something went wrong, we cannot load the conversion modules. + This means we cannot proceed since the user explicitly asked + for these. */ + (void) INTUSE(_IO_file_close_it) (fp); + __set_errno (EINVAL); + return NULL; + } + + assert (fcts.towc_nsteps == 1); + assert (fcts.tomb_nsteps == 1); + + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end; + fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_write_base; + + /* Clear the state. We start all over again. */ + memset (&fp->_wide_data->_IO_state, '\0', sizeof (__mbstate_t)); + memset (&fp->_wide_data->_IO_last_state, '\0', sizeof (__mbstate_t)); + + cc = fp->_codecvt = &fp->_wide_data->_codecvt; + + /* The functions are always the same. */ + *cc = __libio_codecvt; + + cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps; + cc->__cd_in.__cd.__steps = fcts.towc; + + cc->__cd_in.__cd.__data[0].__invocation_counter = 0; + cc->__cd_in.__cd.__data[0].__internal_use = 1; + cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST; + cc->__cd_in.__cd.__data[0].__statep = &result->_wide_data->_IO_state; + + /* XXX For now no transliteration. */ + cc->__cd_in.__cd.__data[0].__trans = NULL; + + cc->__cd_out.__cd.__nsteps = fcts.tomb_nsteps; + cc->__cd_out.__cd.__steps = fcts.tomb; + + cc->__cd_out.__cd.__data[0].__invocation_counter = 0; + cc->__cd_out.__cd.__data[0].__internal_use = 1; + cc->__cd_out.__cd.__data[0].__flags = __GCONV_IS_LAST; + cc->__cd_out.__cd.__data[0].__statep = + &result->_wide_data->_IO_state; + + /* And now the transliteration. */ + cc->__cd_out.__cd.__data[0].__trans = &__libio_translit; + + /* Set the mode now. */ + result->_mode = 1; + + /* We don't need the step data structure anymore. */ + __gconv_release_cache (fcts.towc, fcts.towc_nsteps); + __gconv_release_cache (fcts.tomb, fcts.tomb_nsteps); + } + } +#endif /* GNU libc */ + + return result; +} +INTDEF2(_IO_new_file_fopen, _IO_file_fopen) + +_IO_FILE * +_IO_new_file_attach (fp, fd) + _IO_FILE *fp; + int fd; +{ + if (_IO_file_is_open (fp)) + return NULL; + fp->_fileno = fd; + fp->_flags &= ~(_IO_NO_READS+_IO_NO_WRITES); + fp->_flags |= _IO_DELETE_DONT_CLOSE; + /* Get the current position of the file. */ + /* We have to do that since that may be junk. */ + fp->_offset = _IO_pos_BAD; + if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_cur, _IOS_INPUT|_IOS_OUTPUT) + == _IO_pos_BAD && errno != ESPIPE) + return NULL; + return fp; +} +INTDEF2(_IO_new_file_attach, _IO_file_attach) + +_IO_FILE * +_IO_new_file_setbuf (fp, p, len) + _IO_FILE *fp; + char *p; + _IO_ssize_t len; +{ + if (_IO_default_setbuf (fp, p, len) == NULL) + return NULL; + + fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end + = fp->_IO_buf_base; + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); + + return fp; +} +INTDEF2(_IO_new_file_setbuf, _IO_file_setbuf) + + +_IO_FILE * +_IO_file_setbuf_mmap (fp, p, len) + _IO_FILE *fp; + char *p; + _IO_ssize_t len; +{ + _IO_FILE *result; + + /* Change the function table. */ + _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &INTUSE(_IO_file_jumps); + fp->_wide_data->_wide_vtable = &_IO_wfile_jumps; + + /* And perform the normal operation. */ + result = _IO_new_file_setbuf (fp, p, len); + + /* If the call failed, restore to using mmap. */ + if (result == NULL) + { + _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps_mmap; + fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap; + } + + return result; +} + +static int new_do_write __P ((_IO_FILE *, const char *, _IO_size_t)); + +/* Write TO_DO bytes from DATA to FP. + Then mark FP as having empty buffers. */ + +int +_IO_new_do_write (fp, data, to_do) + _IO_FILE *fp; + const char *data; + _IO_size_t to_do; +{ + return (to_do == 0 + || (_IO_size_t) new_do_write (fp, data, to_do) == to_do) ? 0 : EOF; +} +INTDEF2(_IO_new_do_write, _IO_do_write) + +static +int +new_do_write (fp, data, to_do) + _IO_FILE *fp; + const char *data; + _IO_size_t to_do; +{ + _IO_size_t count; + if (fp->_flags & _IO_IS_APPENDING) + /* On a system without a proper O_APPEND implementation, + you would need to sys_seek(0, SEEK_END) here, but is + is not needed nor desirable for Unix- or Posix-like systems. + Instead, just indicate that offset (before and after) is + unpredictable. */ + fp->_offset = _IO_pos_BAD; + else if (fp->_IO_read_end != fp->_IO_write_base) + { + _IO_off64_t new_pos + = _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1); + if (new_pos == _IO_pos_BAD) + return 0; + fp->_offset = new_pos; + } + count = _IO_SYSWRITE (fp, data, to_do); + if (fp->_cur_column && count) + fp->_cur_column = INTUSE(_IO_adjust_column) (fp->_cur_column - 1, data, + count) + 1; + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); + fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base; + fp->_IO_write_end = (fp->_mode <= 0 + && (fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED)) + ? fp->_IO_buf_base : fp->_IO_buf_end); + return count; +} + +int +_IO_new_file_underflow (fp) + _IO_FILE *fp; +{ + _IO_ssize_t count; +#if 0 + /* SysV does not make this test; take it out for compatibility */ + if (fp->_flags & _IO_EOF_SEEN) + return (EOF); +#endif + + if (fp->_flags & _IO_NO_READS) + { + fp->_flags |= _IO_ERR_SEEN; + __set_errno (EBADF); + return EOF; + } + if (fp->_IO_read_ptr < fp->_IO_read_end) + return *(unsigned char *) fp->_IO_read_ptr; + + if (fp->_IO_buf_base == NULL) + { + /* Maybe we already have a push back pointer. */ + if (fp->_IO_save_base != NULL) + { + free (fp->_IO_save_base); + fp->_flags &= ~_IO_IN_BACKUP; + } + INTUSE(_IO_doallocbuf) (fp); + } + + /* Flush all line buffered files before reading. */ + /* FIXME This can/should be moved to genops ?? */ + if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED)) + { +#if 0 + INTUSE(_IO_flush_all_linebuffered) (); +#else + /* We used to flush all line-buffered stream. This really isn't + required by any standard. My recollection is that + traditional Unix systems did this for stdout. stderr better + not be line buffered. So we do just that here + explicitly. --drepper */ + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _IO_stdout); + _IO_flockfile (_IO_stdout); + + if ((_IO_stdout->_flags & (_IO_LINKED | _IO_NO_WRITES | _IO_LINE_BUF)) + == (_IO_LINKED | _IO_LINE_BUF)) + _IO_OVERFLOW (_IO_stdout, EOF); + + _IO_funlockfile (_IO_stdout); + _IO_cleanup_region_end (0); +#endif + } + + INTUSE(_IO_switch_to_get_mode) (fp); + + /* This is very tricky. We have to adjust those + pointers before we call _IO_SYSREAD () since + we may longjump () out while waiting for + input. Those pointers may be screwed up. H.J. */ + fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base; + fp->_IO_read_end = fp->_IO_buf_base; + fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end + = fp->_IO_buf_base; + + count = _IO_SYSREAD (fp, fp->_IO_buf_base, + fp->_IO_buf_end - fp->_IO_buf_base); + if (count <= 0) + { + if (count == 0) + fp->_flags |= _IO_EOF_SEEN; + else + fp->_flags |= _IO_ERR_SEEN, count = 0; + } + fp->_IO_read_end += count; + if (count == 0) + return EOF; + if (fp->_offset != _IO_pos_BAD) + _IO_pos_adjust (fp->_offset, count); + return *(unsigned char *) fp->_IO_read_ptr; +} +INTDEF2(_IO_new_file_underflow, _IO_file_underflow) + +#ifdef HAVE_MMAP +/* Guts of underflow callback if we mmap the file. This stats the file and + updates the stream state to match. In the normal case we return zero. + If the file is no longer eligible for mmap, its jump tables are reset to + the vanilla ones and we return nonzero. */ +static int +mmap_remap_check (_IO_FILE *fp) +{ + struct _G_stat64 st; + + if (_IO_SYSSTAT (fp, &st) == 0 + && S_ISREG (st.st_mode) && st.st_size != 0 + /* Limit the file size to 1MB for 32-bit machines. */ + && (sizeof (ptrdiff_t) > 4 || st.st_size < 1*1024*1024)) + { + const size_t pagesize = __getpagesize (); +# define ROUNDED(x) (((x) + pagesize - 1) & ~(pagesize - 1)) + if (ROUNDED (st.st_size) < ROUNDED (fp->_IO_buf_end + - fp->_IO_buf_base)) + { + /* We can trim off some pages past the end of the file. */ + (void) __munmap (fp->_IO_buf_base + ROUNDED (st.st_size), + ROUNDED (fp->_IO_buf_end - fp->_IO_buf_base) + - ROUNDED (st.st_size)); + fp->_IO_buf_end = fp->_IO_buf_base + st.st_size; + } + else if (ROUNDED (st.st_size) > ROUNDED (fp->_IO_buf_end + - fp->_IO_buf_base)) + { + /* The file added some pages. We need to remap it. */ + void *p; +#if defined __linux__ /* XXX */ + p = __mremap (fp->_IO_buf_base, ROUNDED (fp->_IO_buf_end + - fp->_IO_buf_base), + ROUNDED (st.st_size), MREMAP_MAYMOVE); + if (p == MAP_FAILED) + { + (void) __munmap (fp->_IO_buf_base, + fp->_IO_buf_end - fp->_IO_buf_base); + goto punt; + } +#else + (void) __munmap (fp->_IO_buf_base, + fp->_IO_buf_end - fp->_IO_buf_base); +# ifdef _G_MMAP64 + p = _G_MMAP64 (NULL, st.st_size, PROT_READ, MAP_SHARED, + fp->_fileno, 0); +# else + p = __mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, + fp->_fileno, 0); +# endif + if (p == MAP_FAILED) + goto punt; +#endif + fp->_IO_buf_base = p; + fp->_IO_buf_end = fp->_IO_buf_base + st.st_size; + } + else + { + /* The number of pages didn't change. */ + fp->_IO_buf_end = fp->_IO_buf_base + st.st_size; + } +# undef ROUNDED + + fp->_offset -= fp->_IO_read_end - fp->_IO_read_ptr; + _IO_setg (fp, fp->_IO_buf_base, + fp->_offset < fp->_IO_buf_end - fp->_IO_buf_base + ? fp->_IO_buf_base + fp->_offset : fp->_IO_buf_end, + fp->_IO_buf_end); + + /* If we are already positioned at or past the end of the file, don't + change the current offset. If not, seek past what we have mapped, + mimicking the position left by a normal underflow reading into its + buffer until EOF. */ + + if (fp->_offset < fp->_IO_buf_end - fp->_IO_buf_base) + { + if ( +# ifdef _G_LSEEK64 + _G_LSEEK64 +# else + __lseek +# endif + (fp->_fileno, fp->_IO_buf_end - fp->_IO_buf_base, SEEK_SET) + != fp->_IO_buf_end - fp->_IO_buf_base) + fp->_flags |= _IO_ERR_SEEN; + else + fp->_offset = fp->_IO_buf_end - fp->_IO_buf_base; + } + + return 0; + } + else + { + /* Life is no longer good for mmap. Punt it. */ + (void) __munmap (fp->_IO_buf_base, + fp->_IO_buf_end - fp->_IO_buf_base); + punt: + fp->_IO_buf_base = fp->_IO_buf_end = NULL; + _IO_setg (fp, NULL, NULL, NULL); + if (fp->_mode <= 0) + _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &INTUSE(_IO_file_jumps); + else + _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_wfile_jumps; + fp->_wide_data->_wide_vtable = &_IO_wfile_jumps; + + return 1; + } +} + +/* Special callback replacing the underflow callbacks if we mmap the file. */ +int +_IO_file_underflow_mmap (_IO_FILE *fp) +{ + if (fp->_IO_read_ptr < fp->_IO_read_end) + return *(unsigned char *) fp->_IO_read_ptr; + + if (__builtin_expect (mmap_remap_check (fp), 0)) + /* We punted to the regular file functions. */ + return _IO_UNDERFLOW (fp); + + if (fp->_IO_read_ptr < fp->_IO_read_end) + return *(unsigned char *) fp->_IO_read_ptr; + + fp->_flags |= _IO_EOF_SEEN; + return EOF; +} + +static void +decide_maybe_mmap (_IO_FILE *fp) +{ + /* We use the file in read-only mode. This could mean we can + mmap the file and use it without any copying. But not all + file descriptors are for mmap-able objects and on 32-bit + machines we don't want to map files which are too large since + this would require too much virtual memory. */ + struct _G_stat64 st; + + if (_IO_SYSSTAT (fp, &st) == 0 + && S_ISREG (st.st_mode) && st.st_size != 0 + /* Limit the file size to 1MB for 32-bit machines. */ + && (sizeof (ptrdiff_t) > 4 || st.st_size < 1*1024*1024) + /* Sanity check. */ + && (fp->_offset == _IO_pos_BAD || fp->_offset <= st.st_size)) + { + /* Try to map the file. */ + void *p; + +# ifdef _G_MMAP64 + p = _G_MMAP64 (NULL, st.st_size, PROT_READ, MAP_SHARED, fp->_fileno, 0); +# else + p = __mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fp->_fileno, 0); +# endif + if (p != MAP_FAILED) + { + /* OK, we managed to map the file. Set the buffer up and use a + special jump table with simplified underflow functions which + never tries to read anything from the file. */ + + if ( +# ifdef _G_LSEEK64 + _G_LSEEK64 +# else + __lseek +# endif + (fp->_fileno, st.st_size, SEEK_SET) != st.st_size) + { + (void) __munmap (p, st.st_size); + fp->_offset = _IO_pos_BAD; + } + else + { + INTUSE(_IO_setb) (fp, p, (char *) p + st.st_size, 0); + + if (fp->_offset == _IO_pos_BAD) + fp->_offset = 0; + + _IO_setg (fp, p, p + fp->_offset, p + st.st_size); + fp->_offset = st.st_size; + + if (fp->_mode <= 0) + _IO_JUMPS ((struct _IO_FILE_plus *)fp) = &_IO_file_jumps_mmap; + else + _IO_JUMPS ((struct _IO_FILE_plus *)fp) = &_IO_wfile_jumps_mmap; + fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap; + + return; + } + } + } + + /* We couldn't use mmap, so revert to the vanilla file operations. */ + + if (fp->_mode <= 0) + _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &INTUSE(_IO_file_jumps); + else + _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_wfile_jumps; + fp->_wide_data->_wide_vtable = &_IO_wfile_jumps; +} + +int +_IO_file_underflow_maybe_mmap (_IO_FILE *fp) +{ + /* This is the first read attempt. Choose mmap or vanilla operations + and then punt to the chosen underflow routine. */ + decide_maybe_mmap (fp); + return _IO_UNDERFLOW (fp); +} +#endif /* HAVE_MMAP */ + + +int +_IO_new_file_overflow (f, ch) + _IO_FILE *f; + int ch; +{ + if (f->_flags & _IO_NO_WRITES) /* SET ERROR */ + { + f->_flags |= _IO_ERR_SEEN; + __set_errno (EBADF); + return EOF; + } + /* If currently reading or no buffer allocated. */ + if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0 || f->_IO_write_base == 0) + { + /* Allocate a buffer if needed. */ + if (f->_IO_write_base == 0) + { + INTUSE(_IO_doallocbuf) (f); + _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base); + } + /* Otherwise must be currently reading. + If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end, + logically slide the buffer forwards one block (by setting the + read pointers to all point at the beginning of the block). This + makes room for subsequent output. + Otherwise, set the read pointers to _IO_read_end (leaving that + alone, so it can continue to correspond to the external position). */ + if (f->_IO_read_ptr == f->_IO_buf_end) + f->_IO_read_end = f->_IO_read_ptr = f->_IO_buf_base; + f->_IO_write_ptr = f->_IO_read_ptr; + f->_IO_write_base = f->_IO_write_ptr; + f->_IO_write_end = f->_IO_buf_end; + f->_IO_read_base = f->_IO_read_ptr = f->_IO_read_end; + + f->_flags |= _IO_CURRENTLY_PUTTING; + if (f->_mode <= 0 && f->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED)) + f->_IO_write_end = f->_IO_write_ptr; + } + if (ch == EOF) + return INTUSE(_IO_do_write) (f, f->_IO_write_base, + f->_IO_write_ptr - f->_IO_write_base); + if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */ + if (_IO_do_flush (f) == EOF) + return EOF; + *f->_IO_write_ptr++ = ch; + if ((f->_flags & _IO_UNBUFFERED) + || ((f->_flags & _IO_LINE_BUF) && ch == '\n')) + if (INTUSE(_IO_do_write) (f, f->_IO_write_base, + f->_IO_write_ptr - f->_IO_write_base) == EOF) + return EOF; + return (unsigned char) ch; +} +INTDEF2(_IO_new_file_overflow, _IO_file_overflow) + +int +_IO_new_file_sync (fp) + _IO_FILE *fp; +{ + _IO_ssize_t delta; + int retval = 0; + + /* char* ptr = cur_ptr(); */ + if (fp->_IO_write_ptr > fp->_IO_write_base) + if (_IO_do_flush(fp)) return EOF; + delta = fp->_IO_read_ptr - fp->_IO_read_end; + if (delta != 0) + { +#ifdef TODO + if (_IO_in_backup (fp)) + delta -= eGptr () - Gbase (); +#endif + _IO_off64_t new_pos = _IO_SYSSEEK (fp, delta, 1); + if (new_pos != (_IO_off64_t) EOF) + fp->_IO_read_end = fp->_IO_read_ptr; +#ifdef ESPIPE + else if (errno == ESPIPE) + ; /* Ignore error from unseekable devices. */ +#endif + else + retval = EOF; + } + if (retval != EOF) + fp->_offset = _IO_pos_BAD; + /* FIXME: Cleanup - can this be shared? */ + /* setg(base(), ptr, ptr); */ + return retval; +} +INTDEF2(_IO_new_file_sync, _IO_file_sync) + +#ifdef HAVE_MMAP +static int +_IO_file_sync_mmap (_IO_FILE *fp) +{ + if (fp->_IO_read_ptr != fp->_IO_read_end) + { +#ifdef TODO + if (_IO_in_backup (fp)) + delta -= eGptr () - Gbase (); +#endif + if ( +# ifdef _G_LSEEK64 + _G_LSEEK64 +# else + __lseek +# endif + (fp->_fileno, fp->_IO_read_ptr - fp->_IO_buf_base, SEEK_SET) + != fp->_IO_read_ptr - fp->_IO_buf_base) + { + fp->_flags |= _IO_ERR_SEEN; + return EOF; + } + } + fp->_offset = fp->_IO_read_ptr - fp->_IO_buf_base; + fp->_IO_read_end = fp->_IO_read_ptr = fp->_IO_read_base; + return 0; +} +#endif /* HAVE_MMAP */ + + +_IO_off64_t +_IO_new_file_seekoff (fp, offset, dir, mode) + _IO_FILE *fp; + _IO_off64_t offset; + int dir; + int mode; +{ + _IO_off64_t result; + _IO_off64_t delta, new_offset; + long count; + /* POSIX.1 8.2.3.7 says that after a call the fflush() the file + offset of the underlying file must be exact. */ + int must_be_exact = (fp->_IO_read_base == fp->_IO_read_end + && fp->_IO_write_base == fp->_IO_write_ptr); + + if (mode == 0) + dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */ + + /* Flush unwritten characters. + (This may do an unneeded write if we seek within the buffer. + But to be able to switch to reading, we would need to set + egptr to ptr. That can't be done in the current design, + which assumes file_ptr() is eGptr. Anyway, since we probably + end up flushing when we close(), it doesn't make much difference.) + FIXME: simulate mem-papped files. */ + + if (fp->_IO_write_ptr > fp->_IO_write_base || _IO_in_put_mode (fp)) + if (INTUSE(_IO_switch_to_get_mode) (fp)) + return EOF; + + if (fp->_IO_buf_base == NULL) + { + /* It could be that we already have a pushback buffer. */ + if (fp->_IO_read_base != NULL) + { + free (fp->_IO_read_base); + fp->_flags &= ~_IO_IN_BACKUP; + } + INTUSE(_IO_doallocbuf) (fp); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); + } + + switch (dir) + { + case _IO_seek_cur: + /* Adjust for read-ahead (bytes is buffer). */ + offset -= fp->_IO_read_end - fp->_IO_read_ptr; + if (fp->_offset == _IO_pos_BAD) + goto dumb; + /* Make offset absolute, assuming current pointer is file_ptr(). */ + offset += fp->_offset; + if (offset < 0) + { + __set_errno (EINVAL); + return EOF; + } + + dir = _IO_seek_set; + break; + case _IO_seek_set: + break; + case _IO_seek_end: + { + struct _G_stat64 st; + if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode)) + { + offset += st.st_size; + dir = _IO_seek_set; + } + else + goto dumb; + } + } + /* At this point, dir==_IO_seek_set. */ + + /* If we are only interested in the current position we've found it now. */ + if (mode == 0) + return offset; + + /* If destination is within current buffer, optimize: */ + if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL + && !_IO_in_backup (fp)) + { + /* Offset relative to start of main get area. */ + _IO_off64_t rel_offset = (offset - fp->_offset + + (fp->_IO_read_end - fp->_IO_read_base)); + if (rel_offset >= 0) + { +#if 0 + if (_IO_in_backup (fp)) + _IO_switch_to_main_get_area (fp); +#endif + if (rel_offset <= fp->_IO_read_end - fp->_IO_read_base) + { + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + rel_offset, + fp->_IO_read_end); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + { + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + goto resync; + } + } +#ifdef TODO + /* If we have streammarkers, seek forward by reading ahead. */ + if (_IO_have_markers (fp)) + { + int to_skip = rel_offset + - (fp->_IO_read_ptr - fp->_IO_read_base); + if (ignore (to_skip) != to_skip) + goto dumb; + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + goto resync; + } +#endif + } +#ifdef TODO + if (rel_offset < 0 && rel_offset >= Bbase () - Bptr ()) + { + if (!_IO_in_backup (fp)) + _IO_switch_to_backup_area (fp); + gbump (fp->_IO_read_end + rel_offset - fp->_IO_read_ptr); + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + goto resync; + } +#endif + } + +#ifdef TODO + INTUSE(_IO_unsave_markers) (fp); +#endif + + if (fp->_flags & _IO_NO_READS) + goto dumb; + + /* Try to seek to a block boundary, to improve kernel page management. */ + new_offset = offset & ~(fp->_IO_buf_end - fp->_IO_buf_base - 1); + delta = offset - new_offset; + if (delta > fp->_IO_buf_end - fp->_IO_buf_base) + { + new_offset = offset; + delta = 0; + } + result = _IO_SYSSEEK (fp, new_offset, 0); + if (result < 0) + return EOF; + if (delta == 0) + count = 0; + else + { + count = _IO_SYSREAD (fp, fp->_IO_buf_base, + (must_be_exact + ? delta : fp->_IO_buf_end - fp->_IO_buf_base)); + if (count < delta) + { + /* We weren't allowed to read, but try to seek the remainder. */ + offset = count == EOF ? delta : delta-count; + dir = _IO_seek_cur; + goto dumb; + } + } + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + delta, + fp->_IO_buf_base + count); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + fp->_offset = result + count; + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + return offset; + dumb: + + INTUSE(_IO_unsave_markers) (fp); + result = _IO_SYSSEEK (fp, offset, dir); + if (result != EOF) + { + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + fp->_offset = result; + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + } + return result; + +resync: + /* We need to do it since it is possible that the file offset in + the kernel may be changed behind our back. It may happen when + we fopen a file and then do a fork. One process may access the + the file and the kernel file offset will be changed. */ + if (fp->_offset >= 0) + _IO_SYSSEEK (fp, fp->_offset, 0); + + return offset; +} +INTDEF2(_IO_new_file_seekoff, _IO_file_seekoff) + +_IO_off64_t +_IO_file_seekoff_mmap (fp, offset, dir, mode) + _IO_FILE *fp; + _IO_off64_t offset; + int dir; + int mode; +{ + _IO_off64_t result; + + /* If we are only interested in the current position, calculate it and + return right now. This calculation does the right thing when we are + using a pushback buffer, but in the usual case has the same value as + (fp->_IO_read_ptr - fp->_IO_buf_base). */ + if (mode == 0) + return fp->_offset - (fp->_IO_read_end - fp->_IO_read_ptr); + + switch (dir) + { + case _IO_seek_cur: + /* Adjust for read-ahead (bytes is buffer). */ + offset += fp->_IO_read_ptr - fp->_IO_read_base; + break; + case _IO_seek_set: + break; + case _IO_seek_end: + offset += fp->_IO_buf_end - fp->_IO_buf_base; + break; + } + /* At this point, dir==_IO_seek_set. */ + + if (offset < 0) + { + /* No negative offsets are valid. */ + __set_errno (EINVAL); + return EOF; + } + + result = _IO_SYSSEEK (fp, offset, 0); + if (result < 0) + return EOF; + + if (offset > fp->_IO_buf_end - fp->_IO_buf_base) + /* One can fseek arbitrarily past the end of the file + and it is meaningless until one attempts to read. + Leave the buffer pointers in EOF state until underflow. */ + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_end, fp->_IO_buf_end); + else + /* Adjust the read pointers to match the file position, + but so the next read attempt will call underflow. */ + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + offset, + fp->_IO_buf_base + offset); + + fp->_offset = result; + + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + + return offset; +} + +#ifdef HAVE_MMAP +static _IO_off64_t +_IO_file_seekoff_maybe_mmap (_IO_FILE *fp, _IO_off64_t offset, int dir, + int mode) +{ + /* We only get here when we haven't tried to read anything yet. + So there is nothing more useful for us to do here than just + the underlying lseek call. */ + + _IO_off64_t result = _IO_SYSSEEK (fp, offset, dir); + if (result < 0) + return EOF; + + fp->_offset = result; + return result; +} +#endif /* HAVE_MMAP */ + +_IO_ssize_t +_IO_file_read (fp, buf, size) + _IO_FILE *fp; + void *buf; + _IO_ssize_t size; +{ + return read (fp->_fileno, buf, size); +} +INTDEF(_IO_file_read) + +_IO_off64_t +_IO_file_seek (fp, offset, dir) + _IO_FILE *fp; + _IO_off64_t offset; + int dir; +{ +#ifdef _G_LSEEK64 + return _G_LSEEK64 (fp->_fileno, offset, dir); +#else + return lseek (fp->_fileno, offset, dir); +#endif +} +INTDEF(_IO_file_seek) + +int +_IO_file_stat (fp, st) + _IO_FILE *fp; + void *st; +{ +#ifdef _G_FSTAT64 + return _G_FSTAT64 (fp->_fileno, (struct _G_stat64 *) st); +#else + return fstat (fp->_fileno, (struct stat *) st); +#endif +} +INTDEF(_IO_file_stat) + +#ifdef HAVE_MMAP +int +_IO_file_close_mmap (fp) + _IO_FILE *fp; +{ + /* In addition to closing the file descriptor we have to unmap the file. */ + (void) __munmap (fp->_IO_buf_base, fp->_IO_buf_end - fp->_IO_buf_base); + fp->_IO_buf_base = fp->_IO_buf_end = NULL; + return close (fp->_fileno); +} +#endif + +int +_IO_file_close (fp) + _IO_FILE *fp; +{ + return close (fp->_fileno); +} +INTDEF(_IO_file_close) + +_IO_ssize_t +_IO_new_file_write (f, data, n) + _IO_FILE *f; + const void *data; + _IO_ssize_t n; +{ + _IO_ssize_t to_do = n; + while (to_do > 0) + { + _IO_ssize_t count = write (f->_fileno, data, to_do); + if (count < 0) + { + f->_flags |= _IO_ERR_SEEN; + break; + } + to_do -= count; + data = (void *) ((char *) data + count); + } + n -= to_do; + if (f->_offset >= 0) + f->_offset += n; + return n; +} + +_IO_size_t +_IO_new_file_xsputn (f, data, n) + _IO_FILE *f; + const void *data; + _IO_size_t n; +{ + register const char *s = (const char *) data; + _IO_size_t to_do = n; + int must_flush = 0; + _IO_size_t count; + + if (n <= 0) + return 0; + /* This is an optimized implementation. + If the amount to be written straddles a block boundary + (or the filebuf is unbuffered), use sys_write directly. */ + + /* First figure out how much space is available in the buffer. */ + count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */ + if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING)) + { + count = f->_IO_buf_end - f->_IO_write_ptr; + if (count >= n) + { + register const char *p; + for (p = s + n; p > s; ) + { + if (*--p == '\n') + { + count = p - s + 1; + must_flush = 1; + break; + } + } + } + } + /* Then fill the buffer. */ + if (count > 0) + { + if (count > to_do) + count = to_do; + if (count > 20) + { +#ifdef _LIBC + f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count); +#else + memcpy (f->_IO_write_ptr, s, count); + f->_IO_write_ptr += count; +#endif + s += count; + } + else + { + register char *p = f->_IO_write_ptr; + register int i = (int) count; + while (--i >= 0) + *p++ = *s++; + f->_IO_write_ptr = p; + } + to_do -= count; + } + if (to_do + must_flush > 0) + { + _IO_size_t block_size, do_write; + /* Next flush the (full) buffer. */ + if (_IO_OVERFLOW (f, EOF) == EOF) + return n - to_do; + + /* Try to maintain alignment: write a whole number of blocks. + dont_write is what gets left over. */ + block_size = f->_IO_buf_end - f->_IO_buf_base; + do_write = to_do - (block_size >= 128 ? to_do % block_size : 0); + + if (do_write) + { + count = new_do_write (f, s, do_write); + to_do -= count; + if (count < do_write) + return n - to_do; + } + + /* Now write out the remainder. Normally, this will fit in the + buffer, but it's somewhat messier for line-buffered files, + so we let _IO_default_xsputn handle the general case. */ + if (to_do) + to_do -= INTUSE(_IO_default_xsputn) (f, s+do_write, to_do); + } + return n - to_do; +} +INTDEF2(_IO_new_file_xsputn, _IO_file_xsputn) + +_IO_size_t +_IO_file_xsgetn (fp, data, n) + _IO_FILE *fp; + void *data; + _IO_size_t n; +{ + register _IO_size_t want, have; + register _IO_ssize_t count; + register char *s = data; + + want = n; + + if (fp->_IO_buf_base == NULL) + { + /* Maybe we already have a push back pointer. */ + if (fp->_IO_save_base != NULL) + { + free (fp->_IO_save_base); + fp->_flags &= ~_IO_IN_BACKUP; + } + INTUSE(_IO_doallocbuf) (fp); + } + + while (want > 0) + { + have = fp->_IO_read_end - fp->_IO_read_ptr; + if (want <= have) + { + memcpy (s, fp->_IO_read_ptr, want); + fp->_IO_read_ptr += want; + want = 0; + } + else + { + if (have > 0) + { +#ifdef _LIBC + s = __mempcpy (s, fp->_IO_read_ptr, have); +#else + memcpy (s, fp->_IO_read_ptr, have); + s += have; +#endif + want -= have; + fp->_IO_read_ptr += have; + } + + /* Check for backup and repeat */ + if (_IO_in_backup (fp)) + { + _IO_switch_to_main_get_area (fp); + continue; + } + + /* If we now want less than a buffer, underflow and repeat + the copy. Otherwise, _IO_SYSREAD directly to + the user buffer. */ + if (fp->_IO_buf_base + && want < (size_t) (fp->_IO_buf_end - fp->_IO_buf_base)) + { + if (__underflow (fp) == EOF) + break; + + continue; + } + + /* These must be set before the sysread as we might longjmp out + waiting for input. */ + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + + /* Try to maintain alignment: read a whole number of blocks. */ + count = want; + if (fp->_IO_buf_base) + { + _IO_size_t block_size = fp->_IO_buf_end - fp->_IO_buf_base; + if (block_size >= 128) + count -= want % block_size; + } + + count = _IO_SYSREAD (fp, s, count); + if (count <= 0) + { + if (count == 0) + fp->_flags |= _IO_EOF_SEEN; + else + fp->_flags |= _IO_ERR_SEEN; + + break; + } + + s += count; + want -= count; + if (fp->_offset != _IO_pos_BAD) + _IO_pos_adjust (fp->_offset, count); + } + } + + return n - want; +} +INTDEF(_IO_file_xsgetn) + +#ifdef HAVE_MMAP +static _IO_size_t _IO_file_xsgetn_mmap __P ((_IO_FILE *, void *, _IO_size_t)); +static _IO_size_t +_IO_file_xsgetn_mmap (fp, data, n) + _IO_FILE *fp; + void *data; + _IO_size_t n; +{ + register _IO_size_t have; + char *read_ptr = fp->_IO_read_ptr; + register char *s = (char *) data; + + have = fp->_IO_read_end - fp->_IO_read_ptr; + + if (have < n) + { + if (__builtin_expect (_IO_in_backup (fp), 0)) + { +#ifdef _LIBC + s = __mempcpy (s, read_ptr, have); +#else + memcpy (s, read_ptr, have); + s += have; +#endif + n -= have; + _IO_switch_to_main_get_area (fp); + read_ptr = fp->_IO_read_ptr; + have = fp->_IO_read_end - fp->_IO_read_ptr; + } + + if (have < n) + { + /* Check that we are mapping all of the file, in case it grew. */ + if (__builtin_expect (mmap_remap_check (fp), 0)) + /* We punted mmap, so complete with the vanilla code. */ + return s - (char *) data + _IO_XSGETN (fp, data, n); + + read_ptr = fp->_IO_read_ptr; + have = fp->_IO_read_end - read_ptr; + } + } + + if (have < n) + fp->_flags |= _IO_EOF_SEEN; + + if (have != 0) + { + have = MIN (have, n); +#ifdef _LIBC + s = __mempcpy (s, read_ptr, have); +#else + memcpy (s, read_ptr, have); + s += have; +#endif + fp->_IO_read_ptr = read_ptr + have; + } + + return s - (char *) data; +} + +static _IO_size_t _IO_file_xsgetn_maybe_mmap __P ((_IO_FILE *, void *, + _IO_size_t)); +static _IO_size_t +_IO_file_xsgetn_maybe_mmap (fp, data, n) + _IO_FILE *fp; + void *data; + _IO_size_t n; +{ + /* We only get here if this is the first attempt to read something. + Decide which operations to use and then punt to the chosen one. */ + + decide_maybe_mmap (fp); + return _IO_XSGETN (fp, data, n); +} +#endif /* HAVE_MMAP */ + +#ifdef _LIBC +# undef _IO_do_write +versioned_symbol (libc, _IO_new_do_write, _IO_do_write, GLIBC_2_1); +versioned_symbol (libc, _IO_new_file_attach, _IO_file_attach, GLIBC_2_1); +versioned_symbol (libc, _IO_new_file_close_it, _IO_file_close_it, GLIBC_2_1); +versioned_symbol (libc, _IO_new_file_finish, _IO_file_finish, GLIBC_2_1); +versioned_symbol (libc, _IO_new_file_fopen, _IO_file_fopen, GLIBC_2_1); +versioned_symbol (libc, _IO_new_file_init, _IO_file_init, GLIBC_2_1); +versioned_symbol (libc, _IO_new_file_setbuf, _IO_file_setbuf, GLIBC_2_1); +versioned_symbol (libc, _IO_new_file_sync, _IO_file_sync, GLIBC_2_1); +versioned_symbol (libc, _IO_new_file_overflow, _IO_file_overflow, GLIBC_2_1); +versioned_symbol (libc, _IO_new_file_seekoff, _IO_file_seekoff, GLIBC_2_1); +versioned_symbol (libc, _IO_new_file_underflow, _IO_file_underflow, GLIBC_2_1); +versioned_symbol (libc, _IO_new_file_write, _IO_file_write, GLIBC_2_1); +versioned_symbol (libc, _IO_new_file_xsputn, _IO_file_xsputn, GLIBC_2_1); +#endif + +struct _IO_jump_t _IO_file_jumps = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, INTUSE(_IO_file_finish)), + JUMP_INIT(overflow, INTUSE(_IO_file_overflow)), + JUMP_INIT(underflow, INTUSE(_IO_file_underflow)), + JUMP_INIT(uflow, INTUSE(_IO_default_uflow)), + JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)), + JUMP_INIT(xsputn, INTUSE(_IO_file_xsputn)), + JUMP_INIT(xsgetn, INTUSE(_IO_file_xsgetn)), + JUMP_INIT(seekoff, _IO_new_file_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_new_file_setbuf), + JUMP_INIT(sync, _IO_new_file_sync), + JUMP_INIT(doallocate, INTUSE(_IO_file_doallocate)), + JUMP_INIT(read, INTUSE(_IO_file_read)), + JUMP_INIT(write, _IO_new_file_write), + JUMP_INIT(seek, INTUSE(_IO_file_seek)), + JUMP_INIT(close, INTUSE(_IO_file_close)), + JUMP_INIT(stat, INTUSE(_IO_file_stat)), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; +INTVARDEF(_IO_file_jumps) + +#ifdef HAVE_MMAP +struct _IO_jump_t _IO_file_jumps_mmap = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, INTUSE(_IO_file_finish)), + JUMP_INIT(overflow, INTUSE(_IO_file_overflow)), + JUMP_INIT(underflow, _IO_file_underflow_mmap), + JUMP_INIT(uflow, INTUSE(_IO_default_uflow)), + JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)), + JUMP_INIT(xsputn, _IO_new_file_xsputn), + JUMP_INIT(xsgetn, _IO_file_xsgetn_mmap), + JUMP_INIT(seekoff, _IO_file_seekoff_mmap), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_file_setbuf_mmap), + JUMP_INIT(sync, _IO_file_sync_mmap), + JUMP_INIT(doallocate, INTUSE(_IO_file_doallocate)), + JUMP_INIT(read, INTUSE(_IO_file_read)), + JUMP_INIT(write, _IO_new_file_write), + JUMP_INIT(seek, INTUSE(_IO_file_seek)), + JUMP_INIT(close, _IO_file_close_mmap), + JUMP_INIT(stat, INTUSE(_IO_file_stat)), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; + +struct _IO_jump_t _IO_file_jumps_maybe_mmap = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, INTUSE(_IO_file_finish)), + JUMP_INIT(overflow, INTUSE(_IO_file_overflow)), + JUMP_INIT(underflow, _IO_file_underflow_maybe_mmap), + JUMP_INIT(uflow, INTUSE(_IO_default_uflow)), + JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)), + JUMP_INIT(xsputn, _IO_new_file_xsputn), + JUMP_INIT(xsgetn, _IO_file_xsgetn_maybe_mmap), + JUMP_INIT(seekoff, _IO_file_seekoff_maybe_mmap), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_file_setbuf_mmap), + JUMP_INIT(sync, _IO_new_file_sync), + JUMP_INIT(doallocate, INTUSE(_IO_file_doallocate)), + JUMP_INIT(read, INTUSE(_IO_file_read)), + JUMP_INIT(write, _IO_new_file_write), + JUMP_INIT(seek, INTUSE(_IO_file_seek)), + JUMP_INIT(close, _IO_file_close), + JUMP_INIT(stat, INTUSE(_IO_file_stat)), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; +#endif /* HAVE_MMAP */ diff --git a/src/kernel/libroot/posix/glibc/libio/fmemopen.c b/src/kernel/libroot/posix/glibc/libio/fmemopen.c new file mode 100644 index 0000000000..ab6ffdd678 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/fmemopen.c @@ -0,0 +1,243 @@ +/* Fmemopen implementation. + Copyright (C) 2000, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Hanno Mueller, kontakt@hanno.de, 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* + * fmemopen() - "my" version of a string stream + * Hanno Mueller, kontakt@hanno.de + * + * + * I needed fmemopen() for an application that I currently work on, + * but couldn't find it in libio. The following snippet of code is an + * attempt to implement what glibc's documentation describes. + * + * No, it isn't really tested yet. :-) + * + * + * + * I already see some potential problems: + * + * - I never used the "original" fmemopen(). I am sure that "my" + * fmemopen() behaves differently than the original version. + * + * - The documentation doesn't say wether a string stream allows + * seeks. I checked the old fmemopen implementation in glibc's stdio + * directory, wasn't quite able to see what is going on in that + * source, but as far as I understand there was no seek there. For + * my application, I needed fseek() and ftell(), so it's here. + * + * - "append" mode and fseek(p, SEEK_END) have two different ideas + * about the "end" of the stream. + * + * As described in the documentation, when opening the file in + * "append" mode, the position pointer will be set to the first null + * character of the string buffer (yet the buffer may already + * contain more data). For fseek(), the last byte of the buffer is + * used as the end of the stream. + * + * - It is unclear to me what the documentation tries to say when it + * explains what happens when you use fmemopen with a NULL + * buffer. + * + * Quote: "fmemopen [then] allocates an array SIZE bytes long. This + * is really only useful if you are going to write things to the + * buffer and then read them back in again." + * + * What does that mean if the original fmemopen() did not allow + * seeking? How do you read what you just wrote without seeking back + * to the beginning of the stream? + * + * - I think there should be a second version of fmemopen() that does + * not add null characters for each write. (At least in my + * application, I am not actually using strings but binary data and + * so I don't need the stream to add null characters on its own.) + */ + +#include +#include +#include +#include +#include +#include +#include "libioP.h" + + +typedef struct fmemopen_cookie_struct fmemopen_cookie_t; +struct fmemopen_cookie_struct +{ + char *buffer; + int mybuffer; + size_t size; + _IO_off64_t pos; + size_t maxpos; +}; + + +static ssize_t +fmemopen_read (void *cookie, char *b, size_t s) +{ + fmemopen_cookie_t *c; + + c = (fmemopen_cookie_t *) cookie; + + if (c->pos + s > c->size) + { + if ((size_t) c->pos == c->size) + return 0; + s = c->size - c->pos; + } + + memcpy (b, &(c->buffer[c->pos]), s); + + c->pos += s; + if ((size_t) c->pos > c->maxpos) + c->maxpos = c->pos; + + return s; +} + + +static ssize_t +fmemopen_write (void *cookie, const char *b, size_t s) +{ + fmemopen_cookie_t *c; + int addnullc; + + c = (fmemopen_cookie_t *) cookie; + + addnullc = s == 0 || b[s - 1] != '\0'; + + if (c->pos + s + addnullc > c->size) + { + if ((size_t) (c->pos + addnullc) == c->size) + { + __set_errno (ENOSPC); + return -1; + } + s = c->size - c->pos - addnullc; + } + + memcpy (&(c->buffer[c->pos]), b, s); + + c->pos += s; + if ((size_t) c->pos > c->maxpos) + { + c->maxpos = c->pos; + if (addnullc) + c->buffer[c->maxpos] = '\0'; + } + + return s; +} + + +static int +fmemopen_seek (void *cookie, _IO_off64_t *p, int w) +{ + _IO_off64_t np; + fmemopen_cookie_t *c; + + c = (fmemopen_cookie_t *) cookie; + + switch (w) + { + case SEEK_SET: + np = *p; + break; + + case SEEK_CUR: + np = c->pos + *p; + break; + + case SEEK_END: + np = c->size - *p; + break; + + default: + return -1; + } + + if (np < 0 || (size_t) np > c->size) + return -1; + + c->pos = np; + + return np; +} + + +static int +fmemopen_close (void *cookie) +{ + fmemopen_cookie_t *c; + + c = (fmemopen_cookie_t *) cookie; + + if (c->mybuffer) + free (c->buffer); + free (c); + + return 0; +} + + +FILE * +fmemopen (void *buf, size_t len, const char *mode) +{ + cookie_io_functions_t iof; + fmemopen_cookie_t *c; + + c = (fmemopen_cookie_t *) malloc (sizeof (fmemopen_cookie_t)); + if (c == NULL) + return NULL; + + c->mybuffer = (buf == NULL); + + if (c->mybuffer) + { + c->buffer = (char *) malloc (len); + if (c->buffer == NULL) + { + free (c); + return NULL; + } + c->buffer[0] = '\0'; + } + else + c->buffer = buf; + + c->size = len; + + if (mode[0] == 'w') + c->buffer[0] = '\0'; + + c->maxpos = strlen (c->buffer); + + if (mode[0] == 'a') + c->pos = c->maxpos; + else + c->pos = 0; + + iof.read = fmemopen_read; + iof.write = fmemopen_write; + iof.seek = fmemopen_seek; + iof.close = fmemopen_close; + + return _IO_fopencookie (c, mode, iof); +} diff --git a/src/kernel/libroot/posix/glibc/libio/fputc.c b/src/kernel/libroot/posix/glibc/libio/fputc.c new file mode 100644 index 0000000000..5ef048ff41 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/fputc.c @@ -0,0 +1,49 @@ +/* Copyright (C) 1993, 1996, 1997, 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +int +fputc (c, fp) + int c; + _IO_FILE *fp; +{ + int result; + CHECK_FILE (fp, EOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + result = _IO_putc_unlocked (c, fp); + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} + +#if defined weak_alias && !defined _IO_MTSAFE_IO +#undef fputc_unlocked +weak_alias (fputc, fputc_unlocked) +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/fputc_u.c b/src/kernel/libroot/posix/glibc/libio/fputc_u.c new file mode 100644 index 0000000000..406b7da2c4 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/fputc_u.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +#undef fputc_unlocked + +int +fputc_unlocked (c, fp) + int c; + _IO_FILE *fp; +{ + CHECK_FILE (fp, EOF); + return _IO_putc_unlocked (c, fp); +} diff --git a/src/kernel/libroot/posix/glibc/libio/fputwc.c b/src/kernel/libroot/posix/glibc/libio/fputwc.c new file mode 100644 index 0000000000..600d7307c7 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/fputwc.c @@ -0,0 +1,47 @@ +/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +wint_t +fputwc (wc, fp) + wchar_t wc; + _IO_FILE *fp; +{ + int result; + CHECK_FILE (fp, EOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + if (_IO_fwide (fp, 1) < 0) + result = WEOF; + else + result = _IO_putwc_unlocked (wc, fp); + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} diff --git a/src/kernel/libroot/posix/glibc/libio/fputwc_u.c b/src/kernel/libroot/posix/glibc/libio/fputwc_u.c new file mode 100644 index 0000000000..93cbcab3d3 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/fputwc_u.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1993, 1996, 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +#undef fputwc_unlocked + +wint_t +fputwc_unlocked (wc, fp) + wchar_t wc; + _IO_FILE *fp; +{ + CHECK_FILE (fp, EOF); + if (_IO_fwide (fp, 1) < 0) + return WEOF; + return _IO_putwc_unlocked (wc, fp); +} diff --git a/src/kernel/libroot/posix/glibc/libio/freopen.c b/src/kernel/libroot/posix/glibc/libio/freopen.c new file mode 100644 index 0000000000..244a90d84e --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/freopen.c @@ -0,0 +1,89 @@ +/* Copyright (C) 1993,95,96,97,98,2000,2001,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" +#include + +#include +#include + +FILE* +freopen (filename, mode, fp) + const char* filename; + const char* mode; + FILE* fp; +{ + FILE *result; + int fd = -1; + CHECK_FILE (fp, NULL); + if (!(fp->_flags & _IO_IS_FILEBUF)) + return NULL; + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + if (filename == NULL && _IO_fileno (fp) >= 0) + { + fd = __dup (_IO_fileno (fp)); + if (fd != -1) + filename = fd_to_filename (fd); + } +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + if (&_IO_stdin_used == NULL) + { + /* If the shared C library is used by the application binary which + was linked against the older version of libio, we just use the + older one even for internal use to avoid trouble since a pointer + to the old libio may be passed into shared C library and wind + up here. */ + _IO_old_file_close_it (fp); + _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_old_file_jumps; + result = _IO_old_file_fopen (fp, filename, mode); + } + else +#endif + { + INTUSE(_IO_file_close_it) (fp); + _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &INTUSE(_IO_file_jumps); + if (fp->_vtable_offset == 0 && fp->_wide_data != NULL) + fp->_wide_data->_wide_vtable = &INTUSE(_IO_wfile_jumps); + result = INTUSE(_IO_file_fopen) (fp, filename, mode, 1); + if (result != NULL) + result = __fopen_maybe_mmap (result); + } + if (result != NULL) + /* unbound stream orientation */ + result->_mode = 0; + if (fd != -1) + { + __close (fd); + if (filename != NULL) + free ((char *) filename); + } + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} diff --git a/src/kernel/libroot/posix/glibc/libio/freopen64.c b/src/kernel/libroot/posix/glibc/libio/freopen64.c new file mode 100644 index 0000000000..8f69fce2ce --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/freopen64.c @@ -0,0 +1,78 @@ +/* Copyright (C) 1993,1995,1996,1997,1998,2000,2001,2002 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" +#include + +#include + +FILE * +freopen64 (filename, mode, fp) + const char* filename; + const char* mode; + FILE *fp; +{ +#ifdef _G_OPEN64 + FILE *result; + int fd = -1; + CHECK_FILE (fp, NULL); + if (!(fp->_flags & _IO_IS_FILEBUF)) + return NULL; + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + if (filename == NULL && _IO_fileno (fp) >= 0) + { + fd = __dup (_IO_fileno (fp)); + if (fd != -1) + filename = fd_to_filename (fd); + } + INTUSE(_IO_file_close_it) (fp); + _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &INTUSE(_IO_file_jumps); + if (fp->_vtable_offset == 0 && fp->_wide_data != NULL) + fp->_wide_data->_wide_vtable = &INTUSE(_IO_wfile_jumps); + result = INTUSE(_IO_file_fopen) (fp, filename, mode, 0); + if (result != NULL) + result = __fopen_maybe_mmap (result); + if (result != NULL) + /* unbound stream orientation */ + result->_mode = 0; + if (fd != -1) + { + __close (fd); + if (filename != NULL) + free ((char *) filename); + } + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +#else + __set_errno (ENOSYS); + return NULL; +#endif +} diff --git a/src/kernel/libroot/posix/glibc/libio/fseek.c b/src/kernel/libroot/posix/glibc/libio/fseek.c new file mode 100644 index 0000000000..831a4d497b --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/fseek.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1993,1995,1996,1997,1998,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +int +fseek (fp, offset, whence) + _IO_FILE* fp; + long int offset; + int whence; +{ + int result; + CHECK_FILE (fp, -1); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + result = _IO_fseek (fp, offset, whence); + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} +libc_hidden_def (fseek) diff --git a/src/kernel/libroot/posix/glibc/libio/fseeko.c b/src/kernel/libroot/posix/glibc/libio/fseeko.c new file mode 100644 index 0000000000..8087b957d2 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/fseeko.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +int +fseeko (fp, offset, whence) + _IO_FILE* fp; + off_t offset; + int whence; +{ + int result; + CHECK_FILE (fp, -1); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + result = _IO_fseek (fp, offset, whence); + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} diff --git a/src/kernel/libroot/posix/glibc/libio/fseeko64.c b/src/kernel/libroot/posix/glibc/libio/fseeko64.c new file mode 100644 index 0000000000..149e70190f --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/fseeko64.c @@ -0,0 +1,51 @@ +/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include +#include "libioP.h" +#include "stdio.h" + +int +fseeko64 (fp, offset, whence) + _IO_FILE* fp; + __off64_t offset; + int whence; +{ +#ifdef _G_LSEEK64 + int result; + CHECK_FILE (fp, -1); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + result = _IO_fseek (fp, offset, whence); + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +#else + __set_errno (ENOSYS); + return -1; +#endif +} diff --git a/src/kernel/libroot/posix/glibc/libio/ftello.c b/src/kernel/libroot/posix/glibc/libio/ftello.c new file mode 100644 index 0000000000..3e6f2761b8 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/ftello.c @@ -0,0 +1,66 @@ +/* Copyright (C) 1993, 1995-2001, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include +#include +#include +#include + + +off_t +ftello (fp) + _IO_FILE *fp; +{ + _IO_off64_t pos; + CHECK_FILE (fp, -1L); + _IO_cleanup_region_start ((void (*) (void *)) _IO_funlockfile, fp); + _IO_flockfile (fp); + pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0); + if (_IO_in_backup (fp)) + { + if (fp->_mode <= 0) + pos -= fp->_IO_save_end - fp->_IO_save_base; + } + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + if (pos == _IO_pos_BAD) + { +#ifdef EIO + if (errno == 0) + __set_errno (EIO); +#endif + return -1L; + } + if ((_IO_off64_t) (off_t) pos != pos) + { +#ifdef EOVERFLOW + __set_errno (EOVERFLOW); +#endif + return -1L; + } + return pos; +} diff --git a/src/kernel/libroot/posix/glibc/libio/ftello64.c b/src/kernel/libroot/posix/glibc/libio/ftello64.c new file mode 100644 index 0000000000..b2da11d133 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/ftello64.c @@ -0,0 +1,64 @@ +/* Copyright (C) 1993, 1995-2001, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include +#include +#include +#include + + +off64_t +ftello64 (fp) + _IO_FILE *fp; +{ +#ifdef _G_LSEEK64 + _IO_off64_t pos; + CHECK_FILE (fp, -1L); + _IO_cleanup_region_start ((void (*) (void *)) _IO_funlockfile, fp); + _IO_flockfile (fp); + pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0); + if (_IO_in_backup (fp)) + { + if (fp->_mode <= 0) + pos -= fp->_IO_save_end - fp->_IO_save_base; + } + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + if (pos == _IO_pos_BAD) + { +#ifdef EIO + if (errno == 0) + __set_errno (EIO); +#endif + return -1L; + } + return pos; +#else + __set_errno (ENOSYS); + return -1; +#endif +} diff --git a/src/kernel/libroot/posix/glibc/libio/fwide.c b/src/kernel/libroot/posix/glibc/libio/fwide.c new file mode 100644 index 0000000000..c435e5ec17 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/fwide.c @@ -0,0 +1,56 @@ +/* Copyright (C) 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include +#include +#include + +int +fwide (fp, mode) + _IO_FILE *fp; + int mode; +{ + int result; + + /* Normalize the value. */ + mode = mode < 0 ? -1 : (mode == 0 ? 0 : 1); + + if (mode == 0 || fp->_mode != 0) + /* The caller simply wants to know about the current orientation + or the orientation already has been determined. */ + return fp->_mode; + + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + + result = _IO_fwide (fp, mode); + + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + + return result; +} diff --git a/src/kernel/libroot/posix/glibc/libio/fwprintf.c b/src/kernel/libroot/posix/glibc/libio/fwprintf.c new file mode 100644 index 0000000000..cadeda04ab --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/fwprintf.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991, 1997, 1999, 2000, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include + + +/* Write formatted output to STREAM from the format string FORMAT. */ +/* VARARGS2 */ +int +__fwprintf (FILE *stream, const wchar_t *format, ...) +{ + va_list arg; + int done; + + va_start (arg, format); + done = __vfwprintf (stream, format, arg); + va_end (arg); + + return done; +} +weak_alias (__fwprintf, fwprintf) diff --git a/src/kernel/libroot/posix/glibc/libio/fwscanf.c b/src/kernel/libroot/posix/glibc/libio/fwscanf.c new file mode 100644 index 0000000000..411e1825c0 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/fwscanf.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1991, 1997, 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include + +/* Read formatted input from STREAM according to the format string FORMAT. */ +/* VARARGS2 */ +int +fwscanf (FILE *stream, const wchar_t *format, ...) +{ + va_list arg; + int done; + + va_start (arg, format); + done = __vfwscanf (stream, format, arg); + va_end (arg); + + return done; +} diff --git a/src/kernel/libroot/posix/glibc/libio/genops.c b/src/kernel/libroot/posix/glibc/libio/genops.c new file mode 100644 index 0000000000..c88a26f5f9 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/genops.c @@ -0,0 +1,1269 @@ +/* Copyright (C) 1993,1995,1997-2002, 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +/* Generic or default I/O operations. */ + +#include "libioP.h" +#ifdef __STDC__ +#include +#endif +#include + +#ifdef _IO_MTSAFE_IO +static _IO_lock_t list_all_lock = _IO_lock_initializer; +#endif + +/* Used to signal modifications to the list of FILE decriptors. */ +static int _IO_list_all_stamp; + + +static _IO_FILE *run_fp; + +static void +flush_cleanup (void *not_used) +{ + if (run_fp != NULL) + _IO_funlockfile (run_fp); +#ifdef _IO_MTSAFE_IO + _IO_lock_unlock (list_all_lock); +#endif +} + +void +_IO_un_link (fp) + struct _IO_FILE_plus *fp; +{ + if (fp->file._flags & _IO_LINKED) + { + struct _IO_FILE_plus **f; +#ifdef _IO_MTSAFE_IO + _IO_cleanup_region_start_noarg (flush_cleanup); + _IO_lock_lock (list_all_lock); + run_fp = (_IO_FILE *) fp; + _IO_flockfile ((_IO_FILE *) fp); +#endif + for (f = &INTUSE(_IO_list_all); *f; + f = (struct _IO_FILE_plus **) &(*f)->file._chain) + { + if (*f == fp) + { + *f = (struct _IO_FILE_plus *) fp->file._chain; + ++_IO_list_all_stamp; + break; + } + } + fp->file._flags &= ~_IO_LINKED; +#ifdef _IO_MTSAFE_IO + _IO_funlockfile ((_IO_FILE *) fp); + run_fp = NULL; + _IO_lock_unlock (list_all_lock); + _IO_cleanup_region_end (0); +#endif + } +} +INTDEF(_IO_un_link) + +void +_IO_link_in (fp) + struct _IO_FILE_plus *fp; +{ + if ((fp->file._flags & _IO_LINKED) == 0) + { + fp->file._flags |= _IO_LINKED; +#ifdef _IO_MTSAFE_IO + _IO_cleanup_region_start_noarg (flush_cleanup); + _IO_lock_lock (list_all_lock); + run_fp = (_IO_FILE *) fp; + _IO_flockfile ((_IO_FILE *) fp); +#endif + fp->file._chain = (_IO_FILE *) INTUSE(_IO_list_all); + INTUSE(_IO_list_all) = fp; + ++_IO_list_all_stamp; +#ifdef _IO_MTSAFE_IO + _IO_funlockfile ((_IO_FILE *) fp); + run_fp = NULL; + _IO_lock_unlock (list_all_lock); + _IO_cleanup_region_end (0); +#endif + } +} +INTDEF(_IO_link_in) + +/* Return minimum _pos markers + Assumes the current get area is the main get area. */ +_IO_ssize_t _IO_least_marker __P ((_IO_FILE *fp, char *end_p)); + +_IO_ssize_t +_IO_least_marker (fp, end_p) + _IO_FILE *fp; + char *end_p; +{ + _IO_ssize_t least_so_far = end_p - fp->_IO_read_base; + struct _IO_marker *mark; + for (mark = fp->_markers; mark != NULL; mark = mark->_next) + if (mark->_pos < least_so_far) + least_so_far = mark->_pos; + return least_so_far; +} + +/* Switch current get area from backup buffer to (start of) main get area. */ + +void +_IO_switch_to_main_get_area (fp) + _IO_FILE *fp; +{ + char *tmp; + fp->_flags &= ~_IO_IN_BACKUP; + /* Swap _IO_read_end and _IO_save_end. */ + tmp = fp->_IO_read_end; + fp->_IO_read_end = fp->_IO_save_end; + fp->_IO_save_end= tmp; + /* Swap _IO_read_base and _IO_save_base. */ + tmp = fp->_IO_read_base; + fp->_IO_read_base = fp->_IO_save_base; + fp->_IO_save_base = tmp; + /* Set _IO_read_ptr. */ + fp->_IO_read_ptr = fp->_IO_read_base; +} + +/* Switch current get area from main get area to (end of) backup area. */ + +void +_IO_switch_to_backup_area (fp) + _IO_FILE *fp; +{ + char *tmp; + fp->_flags |= _IO_IN_BACKUP; + /* Swap _IO_read_end and _IO_save_end. */ + tmp = fp->_IO_read_end; + fp->_IO_read_end = fp->_IO_save_end; + fp->_IO_save_end = tmp; + /* Swap _IO_read_base and _IO_save_base. */ + tmp = fp->_IO_read_base; + fp->_IO_read_base = fp->_IO_save_base; + fp->_IO_save_base = tmp; + /* Set _IO_read_ptr. */ + fp->_IO_read_ptr = fp->_IO_read_end; +} + +int +_IO_switch_to_get_mode (fp) + _IO_FILE *fp; +{ + if (fp->_IO_write_ptr > fp->_IO_write_base) + if (_IO_OVERFLOW (fp, EOF) == EOF) + return EOF; + if (_IO_in_backup (fp)) + fp->_IO_read_base = fp->_IO_backup_base; + else + { + fp->_IO_read_base = fp->_IO_buf_base; + if (fp->_IO_write_ptr > fp->_IO_read_end) + fp->_IO_read_end = fp->_IO_write_ptr; + } + fp->_IO_read_ptr = fp->_IO_write_ptr; + + fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr; + + fp->_flags &= ~_IO_CURRENTLY_PUTTING; + return 0; +} +INTDEF(_IO_switch_to_get_mode) + +void +_IO_free_backup_area (fp) + _IO_FILE *fp; +{ + if (_IO_in_backup (fp)) + _IO_switch_to_main_get_area (fp); /* Just in case. */ + free (fp->_IO_save_base); + fp->_IO_save_base = NULL; + fp->_IO_save_end = NULL; + fp->_IO_backup_base = NULL; +} +INTDEF(_IO_free_backup_area) + +#if 0 +int +_IO_switch_to_put_mode (fp) + _IO_FILE *fp; +{ + fp->_IO_write_base = fp->_IO_read_ptr; + fp->_IO_write_ptr = fp->_IO_read_ptr; + /* Following is wrong if line- or un-buffered? */ + fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP + ? fp->_IO_read_end : fp->_IO_buf_end); + + fp->_IO_read_ptr = fp->_IO_read_end; + fp->_IO_read_base = fp->_IO_read_end; + + fp->_flags |= _IO_CURRENTLY_PUTTING; + return 0; +} +#endif + +int +__overflow (f, ch) + _IO_FILE *f; + int ch; +{ + /* This is a single-byte stream. */ + if (f->_mode == 0) + _IO_fwide (f, -1); + return _IO_OVERFLOW (f, ch); +} +libc_hidden_def (__overflow) + +static int save_for_backup __P ((_IO_FILE *fp, char *end_p)) +#ifdef _LIBC + internal_function +#endif + ; + +static int +#ifdef _LIBC +internal_function +#endif +save_for_backup (fp, end_p) + _IO_FILE *fp; + char *end_p; +{ + /* Append [_IO_read_base..end_p] to backup area. */ + _IO_ssize_t least_mark = _IO_least_marker (fp, end_p); + /* needed_size is how much space we need in the backup area. */ + _IO_size_t needed_size = (end_p - fp->_IO_read_base) - least_mark; + /* FIXME: Dubious arithmetic if pointers are NULL */ + _IO_size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base; + _IO_size_t avail; /* Extra space available for future expansion. */ + _IO_ssize_t delta; + struct _IO_marker *mark; + if (needed_size > current_Bsize) + { + char *new_buffer; + avail = 100; + new_buffer = (char *) malloc (avail + needed_size); + if (new_buffer == NULL) + return EOF; /* FIXME */ + if (least_mark < 0) + { +#ifdef _LIBC + __mempcpy (__mempcpy (new_buffer + avail, + fp->_IO_save_end + least_mark, + -least_mark), + fp->_IO_read_base, + end_p - fp->_IO_read_base); +#else + memcpy (new_buffer + avail, + fp->_IO_save_end + least_mark, + -least_mark); + memcpy (new_buffer + avail - least_mark, + fp->_IO_read_base, + end_p - fp->_IO_read_base); +#endif + } + else + memcpy (new_buffer + avail, + fp->_IO_read_base + least_mark, + needed_size); + if (fp->_IO_save_base) + free (fp->_IO_save_base); + fp->_IO_save_base = new_buffer; + fp->_IO_save_end = new_buffer + avail + needed_size; + } + else + { + avail = current_Bsize - needed_size; + if (least_mark < 0) + { + memmove (fp->_IO_save_base + avail, + fp->_IO_save_end + least_mark, + -least_mark); + memcpy (fp->_IO_save_base + avail - least_mark, + fp->_IO_read_base, + end_p - fp->_IO_read_base); + } + else if (needed_size > 0) + memcpy (fp->_IO_save_base + avail, + fp->_IO_read_base + least_mark, + needed_size); + } + fp->_IO_backup_base = fp->_IO_save_base + avail; + /* Adjust all the streammarkers. */ + delta = end_p - fp->_IO_read_base; + for (mark = fp->_markers; mark != NULL; mark = mark->_next) + mark->_pos -= delta; + return 0; +} + +int +__underflow (fp) + _IO_FILE *fp; +{ +#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T + if (fp->_vtable_offset == 0 && _IO_fwide (fp, -1) != -1) + return EOF; +#endif + + if (fp->_mode == 0) + _IO_fwide (fp, -1); + if (_IO_in_put_mode (fp)) + if (INTUSE(_IO_switch_to_get_mode) (fp) == EOF) + return EOF; + if (fp->_IO_read_ptr < fp->_IO_read_end) + return *(unsigned char *) fp->_IO_read_ptr; + if (_IO_in_backup (fp)) + { + _IO_switch_to_main_get_area (fp); + if (fp->_IO_read_ptr < fp->_IO_read_end) + return *(unsigned char *) fp->_IO_read_ptr; + } + if (_IO_have_markers (fp)) + { + if (save_for_backup (fp, fp->_IO_read_end)) + return EOF; + } + else if (_IO_have_backup (fp)) + INTUSE(_IO_free_backup_area) (fp); + return _IO_UNDERFLOW (fp); +} +libc_hidden_def (__underflow) + +int +__uflow (fp) + _IO_FILE *fp; +{ +#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T + if (fp->_vtable_offset == 0 && _IO_fwide (fp, -1) != -1) + return EOF; +#endif + + if (fp->_mode == 0) + _IO_fwide (fp, -11); + if (_IO_in_put_mode (fp)) + if (INTUSE(_IO_switch_to_get_mode) (fp) == EOF) + return EOF; + if (fp->_IO_read_ptr < fp->_IO_read_end) + return *(unsigned char *) fp->_IO_read_ptr++; + if (_IO_in_backup (fp)) + { + _IO_switch_to_main_get_area (fp); + if (fp->_IO_read_ptr < fp->_IO_read_end) + return *(unsigned char *) fp->_IO_read_ptr++; + } + if (_IO_have_markers (fp)) + { + if (save_for_backup (fp, fp->_IO_read_end)) + return EOF; + } + else if (_IO_have_backup (fp)) + INTUSE(_IO_free_backup_area) (fp); + return _IO_UFLOW (fp); +} +libc_hidden_def (__uflow) + +void +_IO_setb (f, b, eb, a) + _IO_FILE *f; + char *b; + char *eb; + int a; +{ + if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF)) + FREE_BUF (f->_IO_buf_base, _IO_blen (f)); + f->_IO_buf_base = b; + f->_IO_buf_end = eb; + if (a) + f->_flags &= ~_IO_USER_BUF; + else + f->_flags |= _IO_USER_BUF; +} +INTDEF(_IO_setb) + +void +_IO_doallocbuf (fp) + _IO_FILE *fp; +{ + if (fp->_IO_buf_base) + return; + if (!(fp->_flags & _IO_UNBUFFERED) || fp->_mode > 0) + if (_IO_DOALLOCATE (fp) != EOF) + return; + INTUSE(_IO_setb) (fp, fp->_shortbuf, fp->_shortbuf+1, 0); +} +INTDEF(_IO_doallocbuf) + +int +_IO_default_underflow (fp) + _IO_FILE *fp; +{ + return EOF; +} + +int +_IO_default_uflow (fp) + _IO_FILE *fp; +{ + int ch = _IO_UNDERFLOW (fp); + if (ch == EOF) + return EOF; + return *(unsigned char *) fp->_IO_read_ptr++; +} +INTDEF(_IO_default_uflow) + +_IO_size_t +_IO_default_xsputn (f, data, n) + _IO_FILE *f; + const void *data; + _IO_size_t n; +{ + const char *s = (char *) data; + _IO_size_t more = n; + if (more <= 0) + return 0; + for (;;) + { + /* Space available. */ + _IO_ssize_t count = f->_IO_write_end - f->_IO_write_ptr; + if (count > 0) + { + if ((_IO_size_t) count > more) + count = more; + if (count > 20) + { +#ifdef _LIBC + f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count); +#else + memcpy (f->_IO_write_ptr, s, count); + f->_IO_write_ptr += count; +#endif + s += count; + } + else if (count <= 0) + count = 0; + else + { + char *p = f->_IO_write_ptr; + _IO_ssize_t i; + for (i = count; --i >= 0; ) + *p++ = *s++; + f->_IO_write_ptr = p; + } + more -= count; + } + if (more == 0 || _IO_OVERFLOW (f, (unsigned char) *s++) == EOF) + break; + more--; + } + return n - more; +} +INTDEF(_IO_default_xsputn) + +_IO_size_t +_IO_sgetn (fp, data, n) + _IO_FILE *fp; + void *data; + _IO_size_t n; +{ + /* FIXME handle putback buffer here! */ + return _IO_XSGETN (fp, data, n); +} +INTDEF(_IO_sgetn) + +_IO_size_t +_IO_default_xsgetn (fp, data, n) + _IO_FILE *fp; + void *data; + _IO_size_t n; +{ + _IO_size_t more = n; + char *s = (char*) data; + for (;;) + { + /* Data available. */ + _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr; + if (count > 0) + { + if ((_IO_size_t) count > more) + count = more; + if (count > 20) + { +#ifdef _LIBC + s = __mempcpy (s, fp->_IO_read_ptr, count); +#else + memcpy (s, fp->_IO_read_ptr, count); + s += count; +#endif + fp->_IO_read_ptr += count; + } + else if (count <= 0) + count = 0; + else + { + char *p = fp->_IO_read_ptr; + int i = (int) count; + while (--i >= 0) + *s++ = *p++; + fp->_IO_read_ptr = p; + } + more -= count; + } + if (more == 0 || __underflow (fp) == EOF) + break; + } + return n - more; +} +INTDEF(_IO_default_xsgetn) + +#if 0 +/* Seems not to be needed. --drepper */ +int +_IO_sync (fp) + _IO_FILE *fp; +{ + return 0; +} +#endif + +_IO_FILE * +_IO_default_setbuf (fp, p, len) + _IO_FILE *fp; + char *p; + _IO_ssize_t len; +{ + if (_IO_SYNC (fp) == EOF) + return NULL; + if (p == NULL || len == 0) + { + fp->_flags |= _IO_UNBUFFERED; + INTUSE(_IO_setb) (fp, fp->_shortbuf, fp->_shortbuf+1, 0); + } + else + { + fp->_flags &= ~_IO_UNBUFFERED; + INTUSE(_IO_setb) (fp, p, p+len, 0); + } + fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0; + fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0; + return fp; +} + +_IO_off64_t +_IO_default_seekpos (fp, pos, mode) + _IO_FILE *fp; + _IO_off64_t pos; + int mode; +{ + return _IO_SEEKOFF (fp, pos, 0, mode); +} + +int +_IO_default_doallocate (fp) + _IO_FILE *fp; +{ + char *buf; + + ALLOC_BUF (buf, _IO_BUFSIZ, EOF); + INTUSE(_IO_setb) (fp, buf, buf+_IO_BUFSIZ, 1); + return 1; +} +INTDEF(_IO_default_doallocate) + +void +_IO_init (fp, flags) + _IO_FILE *fp; + int flags; +{ + _IO_no_init (fp, flags, -1, NULL, NULL); +} +INTDEF(_IO_init) + +void +_IO_no_init (fp, flags, orientation, wd, jmp) + _IO_FILE *fp; + int flags; + int orientation; + struct _IO_wide_data *wd; + struct _IO_jump_t *jmp; +{ + fp->_flags = _IO_MAGIC|flags; + fp->_flags2 = 0; + fp->_IO_buf_base = NULL; + fp->_IO_buf_end = NULL; + fp->_IO_read_base = NULL; + fp->_IO_read_ptr = NULL; + fp->_IO_read_end = NULL; + fp->_IO_write_base = NULL; + fp->_IO_write_ptr = NULL; + fp->_IO_write_end = NULL; + fp->_chain = NULL; /* Not necessary. */ + + fp->_IO_save_base = NULL; + fp->_IO_backup_base = NULL; + fp->_IO_save_end = NULL; + fp->_markers = NULL; + fp->_cur_column = 0; +#if _IO_JUMPS_OFFSET + fp->_vtable_offset = 0; +#endif +#ifdef _IO_MTSAFE_IO + if (fp->_lock != NULL) + _IO_lock_init (*fp->_lock); +#endif + fp->_mode = orientation; +#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T + if (orientation >= 0) + { + fp->_wide_data = wd; + fp->_wide_data->_IO_buf_base = NULL; + fp->_wide_data->_IO_buf_end = NULL; + fp->_wide_data->_IO_read_base = NULL; + fp->_wide_data->_IO_read_ptr = NULL; + fp->_wide_data->_IO_read_end = NULL; + fp->_wide_data->_IO_write_base = NULL; + fp->_wide_data->_IO_write_ptr = NULL; + fp->_wide_data->_IO_write_end = NULL; + fp->_wide_data->_IO_save_base = NULL; + fp->_wide_data->_IO_backup_base = NULL; + fp->_wide_data->_IO_save_end = NULL; + + fp->_wide_data->_wide_vtable = jmp; + } +#endif +} + +int +_IO_default_sync (fp) + _IO_FILE *fp; +{ + return 0; +} + +/* The way the C++ classes are mapped into the C functions in the + current implementation, this function can get called twice! */ + +void +_IO_default_finish (fp, dummy) + _IO_FILE *fp; + int dummy; +{ + struct _IO_marker *mark; + if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF)) + { + FREE_BUF (fp->_IO_buf_base, _IO_blen (fp)); + fp->_IO_buf_base = fp->_IO_buf_end = NULL; + } + + for (mark = fp->_markers; mark != NULL; mark = mark->_next) + mark->_sbuf = NULL; + + if (fp->_IO_save_base) + { + free (fp->_IO_save_base); + fp->_IO_save_base = NULL; + } + +#ifdef _IO_MTSAFE_IO + if (fp->_lock != NULL) + _IO_lock_fini (*fp->_lock); +#endif + + INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp); +} +INTDEF(_IO_default_finish) + +_IO_off64_t +_IO_default_seekoff (fp, offset, dir, mode) + _IO_FILE *fp; + _IO_off64_t offset; + int dir; + int mode; +{ + return _IO_pos_BAD; +} + +int +_IO_sputbackc (fp, c) + _IO_FILE *fp; + int c; +{ + int result; + + if (fp->_IO_read_ptr > fp->_IO_read_base + && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c) + { + fp->_IO_read_ptr--; + result = (unsigned char) c; + } + else + result = _IO_PBACKFAIL (fp, c); + + if (result != EOF) + fp->_flags &= ~_IO_EOF_SEEN; + + return result; +} +INTDEF(_IO_sputbackc) + +int +_IO_sungetc (fp) + _IO_FILE *fp; +{ + int result; + + if (fp->_IO_read_ptr > fp->_IO_read_base) + { + fp->_IO_read_ptr--; + result = (unsigned char) *fp->_IO_read_ptr; + } + else + result = _IO_PBACKFAIL (fp, EOF); + + if (result != EOF) + fp->_flags &= ~_IO_EOF_SEEN; + + return result; +} + +#if 0 /* Work in progress */ +/* Seems not to be needed. */ +#if 0 +void +_IO_set_column (fp, c) + _IO_FILE *fp; + int c; +{ + if (c == -1) + fp->_column = -1; + else + fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base); +} +#else +int +_IO_set_column (fp, i) + _IO_FILE *fp; + int i; +{ + fp->_cur_column = i + 1; + return 0; +} +#endif +#endif + + +unsigned +_IO_adjust_column (start, line, count) + unsigned start; + const char *line; + int count; +{ + const char *ptr = line + count; + while (ptr > line) + if (*--ptr == '\n') + return line + count - ptr - 1; + return start + count; +} +INTDEF(_IO_adjust_column) + +#if 0 +/* Seems not to be needed. --drepper */ +int +_IO_get_column (fp) + _IO_FILE *fp; +{ + if (fp->_cur_column) + return _IO_adjust_column (fp->_cur_column - 1, + fp->_IO_write_base, + fp->_IO_write_ptr - fp->_IO_write_base); + return -1; +} +#endif + + +int +_IO_flush_all_lockp (int do_lock) +{ + int result = 0; + struct _IO_FILE *fp; + int last_stamp; + +#ifdef _IO_MTSAFE_IO + _IO_cleanup_region_start_noarg (flush_cleanup); + if (do_lock) + _IO_lock_lock (list_all_lock); +#endif + + last_stamp = _IO_list_all_stamp; + fp = (_IO_FILE *) INTUSE(_IO_list_all); + while (fp != NULL) + { + run_fp = fp; + if (do_lock) + _IO_flockfile (fp); + + if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base) +#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T + || (fp->_vtable_offset == 0 + && fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr + > fp->_wide_data->_IO_write_base)) +#endif + ) + && _IO_OVERFLOW (fp, EOF) == EOF) + result = EOF; + + if (do_lock) + _IO_funlockfile (fp); + run_fp = NULL; + + if (last_stamp != _IO_list_all_stamp) + { + /* Something was added to the list. Start all over again. */ + fp = (_IO_FILE *) INTUSE(_IO_list_all); + last_stamp = _IO_list_all_stamp; + } + else + fp = fp->_chain; + } + +#ifdef _IO_MTSAFE_IO + if (do_lock) + _IO_lock_unlock (list_all_lock); + _IO_cleanup_region_end (0); +#endif + + return result; +} + + +int +_IO_flush_all () +{ + /* We want locking. */ + return _IO_flush_all_lockp (1); +} +INTDEF(_IO_flush_all) + +void +_IO_flush_all_linebuffered () +{ + struct _IO_FILE *fp; + int last_stamp; + +#ifdef _IO_MTSAFE_IO + _IO_cleanup_region_start_noarg (flush_cleanup); + _IO_lock_lock (list_all_lock); +#endif + + last_stamp = _IO_list_all_stamp; + fp = (_IO_FILE *) INTUSE(_IO_list_all); + while (fp != NULL) + { + run_fp = fp; + _IO_flockfile (fp); + + if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF) + _IO_OVERFLOW (fp, EOF); + + _IO_funlockfile (fp); + run_fp = NULL; + + if (last_stamp != _IO_list_all_stamp) + { + /* Something was added to the list. Start all over again. */ + fp = (_IO_FILE *) INTUSE(_IO_list_all); + last_stamp = _IO_list_all_stamp; + } + else + fp = fp->_chain; + } + +#ifdef _IO_MTSAFE_IO + _IO_lock_unlock (list_all_lock); + _IO_cleanup_region_end (0); +#endif +} +INTDEF(_IO_flush_all_linebuffered) +#ifdef _LIBC +weak_alias (_IO_flush_all_linebuffered, _flushlbf) +#endif + +static void _IO_unbuffer_write __P ((void)); + +static void +_IO_unbuffer_write () +{ + struct _IO_FILE *fp; + for (fp = (_IO_FILE *) INTUSE(_IO_list_all); fp; fp = fp->_chain) + { + if (! (fp->_flags & _IO_UNBUFFERED) + && (! (fp->_flags & _IO_NO_WRITES) + || (fp->_flags & _IO_IS_APPENDING)) + /* Iff stream is un-orientated, it wasn't used. */ + && fp->_mode != 0) + _IO_SETBUF (fp, NULL, 0); + + /* Make sure that never again the wide char functions can be + used. */ + fp->_mode = -1; + } +} + +int +_IO_cleanup () +{ + int result = INTUSE(_IO_flush_all) (); + + /* We currently don't have a reliable mechanism for making sure that + C++ static destructors are executed in the correct order. + So it is possible that other static destructors might want to + write to cout - and they're supposed to be able to do so. + + The following will make the standard streambufs be unbuffered, + which forces any output from late destructors to be written out. */ + _IO_unbuffer_write (); + + return result; +} + + +void +_IO_init_marker (marker, fp) + struct _IO_marker *marker; + _IO_FILE *fp; +{ + marker->_sbuf = fp; + if (_IO_in_put_mode (fp)) + INTUSE(_IO_switch_to_get_mode) (fp); + if (_IO_in_backup (fp)) + marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end; + else + marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base; + + /* Should perhaps sort the chain? */ + marker->_next = fp->_markers; + fp->_markers = marker; +} + +void +_IO_remove_marker (marker) + struct _IO_marker *marker; +{ + /* Unlink from sb's chain. */ + struct _IO_marker **ptr = &marker->_sbuf->_markers; + for (; ; ptr = &(*ptr)->_next) + { + if (*ptr == NULL) + break; + else if (*ptr == marker) + { + *ptr = marker->_next; + return; + } + } +#if 0 + if _sbuf has a backup area that is no longer needed, should we delete + it now, or wait until the next underflow? +#endif +} + +#define BAD_DELTA EOF + +int +_IO_marker_difference (mark1, mark2) + struct _IO_marker *mark1; + struct _IO_marker *mark2; +{ + return mark1->_pos - mark2->_pos; +} + +/* Return difference between MARK and current position of MARK's stream. */ +int +_IO_marker_delta (mark) + struct _IO_marker *mark; +{ + int cur_pos; + if (mark->_sbuf == NULL) + return BAD_DELTA; + if (_IO_in_backup (mark->_sbuf)) + cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end; + else + cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base; + return mark->_pos - cur_pos; +} + +int +_IO_seekmark (fp, mark, delta) + _IO_FILE *fp; + struct _IO_marker *mark; + int delta; +{ + if (mark->_sbuf != fp) + return EOF; + if (mark->_pos >= 0) + { + if (_IO_in_backup (fp)) + _IO_switch_to_main_get_area (fp); + fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos; + } + else + { + if (!_IO_in_backup (fp)) + _IO_switch_to_backup_area (fp); + fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos; + } + return 0; +} + +void +_IO_unsave_markers (fp) + _IO_FILE *fp; +{ + struct _IO_marker *mark = fp->_markers; + if (mark) + { +#ifdef TODO + streampos offset = seekoff (0, ios::cur, ios::in); + if (offset != EOF) + { + offset += eGptr () - Gbase (); + for ( ; mark != NULL; mark = mark->_next) + mark->set_streampos (mark->_pos + offset); + } + else + { + for ( ; mark != NULL; mark = mark->_next) + mark->set_streampos (EOF); + } +#endif + fp->_markers = 0; + } + + if (_IO_have_backup (fp)) + INTUSE(_IO_free_backup_area) (fp); +} +INTDEF(_IO_unsave_markers) + +#if 0 +/* Seems not to be needed. --drepper */ +int +_IO_nobackup_pbackfail (fp, c) + _IO_FILE *fp; + int c; +{ + if (fp->_IO_read_ptr > fp->_IO_read_base) + fp->_IO_read_ptr--; + if (c != EOF && *fp->_IO_read_ptr != c) + *fp->_IO_read_ptr = c; + return (unsigned char) c; +} +#endif + +int +_IO_default_pbackfail (fp, c) + _IO_FILE *fp; + int c; +{ + if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp) + && (unsigned char) fp->_IO_read_ptr[-1] == c) + --fp->_IO_read_ptr; + else + { + /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/ + if (!_IO_in_backup (fp)) + { + /* We need to keep the invariant that the main get area + logically follows the backup area. */ + if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp)) + { + if (save_for_backup (fp, fp->_IO_read_ptr)) + return EOF; + } + else if (!_IO_have_backup (fp)) + { + /* No backup buffer: allocate one. */ + /* Use nshort buffer, if unused? (probably not) FIXME */ + int backup_size = 128; + char *bbuf = (char *) malloc (backup_size); + if (bbuf == NULL) + return EOF; + fp->_IO_save_base = bbuf; + fp->_IO_save_end = fp->_IO_save_base + backup_size; + fp->_IO_backup_base = fp->_IO_save_end; + } + fp->_IO_read_base = fp->_IO_read_ptr; + _IO_switch_to_backup_area (fp); + } + else if (fp->_IO_read_ptr <= fp->_IO_read_base) + { + /* Increase size of existing backup buffer. */ + _IO_size_t new_size; + _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base; + char *new_buf; + new_size = 2 * old_size; + new_buf = (char *) malloc (new_size); + if (new_buf == NULL) + return EOF; + memcpy (new_buf + (new_size - old_size), fp->_IO_read_base, + old_size); + free (fp->_IO_read_base); + _IO_setg (fp, new_buf, new_buf + (new_size - old_size), + new_buf + new_size); + fp->_IO_backup_base = fp->_IO_read_ptr; + } + + *--fp->_IO_read_ptr = c; + } + return (unsigned char) c; +} +INTDEF(_IO_default_pbackfail) + +_IO_off64_t +_IO_default_seek (fp, offset, dir) + _IO_FILE *fp; + _IO_off64_t offset; + int dir; +{ + return _IO_pos_BAD; +} + +int +_IO_default_stat (fp, st) + _IO_FILE *fp; + void* st; +{ + return EOF; +} + +_IO_ssize_t +_IO_default_read (fp, data, n) + _IO_FILE* fp; + void *data; + _IO_ssize_t n; +{ + return -1; +} + +_IO_ssize_t +_IO_default_write (fp, data, n) + _IO_FILE *fp; + const void *data; + _IO_ssize_t n; +{ + return 0; +} + +int +_IO_default_showmanyc (fp) + _IO_FILE *fp; +{ + return -1; +} + +void +_IO_default_imbue (fp, locale) + _IO_FILE *fp; + void *locale; +{ +} + +_IO_ITER +_IO_iter_begin() +{ + return (_IO_ITER) INTUSE(_IO_list_all); +} +libc_hidden_def (_IO_iter_begin) + +_IO_ITER +_IO_iter_end() +{ + return NULL; +} +libc_hidden_def (_IO_iter_end) + +_IO_ITER +_IO_iter_next(iter) + _IO_ITER iter; +{ + return iter->_chain; +} +libc_hidden_def (_IO_iter_next) + +_IO_FILE * +_IO_iter_file(iter) + _IO_ITER iter; +{ + return iter; +} +libc_hidden_def (_IO_iter_file) + +void +_IO_list_lock() +{ +#ifdef _IO_MTSAFE_IO + _IO_lock_lock (list_all_lock); +#endif +} +libc_hidden_def (_IO_list_lock) + +void +_IO_list_unlock() +{ +#ifdef _IO_MTSAFE_IO + _IO_lock_unlock (list_all_lock); +#endif +} +libc_hidden_def (_IO_list_unlock) + +void +_IO_list_resetlock() +{ +#ifdef _IO_MTSAFE_IO + _IO_lock_init (list_all_lock); +#endif +} +libc_hidden_def (_IO_list_resetlock) + + +#ifdef TODO +#if defined(linux) +#define IO_CLEANUP ; +#endif + +#ifdef IO_CLEANUP + IO_CLEANUP +#else +struct __io_defs { + __io_defs() { } + ~__io_defs() { _IO_cleanup (); } +}; +__io_defs io_defs__; +#endif + +#endif /* TODO */ + +#ifdef text_set_element +text_set_element(__libc_atexit, _IO_cleanup); +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/getc.c b/src/kernel/libroot/posix/glibc/libio/getc.c new file mode 100644 index 0000000000..a35dcb9f8d --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/getc.c @@ -0,0 +1,58 @@ +/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +#undef _IO_getc + +int +_IO_getc (fp) + FILE *fp; +{ + int result; + CHECK_FILE (fp, EOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + result = _IO_getc_unlocked (fp); + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} + +#undef getc + +#ifdef weak_alias +weak_alias (_IO_getc, getc) +weak_alias (_IO_getc, fgetc) + +#ifndef _IO_MTSAFE_IO +#undef getc_unlocked +weak_alias (_IO_getc, getc_unlocked) +weak_alias (_IO_getc, fgetc_unlocked) +#endif +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/getc_u.c b/src/kernel/libroot/posix/glibc/libio/getc_u.c new file mode 100644 index 0000000000..5c08dbc156 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/getc_u.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1993,1995,1996,1997,1999,2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +#undef getc_unlocked + +int +__getc_unlocked (FILE *fp) +{ + CHECK_FILE (fp, EOF); + return _IO_getc_unlocked (fp); +} + +weak_alias (__getc_unlocked, getc_unlocked) +weak_alias (__getc_unlocked, fgetc_unlocked) diff --git a/src/kernel/libroot/posix/glibc/libio/getchar.c b/src/kernel/libroot/posix/glibc/libio/getchar.c new file mode 100644 index 0000000000..8ce67fea52 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/getchar.c @@ -0,0 +1,49 @@ +/* Copyright (C) 1993, 1996, 1997, 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +#undef getchar + +int +getchar () +{ + int result; + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _IO_stdin); + _IO_flockfile (_IO_stdin); + result = _IO_getc_unlocked (_IO_stdin); + _IO_funlockfile (_IO_stdin); + _IO_cleanup_region_end (0); + return result; +} + +#if defined weak_alias && !defined _IO_MTSAFE_IO +#undef getchar_unlocked +weak_alias (getchar, getchar_unlocked) +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/getchar_u.c b/src/kernel/libroot/posix/glibc/libio/getchar_u.c new file mode 100644 index 0000000000..080c3998a4 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/getchar_u.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +#undef getchar_unlocked + +int +getchar_unlocked () +{ + return _IO_getc_unlocked (_IO_stdin); +} diff --git a/src/kernel/libroot/posix/glibc/libio/getwc.c b/src/kernel/libroot/posix/glibc/libio/getwc.c new file mode 100644 index 0000000000..0617e2d713 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/getwc.c @@ -0,0 +1,53 @@ +/* Copyright (C) 1993, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include +#include + +#undef _IO_getwc + +wint_t +_IO_getwc (fp) + FILE *fp; +{ + wint_t result; + CHECK_FILE (fp, WEOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + result = _IO_getwc_unlocked (fp); + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} + +#undef getwc + +#ifdef weak_alias +weak_alias (_IO_getwc, getwc) +weak_alias (_IO_getwc, fgetwc) +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/getwc_u.c b/src/kernel/libroot/posix/glibc/libio/getwc_u.c new file mode 100644 index 0000000000..bdad3c8bf3 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/getwc_u.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1993,1995,1996,1997,1999,2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +#undef getwc_unlocked + +wint_t +__getwc_unlocked (FILE *fp) +{ + CHECK_FILE (fp, EOF); + return _IO_getwc_unlocked (fp); +} + +weak_alias (__getwc_unlocked, getwc_unlocked) +weak_alias (__getwc_unlocked, fgetwc_unlocked) diff --git a/src/kernel/libroot/posix/glibc/libio/getwchar.c b/src/kernel/libroot/posix/glibc/libio/getwchar.c new file mode 100644 index 0000000000..0298e22ead --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/getwchar.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +#undef getwchar + +wint_t +getwchar () +{ + wint_t result; + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _IO_stdin); + _IO_flockfile (_IO_stdin); + result = _IO_getwc_unlocked (_IO_stdin); + _IO_funlockfile (_IO_stdin); + _IO_cleanup_region_end (0); + return result; +} diff --git a/src/kernel/libroot/posix/glibc/libio/getwchar_u.c b/src/kernel/libroot/posix/glibc/libio/getwchar_u.c new file mode 100644 index 0000000000..9dbf1ac6e0 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/getwchar_u.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1993, 1996, 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +#undef getwchar_unlocked + +wint_t +getwchar_unlocked () +{ + return _IO_getwc_unlocked (_IO_stdin); +} diff --git a/src/kernel/libroot/posix/glibc/libio/iofclose.c b/src/kernel/libroot/posix/glibc/libio/iofclose.c new file mode 100644 index 0000000000..62d12244c5 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iofclose.c @@ -0,0 +1,98 @@ +/* Copyright (C) 1993,1995,1997-2001,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#ifdef __STDC__ +#include +#endif +#if _LIBC +# include "../iconv/gconv_int.h" +# include +#else +# define SHLIB_COMPAT(a, b, c) 0 +# define _IO_new_fclose fclose +#endif + +int +_IO_new_fclose (fp) + _IO_FILE *fp; +{ + int status; + + CHECK_FILE(fp, EOF); + +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + /* We desperately try to help programs which are using streams in a + strange way and mix old and new functions. Detect old streams + here. */ + if (fp->_vtable_offset != 0) + return _IO_old_fclose (fp); +#endif + + /* First unlink the stream. */ + if (fp->_IO_file_flags & _IO_IS_FILEBUF) + INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp); + + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + if (fp->_IO_file_flags & _IO_IS_FILEBUF) + status = INTUSE(_IO_file_close_it) (fp); + else + status = fp->_flags & _IO_ERR_SEEN ? -1 : 0; + _IO_FINISH (fp); + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + if (fp->_mode > 0) + { +#if _LIBC + /* This stream has a wide orientation. This means we have to free + the conversion functions. */ + struct _IO_codecvt *cc = fp->_codecvt; + + __gconv_release_step (cc->__cd_in.__cd.__steps); + __gconv_release_step (cc->__cd_out.__cd.__steps); +#endif + } + else + { + if (_IO_have_backup (fp)) + INTUSE(_IO_free_backup_area) (fp); + } + if (fp != _IO_stdin && fp != _IO_stdout && fp != _IO_stderr) + { + fp->_IO_file_flags = 0; + free(fp); + } + + return status; +} + +#ifdef _LIBC +versioned_symbol (libc, _IO_new_fclose, _IO_fclose, GLIBC_2_1); +strong_alias (_IO_new_fclose, __new_fclose) +versioned_symbol (libc, __new_fclose, fclose, GLIBC_2_1); +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/iofdopen.c b/src/kernel/libroot/posix/glibc/libio/iofdopen.c new file mode 100644 index 0000000000..fc2625b840 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iofdopen.c @@ -0,0 +1,184 @@ +/* Copyright (C) 1993,1994,1997-1999,2000,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#ifdef __STDC__ +# include +#endif +#include + +#ifdef _LIBC +# include +#endif + +#ifndef _IO_fcntl +#ifdef _LIBC +#define _IO_fcntl __fcntl +#else +#define _IO_fcntl fcntl +#endif +#endif + +_IO_FILE * +_IO_new_fdopen (fd, mode) + int fd; + const char *mode; +{ + int read_write; + int posix_mode = 0; + struct locked_FILE + { + struct _IO_FILE_plus fp; +#ifdef _IO_MTSAFE_IO + _IO_lock_t lock; +#endif + struct _IO_wide_data wd; + } *new_f; + int fd_flags; + int i; + int use_mmap = 0; + + switch (*mode) + { + case 'r': + read_write = _IO_NO_WRITES; + break; + case 'w': + read_write = _IO_NO_READS; + break; + case 'a': + posix_mode = O_APPEND; + read_write = _IO_NO_READS|_IO_IS_APPENDING; + break; + default: + MAYBE_SET_EINVAL; + return NULL; + } + for (i = 1; i < 5; ++i) + { + switch (*++mode) + { + case '\0': + break; + case '+': + read_write &= _IO_IS_APPENDING; + break; + case 'm': + use_mmap = 1; + continue; + case 'x': + case 'b': + default: + /* Ignore */ + continue; + } + break; + } +#ifdef F_GETFL + fd_flags = _IO_fcntl (fd, F_GETFL); +#ifndef O_ACCMODE +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) +#endif + if (fd_flags == -1) + return NULL; + + if (((fd_flags & O_ACCMODE) == O_RDONLY && !(read_write & _IO_NO_WRITES)) + || ((fd_flags & O_ACCMODE) == O_WRONLY && !(read_write & _IO_NO_READS))) + { + MAYBE_SET_EINVAL; + return NULL; + } + + /* The May 93 draft of P1003.4/D14.1 (redesignated as 1003.1b) + [System Application Program Interface (API) Amendment 1: + Realtime Extensions], Rationale B.8.3.3 + Open a Stream on a File Descriptor says: + + Although not explicitly required by POSIX.1, a good + implementation of append ("a") mode would cause the + O_APPEND flag to be set. + + (Historical implementations [such as Solaris2] do a one-time + seek in fdopen.) + + However, we do not turn O_APPEND off if the mode is "w" (even + though that would seem consistent) because that would be more + likely to break historical programs. + */ + if ((posix_mode & O_APPEND) && !(fd_flags & O_APPEND)) + { +#ifdef F_SETFL + if (_IO_fcntl (fd, F_SETFL, fd_flags | O_APPEND) == -1) +#endif + return NULL; + } +#endif + + new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); + if (new_f == NULL) + return NULL; +#ifdef _IO_MTSAFE_IO + new_f->fp.file._lock = &new_f->lock; +#endif + /* Set up initially to use the `maybe_mmap' jump tables rather than using + __fopen_maybe_mmap to do it, because we need them in place before we + call _IO_file_attach or else it will allocate a buffer immediately. */ + _IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd, +#ifdef _G_HAVE_MMAP + (use_mmap && (read_write & _IO_NO_WRITES)) + ? &_IO_wfile_jumps_maybe_mmap : +#endif + &INTUSE(_IO_wfile_jumps)); + _IO_JUMPS (&new_f->fp) = +#ifdef _G_HAVE_MMAP + (use_mmap && (read_write & _IO_NO_WRITES)) ? &_IO_file_jumps_maybe_mmap : +#endif + &INTUSE(_IO_file_jumps); + INTUSE(_IO_file_init) (&new_f->fp); +#if !_IO_UNIFIED_JUMPTABLES + new_f->fp.vtable = NULL; +#endif + if (INTUSE(_IO_file_attach) ((_IO_FILE *) &new_f->fp, fd) == NULL) + { + INTUSE(_IO_setb) (&new_f->fp.file, NULL, NULL, 0); + INTUSE(_IO_un_link) (&new_f->fp); + free (new_f); + return NULL; + } + new_f->fp.file._flags &= ~_IO_DELETE_DONT_CLOSE; + + new_f->fp.file._IO_file_flags = + _IO_mask_flags (&new_f->fp.file, read_write, + _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); + + return &new_f->fp.file; +} +INTDEF2(_IO_new_fdopen, _IO_fdopen) + +strong_alias (_IO_new_fdopen, __new_fdopen) +versioned_symbol (libc, _IO_new_fdopen, _IO_fdopen, GLIBC_2_1); +versioned_symbol (libc, __new_fdopen, fdopen, GLIBC_2_1); diff --git a/src/kernel/libroot/posix/glibc/libio/iofflush.c b/src/kernel/libroot/posix/glibc/libio/iofflush.c new file mode 100644 index 0000000000..d1a76ccd4e --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iofflush.c @@ -0,0 +1,58 @@ +/* Copyright (C) 1993,1995,1996,1997,1998,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +int +_IO_fflush (fp) + _IO_FILE *fp; +{ + if (fp == NULL) + return INTUSE(_IO_flush_all) (); + else + { + int result; + CHECK_FILE (fp, EOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + result = _IO_SYNC (fp) ? EOF : 0; + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; + } +} +INTDEF(_IO_fflush) + +#ifdef weak_alias +weak_alias (_IO_fflush, fflush) + +#ifndef _IO_MTSAFE_IO +weak_alias (_IO_fflush, fflush_unlocked) +libc_hidden_weak (fflush_unlocked) +#endif +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/iofflush_u.c b/src/kernel/libroot/posix/glibc/libio/iofflush_u.c new file mode 100644 index 0000000000..d604ebfec2 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iofflush_u.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1993, 1995, 1996, 1997, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +int +fflush_unlocked (fp) + _IO_FILE *fp; +{ + if (fp == NULL) + return INTUSE(_IO_flush_all) (); + else + { + CHECK_FILE (fp, EOF); + return _IO_SYNC (fp) ? EOF : 0; + } +} +libc_hidden_def (fflush_unlocked) diff --git a/src/kernel/libroot/posix/glibc/libio/iofgetpos.c b/src/kernel/libroot/posix/glibc/libio/iofgetpos.c new file mode 100644 index 0000000000..0c80b2fae5 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iofgetpos.c @@ -0,0 +1,82 @@ +/* Copyright (C) 1993, 1995-2001, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include +#include +#include + +int +_IO_new_fgetpos (fp, posp) + _IO_FILE *fp; + _IO_fpos_t *posp; +{ + _IO_off64_t pos; + int result = 0; + CHECK_FILE (fp, EOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0); + if (_IO_in_backup (fp)) + { + if (fp->_mode <= 0) + pos -= fp->_IO_save_end - fp->_IO_save_base; + } + if (pos == _IO_pos_BAD) + { + /* ANSI explicitly requires setting errno to a positive value on + failure. */ +#ifdef EIO + if (errno == 0) + __set_errno (EIO); +#endif + result = EOF; + } + else if ((_IO_off64_t) (__typeof (posp->__pos)) pos != pos) + { +#ifdef EOVERFLOW + __set_errno (EOVERFLOW); +#endif + result = EOF; + } + else + { + posp->__pos = pos; + if (fp->_mode > 0 + && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0) + /* This is a stateful encoding, safe the state. */ + posp->__state = fp->_wide_data->_IO_state; + } + + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} + +strong_alias (_IO_new_fgetpos, __new_fgetpos) +versioned_symbol (libc, _IO_new_fgetpos, _IO_fgetpos, GLIBC_2_2); +versioned_symbol (libc, __new_fgetpos, fgetpos, GLIBC_2_2); diff --git a/src/kernel/libroot/posix/glibc/libio/iofgetpos64.c b/src/kernel/libroot/posix/glibc/libio/iofgetpos64.c new file mode 100644 index 0000000000..3ad7e11cd0 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iofgetpos64.c @@ -0,0 +1,75 @@ +/* Copyright (C) 1993, 1995-2001, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include +#include + + +int +_IO_new_fgetpos64 (fp, posp) + _IO_FILE *fp; + _IO_fpos64_t *posp; +{ +#ifdef _G_LSEEK64 + _IO_off64_t pos; + CHECK_FILE (fp, EOF); + _IO_cleanup_region_start ((void (*) (void *)) _IO_funlockfile, fp); + _IO_flockfile (fp); + pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0); + if (_IO_in_backup (fp)) + { + if (fp->_mode <= 0) + pos -= fp->_IO_save_end - fp->_IO_save_base; + } + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + if (pos == _IO_pos_BAD) + { + /* ANSI explicitly requires setting errno to a positive value on + failure. */ +# ifdef EIO + if (errno == 0) + __set_errno (EIO); +# endif + return EOF; + } + posp->__pos = pos; + if (fp->_mode > 0 + && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0) + /* This is a stateful encoding, safe the state. */ + posp->__state = fp->_wide_data->_IO_state; + return 0; +#else + __set_errno (ENOSYS); + return EOF; +#endif +} + +strong_alias (_IO_new_fgetpos64, __new_fgetpos64) +versioned_symbol (libc, _IO_new_fgetpos64, _IO_fgetpos64, GLIBC_2_2); +versioned_symbol (libc, __new_fgetpos64, fgetpos64, GLIBC_2_2); diff --git a/src/kernel/libroot/posix/glibc/libio/iofgets.c b/src/kernel/libroot/posix/glibc/libio/iofgets.c new file mode 100644 index 0000000000..ea1d3ed53b --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iofgets.c @@ -0,0 +1,74 @@ +/* Copyright (C) 1993, 95, 96, 97, 98, 99, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +char * +_IO_fgets (buf, n, fp) + char *buf; + int n; + _IO_FILE *fp; +{ + _IO_size_t count; + char *result; + int old_error; + CHECK_FILE (fp, NULL); + if (n <= 0) + return NULL; + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + /* This is very tricky since a file descriptor may be in the + non-blocking mode. The error flag doesn't mean much in this + case. We return an error only when there is a new error. */ + old_error = fp->_IO_file_flags & _IO_ERR_SEEN; + fp->_IO_file_flags &= ~_IO_ERR_SEEN; + count = INTUSE(_IO_getline) (fp, buf, n - 1, '\n', 1); + /* If we read in some bytes and errno is EAGAIN, that error will + be reported for next read. */ + if (count == 0 || ((fp->_IO_file_flags & _IO_ERR_SEEN) + && errno != EAGAIN)) + result = NULL; + else + { + buf[count] = '\0'; + result = buf; + } + fp->_IO_file_flags |= old_error; + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} + +#ifdef weak_alias +weak_alias (_IO_fgets, fgets) + +# ifndef _IO_MTSAFE_IO +weak_alias (_IO_fgets, fgets_unlocked) +libc_hidden_weak (fgets_unlocked) +# endif +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/iofgets_u.c b/src/kernel/libroot/posix/glibc/libio/iofgets_u.c new file mode 100644 index 0000000000..ded2a7c83c --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iofgets_u.c @@ -0,0 +1,62 @@ +/* Copyright (C) 1993,1995,1996,1997,1998,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +char * +fgets_unlocked (buf, n, fp) + char *buf; + int n; + _IO_FILE *fp; +{ + _IO_size_t count; + char *result; + int old_error; + CHECK_FILE (fp, NULL); + if (n <= 0) + return NULL; + /* This is very tricky since a file descriptor may be in the + non-blocking mode. The error flag doesn't mean much in this + case. We return an error only when there is a new error. */ + old_error = fp->_IO_file_flags & _IO_ERR_SEEN; + fp->_IO_file_flags &= ~_IO_ERR_SEEN; + count = INTUSE(_IO_getline) (fp, buf, n - 1, '\n', 1); + /* If we read in some bytes and errno is EAGAIN, that error will + be reported for next read. */ + if (count == 0 || ((fp->_IO_file_flags & _IO_ERR_SEEN) + && errno != EAGAIN)) + result = NULL; + else + { + buf[count] = '\0'; + result = buf; + } + fp->_IO_file_flags |= old_error; + return result; +} +libc_hidden_def (fgets_unlocked) diff --git a/src/kernel/libroot/posix/glibc/libio/iofgetws.c b/src/kernel/libroot/posix/glibc/libio/iofgetws.c new file mode 100644 index 0000000000..741bb49e6f --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iofgetws.c @@ -0,0 +1,64 @@ +/* Copyright (C) 1993, 95, 96, 97, 98, 99, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +wchar_t * +fgetws (buf, n, fp) + wchar_t *buf; + int n; + _IO_FILE *fp; +{ + _IO_size_t count; + wchar_t *result; + int old_error; + CHECK_FILE (fp, NULL); + if (n <= 0) + return NULL; + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + /* This is very tricky since a file descriptor may be in the + non-blocking mode. The error flag doesn't mean much in this + case. We return an error only when there is a new error. */ + old_error = fp->_IO_file_flags & _IO_ERR_SEEN; + fp->_IO_file_flags &= ~_IO_ERR_SEEN; + count = _IO_getwline (fp, buf, n - 1, L'\n', 1); + /* If we read in some bytes and errno is EAGAIN, that error will + be reported for next read. */ + if (count == 0 || (_IO_ferror_unlocked (fp) && errno != EAGAIN)) + result = NULL; + else + { + buf[count] = '\0'; + result = buf; + } + fp->_IO_file_flags |= old_error; + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} diff --git a/src/kernel/libroot/posix/glibc/libio/iofgetws_u.c b/src/kernel/libroot/posix/glibc/libio/iofgetws_u.c new file mode 100644 index 0000000000..1253564566 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iofgetws_u.c @@ -0,0 +1,61 @@ +/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +wchar_t * +fgetws_unlocked (buf, n, fp) + wchar_t *buf; + int n; + _IO_FILE *fp; +{ + _IO_size_t count; + wchar_t *result; + int old_error; + CHECK_FILE (fp, NULL); + if (n <= 0) + return NULL; + /* This is very tricky since a file descriptor may be in the + non-blocking mode. The error flag doesn't mean much in this + case. We return an error only when there is a new error. */ + old_error = fp->_IO_file_flags & _IO_ERR_SEEN; + fp->_IO_file_flags &= ~_IO_ERR_SEEN; + count = _IO_getwline (fp, buf, n - 1, L'\n', 1); + /* If we read in some bytes and errno is EAGAIN, that error will + be reported for next read. */ + if (count == 0 || ((fp->_IO_file_flags & _IO_ERR_SEEN) + && errno != EAGAIN)) + result = NULL; + else + { + buf[count] = '\0'; + result = buf; + } + fp->_IO_file_flags |= old_error; + return result; +} diff --git a/src/kernel/libroot/posix/glibc/libio/iofopen.c b/src/kernel/libroot/posix/glibc/libio/iofopen.c new file mode 100644 index 0000000000..8cd68a3690 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iofopen.c @@ -0,0 +1,113 @@ +/* Copyright (C) 1993,1997,1998,1999,2000,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#ifdef __STDC__ +#include +#include +#endif +#ifdef _LIBC +# include +#else +# define _IO_new_fopen fopen +#endif + +_IO_FILE * +__fopen_maybe_mmap (fp) + _IO_FILE *fp; +{ +#ifdef _G_HAVE_MMAP + if ((fp->_flags2 & _IO_FLAGS2_MMAP) && (fp->_flags & _IO_NO_WRITES)) + { + /* Since this is read-only, we might be able to mmap the contents + directly. We delay the decision until the first read attempt by + giving it a jump table containing functions that choose mmap or + vanilla file operations and reset the jump table accordingly. */ + + if (fp->_mode <= 0) + _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps_maybe_mmap; + else + _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_wfile_jumps_maybe_mmap; + fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_maybe_mmap; + } +#endif + return fp; +} + + +_IO_FILE * +__fopen_internal (filename, mode, is32) + const char *filename; + const char *mode; + int is32; +{ + struct locked_FILE + { + struct _IO_FILE_plus fp; +#ifdef _IO_MTSAFE_IO + _IO_lock_t lock; +#endif + struct _IO_wide_data wd; + } *new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); + + if (new_f == NULL) + return NULL; +#ifdef _IO_MTSAFE_IO + new_f->fp.file._lock = &new_f->lock; +#endif +#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T + _IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd, &INTUSE(_IO_wfile_jumps)); +#else + _IO_no_init (&new_f->fp.file, 1, 0, NULL, NULL); +#endif + _IO_JUMPS (&new_f->fp) = &INTUSE(_IO_file_jumps); + INTUSE(_IO_file_init) (&new_f->fp); +#if !_IO_UNIFIED_JUMPTABLES + new_f->fp.vtable = NULL; +#endif + if (INTUSE(_IO_file_fopen) ((_IO_FILE *) new_f, filename, mode, is32) + != NULL) + return __fopen_maybe_mmap (&new_f->fp.file); + + INTUSE(_IO_un_link) (&new_f->fp); + free (new_f); + return NULL; +} + +_IO_FILE * +_IO_new_fopen (filename, mode) + const char *filename; + const char *mode; +{ + return __fopen_internal (filename, mode, 1); +} + +#ifdef _LIBC +strong_alias (_IO_new_fopen, __new_fopen) +versioned_symbol (libc, _IO_new_fopen, _IO_fopen, GLIBC_2_1); +versioned_symbol (libc, __new_fopen, fopen, GLIBC_2_1); +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/iofopen64.c b/src/kernel/libroot/posix/glibc/libio/iofopen64.c new file mode 100644 index 0000000000..69e62b8cda --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iofopen64.c @@ -0,0 +1,48 @@ +/* Copyright (C) 1993, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#ifdef __STDC__ +#include +#endif + +_IO_FILE * +_IO_fopen64 (filename, mode) + const char *filename; + const char *mode; +{ +#ifdef _G_OPEN64 + return __fopen_internal (filename, mode, 0); +#else + __set_errno (ENOSYS); + return NULL; +#endif +} + +#ifdef weak_alias +weak_alias (_IO_fopen64, fopen64) +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/iofopncook.c b/src/kernel/libroot/posix/glibc/libio/iofopncook.c new file mode 100644 index 0000000000..b35b56d24b --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iofopncook.c @@ -0,0 +1,256 @@ +/* Copyright (C) 1993,95,97,99,2000,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include +#include +#include +#include + +/* Prototyped for local functions. */ +static _IO_ssize_t _IO_cookie_read (register _IO_FILE* fp, void* buf, + _IO_ssize_t size); +static _IO_ssize_t _IO_cookie_write (register _IO_FILE* fp, + const void* buf, _IO_ssize_t size); +static _IO_off64_t _IO_cookie_seek (_IO_FILE *fp, _IO_off64_t offset, int dir); +static int _IO_cookie_close (_IO_FILE* fp); + +static _IO_ssize_t +_IO_cookie_read (fp, buf, size) + _IO_FILE *fp; + void *buf; + _IO_ssize_t size; +{ + struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp; + + if (cfile->__io_functions.read == NULL) + return -1; + + return cfile->__io_functions.read (cfile->__cookie, buf, size); +} + +static _IO_ssize_t +_IO_cookie_write (fp, buf, size) + _IO_FILE *fp; + const void *buf; + _IO_ssize_t size; +{ + struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp; + + if (cfile->__io_functions.write == NULL) + return -1; + + return cfile->__io_functions.write (cfile->__cookie, buf, size); +} + +static _IO_off64_t +_IO_cookie_seek (fp, offset, dir) + _IO_FILE *fp; + _IO_off64_t offset; + int dir; +{ + struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp; + + return ((cfile->__io_functions.seek == NULL + || (cfile->__io_functions.seek (cfile->__cookie, &offset, dir) + == -1) + || offset == (_IO_off64_t) -1) + ? _IO_pos_BAD : offset); +} + +static int +_IO_cookie_close (fp) + _IO_FILE *fp; +{ + struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp; + + if (cfile->__io_functions.close == NULL) + return 0; + + return cfile->__io_functions.close (cfile->__cookie); +} + + +static struct _IO_jump_t _IO_cookie_jumps = { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, INTUSE(_IO_file_finish)), + JUMP_INIT(overflow, INTUSE(_IO_file_overflow)), + JUMP_INIT(underflow, INTUSE(_IO_file_underflow)), + JUMP_INIT(uflow, INTUSE(_IO_default_uflow)), + JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)), + JUMP_INIT(xsputn, INTUSE(_IO_file_xsputn)), + JUMP_INIT(xsgetn, INTUSE(_IO_default_xsgetn)), + JUMP_INIT(seekoff, INTUSE(_IO_file_seekoff)), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, INTUSE(_IO_file_setbuf)), + JUMP_INIT(sync, INTUSE(_IO_file_sync)), + JUMP_INIT(doallocate, INTUSE(_IO_file_doallocate)), + JUMP_INIT(read, _IO_cookie_read), + JUMP_INIT(write, _IO_cookie_write), + JUMP_INIT(seek, _IO_cookie_seek), + JUMP_INIT(close, _IO_cookie_close), + JUMP_INIT(stat, _IO_default_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue), +}; + + +void +_IO_cookie_init (struct _IO_cookie_file *cfile, int read_write, + void *cookie, _IO_cookie_io_functions_t io_functions) +{ + INTUSE(_IO_init) (&cfile->__fp.file, 0); + _IO_JUMPS (&cfile->__fp) = &_IO_cookie_jumps; + + cfile->__cookie = cookie; + cfile->__io_functions = io_functions; + + INTUSE(_IO_file_init) (&cfile->__fp); + + cfile->__fp.file._IO_file_flags = + _IO_mask_flags (&cfile->__fp.file, read_write, + _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); + + /* We use a negative number different from -1 for _fileno to mark that + this special stream is not associated with a real file, but still has + to be treated as such. */ + cfile->__fp.file._fileno = -2; +} + + +_IO_FILE * +_IO_fopencookie (cookie, mode, io_functions) + void *cookie; + const char *mode; + _IO_cookie_io_functions_t io_functions; +{ + int read_write; + struct locked_FILE + { + struct _IO_cookie_file cfile; +#ifdef _IO_MTSAFE_IO + _IO_lock_t lock; +#endif + } *new_f; + + switch (*mode++) + { + case 'r': + read_write = _IO_NO_WRITES; + break; + case 'w': + read_write = _IO_NO_READS; + break; + case 'a': + read_write = _IO_NO_READS|_IO_IS_APPENDING; + break; + default: + return NULL; + } + if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+')) + read_write &= _IO_IS_APPENDING; + + new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); + if (new_f == NULL) + return NULL; +#ifdef _IO_MTSAFE_IO + new_f->cfile.__fp.file._lock = &new_f->lock; +#endif + + _IO_cookie_init (&new_f->cfile, read_write, cookie, io_functions); + + return (_IO_FILE *) &new_f->cfile.__fp; +} + +versioned_symbol (libc, _IO_fopencookie, fopencookie, GLIBC_2_2); + +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) + +static _IO_off64_t _IO_old_cookie_seek (_IO_FILE *fp, _IO_off64_t offset, + int dir); +_IO_FILE * _IO_old_fopencookie (void *cookie, const char *mode, + _IO_cookie_io_functions_t io_functions); + +static _IO_off64_t +_IO_old_cookie_seek (fp, offset, dir) + _IO_FILE *fp; + _IO_off64_t offset; + int dir; +{ + struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp; + int (*seek) (_IO_FILE *, _IO_off_t, int); + int ret; + + seek = (int (*)(_IO_FILE *, _IO_off_t, int)) cfile->__io_functions.seek; + if (seek == NULL) + return _IO_pos_BAD; + + ret = seek (cfile->__cookie, offset, dir); + + return (ret == -1) ? _IO_pos_BAD : ret; +} + +static struct _IO_jump_t _IO_old_cookie_jumps = { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, INTUSE(_IO_file_finish)), + JUMP_INIT(overflow, INTUSE(_IO_file_overflow)), + JUMP_INIT(underflow, INTUSE(_IO_file_underflow)), + JUMP_INIT(uflow, INTUSE(_IO_default_uflow)), + JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)), + JUMP_INIT(xsputn, INTUSE(_IO_file_xsputn)), + JUMP_INIT(xsgetn, INTUSE(_IO_default_xsgetn)), + JUMP_INIT(seekoff, INTUSE(_IO_file_seekoff)), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, INTUSE(_IO_file_setbuf)), + JUMP_INIT(sync, INTUSE(_IO_file_sync)), + JUMP_INIT(doallocate, INTUSE(_IO_file_doallocate)), + JUMP_INIT(read, _IO_cookie_read), + JUMP_INIT(write, _IO_cookie_write), + JUMP_INIT(seek, _IO_old_cookie_seek), + JUMP_INIT(close, _IO_cookie_close), + JUMP_INIT(stat, _IO_default_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue), +}; + +_IO_FILE * +_IO_old_fopencookie (cookie, mode, io_functions) + void *cookie; + const char *mode; + _IO_cookie_io_functions_t io_functions; +{ + _IO_FILE *ret; + + ret = _IO_fopencookie (cookie, mode, io_functions); + if (ret != NULL) + _IO_JUMPS ((struct _IO_FILE_plus *) ret) = &_IO_old_cookie_jumps; + + return ret; +} + +compat_symbol (libc, _IO_old_fopencookie, fopencookie, GLIBC_2_0); + +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/iofputs.c b/src/kernel/libroot/posix/glibc/libio/iofputs.c new file mode 100644 index 0000000000..1201735a38 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iofputs.c @@ -0,0 +1,57 @@ +/* Copyright (C) 1993,1996,1997,1998,1999,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +int +_IO_fputs (str, fp) + const char *str; + _IO_FILE *fp; +{ + _IO_size_t len = strlen (str); + int result = EOF; + CHECK_FILE (fp, EOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + if ((fp->_vtable_offset != 0 || _IO_fwide (fp, -1) == -1) + && _IO_sputn (fp, str, len) == len) + result = 1; + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} +libc_hidden_def (_IO_fputs) + +#ifdef weak_alias +weak_alias (_IO_fputs, fputs) + +# ifndef _IO_MTSAFE_IO +weak_alias (_IO_fputs, fputs_unlocked) +libc_hidden_ver (_IO_fputs, fputs_unlocked) +# endif +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/iofputs_u.c b/src/kernel/libroot/posix/glibc/libio/iofputs_u.c new file mode 100644 index 0000000000..475e5334d2 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iofputs_u.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1993,1996,1997,1998,1999,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include +#include + +int +fputs_unlocked (str, fp) + const char *str; + _IO_FILE *fp; +{ + _IO_size_t len = strlen (str); + int result = EOF; + CHECK_FILE (fp, EOF); + if (_IO_fwide (fp, -1) == -1 && _IO_sputn (fp, str, len) == len) + result = 1; + return result; +} +libc_hidden_def (fputs_unlocked) diff --git a/src/kernel/libroot/posix/glibc/libio/iofputws.c b/src/kernel/libroot/posix/glibc/libio/iofputws.c new file mode 100644 index 0000000000..c23156dceb --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iofputws.c @@ -0,0 +1,47 @@ +/* Copyright (C) 1993,1996,1997,1998,1999,2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +int +fputws (str, fp) + const wchar_t *str; + _IO_FILE *fp; +{ + _IO_size_t len = __wcslen (str); + int result = EOF; + CHECK_FILE (fp, EOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + if (_IO_fwide (fp, 1) == 1 + && _IO_sputn (fp, (char *) str, len) == len) + result = 1; + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} diff --git a/src/kernel/libroot/posix/glibc/libio/iofputws_u.c b/src/kernel/libroot/posix/glibc/libio/iofputws_u.c new file mode 100644 index 0000000000..a73f6b529e --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iofputws_u.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1993, 1996-2000, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include +#include + +int +fputws_unlocked (str, fp) + const wchar_t *str; + _IO_FILE *fp; +{ + _IO_size_t len = __wcslen (str); + int result = EOF; + CHECK_FILE (fp, EOF); + if (_IO_fwide (fp, 1) == 1 + && _IO_sputn (fp, (char *) str, len) == len) + result = 1; + return result; +} +libc_hidden_def (fputws_unlocked) diff --git a/src/kernel/libroot/posix/glibc/libio/iofread.c b/src/kernel/libroot/posix/glibc/libio/iofread.c new file mode 100644 index 0000000000..6eb99da4ab --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iofread.c @@ -0,0 +1,58 @@ +/* Copyright (C) 1993,1995,1997,1998,1999,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" + +_IO_size_t +_IO_fread (buf, size, count, fp) + void *buf; + _IO_size_t size; + _IO_size_t count; + _IO_FILE *fp; +{ + _IO_size_t bytes_requested = size * count; + _IO_size_t bytes_read; + CHECK_FILE (fp, 0); + if (bytes_requested == 0) + return 0; + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + bytes_read = INTUSE(_IO_sgetn) (fp, (char *) buf, bytes_requested); + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return bytes_requested == bytes_read ? count : bytes_read / size; +} +INTDEF(_IO_fread) + +#ifdef weak_alias +weak_alias (_IO_fread, fread) + +# ifndef _IO_MTSAFE_IO +weak_alias (_IO_fread, fread_unlocked) +libc_hidden_ver (_IO_fread, fread_unlocked) +# endif +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/iofread_u.c b/src/kernel/libroot/posix/glibc/libio/iofread_u.c new file mode 100644 index 0000000000..98c7ffdd16 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iofread_u.c @@ -0,0 +1,48 @@ +/* Copyright (C) 1993, 1995, 1997, 1998, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +#undef fread_unlocked + +_IO_size_t +fread_unlocked (buf, size, count, fp) + void *buf; + _IO_size_t size; + _IO_size_t count; + _IO_FILE *fp; +{ + _IO_size_t bytes_requested = size * count; + _IO_size_t bytes_read; + CHECK_FILE (fp, 0); + if (bytes_requested == 0) + return 0; + bytes_read = INTUSE(_IO_sgetn) (fp, (char *) buf, bytes_requested); + return bytes_requested == bytes_read ? count : bytes_read / size; +} +libc_hidden_def (fread_unlocked) diff --git a/src/kernel/libroot/posix/glibc/libio/iofsetpos.c b/src/kernel/libroot/posix/glibc/libio/iofsetpos.c new file mode 100644 index 0000000000..f3821e2fa5 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iofsetpos.c @@ -0,0 +1,67 @@ +/* Copyright (C) 1993, 1995, 1997-2000, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include +#include +#include + +int +_IO_new_fsetpos (fp, posp) + _IO_FILE *fp; + const _IO_fpos_t *posp; +{ + int result; + CHECK_FILE (fp, EOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + if (_IO_seekpos_unlocked (fp, posp->__pos, _IOS_INPUT|_IOS_OUTPUT) + == _IO_pos_BAD) + { + /* ANSI explicitly requires setting errno to a positive value on + failure. */ +#ifdef EIO + if (errno == 0) + __set_errno (EIO); +#endif + result = EOF; + } + else + { + result = 0; + if (fp->_mode > 0 + && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0) + /* This is a stateful encoding, restore the state. */ + fp->_wide_data->_IO_state = posp->__state; + } + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} + +strong_alias (_IO_new_fsetpos, __new_fsetpos) +versioned_symbol (libc, _IO_new_fsetpos, _IO_fsetpos, GLIBC_2_2); +versioned_symbol (libc, __new_fsetpos, fsetpos, GLIBC_2_2); diff --git a/src/kernel/libroot/posix/glibc/libio/iofsetpos64.c b/src/kernel/libroot/posix/glibc/libio/iofsetpos64.c new file mode 100644 index 0000000000..4746d720c3 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iofsetpos64.c @@ -0,0 +1,72 @@ +/* Copyright (C) 1993, 1995, 1997-2000, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include +#include +#include + +int +_IO_new_fsetpos64 (fp, posp) + _IO_FILE *fp; + const _IO_fpos64_t *posp; +{ +#ifdef _G_LSEEK64 + int result; + CHECK_FILE (fp, EOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + if (_IO_seekpos_unlocked (fp, posp->__pos, _IOS_INPUT|_IOS_OUTPUT) + == _IO_pos_BAD) + { + /* ANSI explicitly requires setting errno to a positive value on + failure. */ +#ifdef EIO + if (errno == 0) + __set_errno (EIO); +#endif + result = EOF; + } + else + { + result = 0; + if (fp->_mode > 0 + && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0) + /* This is a stateful encoding, safe the state. */ + fp->_wide_data->_IO_state = posp->__state; + } + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +#else + __set_errno (ENOSYS); + return EOF; +#endif +} + +strong_alias (_IO_new_fsetpos64, __new_fsetpos64) +versioned_symbol (libc, __new_fsetpos64, fsetpos64, GLIBC_2_2); +versioned_symbol (libc, _IO_new_fsetpos64, _IO_fsetpos64, GLIBC_2_2); diff --git a/src/kernel/libroot/posix/glibc/libio/ioftell.c b/src/kernel/libroot/posix/glibc/libio/ioftell.c new file mode 100644 index 0000000000..fd5da6b618 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/ioftell.c @@ -0,0 +1,70 @@ +/* Copyright (C) 1993, 1995-2000, 2001, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include +#include +/* ANSI explicily requires setting errno to a positive value on failure. */ + +long int +_IO_ftell (fp) + _IO_FILE *fp; +{ + _IO_off64_t pos; + CHECK_FILE (fp, -1L); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0); + if (_IO_in_backup (fp)) + { + if (fp->_vtable_offset != 0 || fp->_mode <= 0) + pos -= fp->_IO_save_end - fp->_IO_save_base; + } + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + if (pos == _IO_pos_BAD) + { +#ifdef EIO + if (errno == 0) + __set_errno (EIO); +#endif + return -1L; + } + if ((_IO_off64_t) (off_t) pos != pos) + { +#ifdef EOVERFLOW + __set_errno (EOVERFLOW); +#endif + return -1L; + } + return pos; +} +INTDEF(_IO_ftell) + +#ifdef weak_alias +weak_alias (_IO_ftell, ftell) +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/iofwide.c b/src/kernel/libroot/posix/glibc/libio/iofwide.c new file mode 100644 index 0000000000..225237ef66 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iofwide.c @@ -0,0 +1,498 @@ +/* Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include +#ifdef _LIBC +# include +# include +#endif +#include +#include +#include + +#ifdef _LIBC +# include +# include +# include +# include +# include +#endif + + +/* Prototypes of libio's codecvt functions. */ +static enum __codecvt_result do_out (struct _IO_codecvt *codecvt, + __mbstate_t *statep, + const wchar_t *from_start, + const wchar_t *from_end, + const wchar_t **from_stop, char *to_start, + char *to_end, char **to_stop); +static enum __codecvt_result do_unshift (struct _IO_codecvt *codecvt, + __mbstate_t *statep, char *to_start, + char *to_end, char **to_stop); +static enum __codecvt_result do_in (struct _IO_codecvt *codecvt, + __mbstate_t *statep, + const char *from_start, + const char *from_end, + const char **from_stop, wchar_t *to_start, + wchar_t *to_end, wchar_t **to_stop); +static int do_encoding (struct _IO_codecvt *codecvt); +static int do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep, + const char *from_start, + const char *from_end, _IO_size_t max); +static int do_max_length (struct _IO_codecvt *codecvt); +static int do_always_noconv (struct _IO_codecvt *codecvt); + + +/* The functions used in `codecvt' for libio are always the same. */ +struct _IO_codecvt __libio_codecvt = +{ + .__codecvt_destr = NULL, /* Destructor, never used. */ + .__codecvt_do_out = do_out, + .__codecvt_do_unshift = do_unshift, + .__codecvt_do_in = do_in, + .__codecvt_do_encoding = do_encoding, + .__codecvt_do_always_noconv = do_always_noconv, + .__codecvt_do_length = do_length, + .__codecvt_do_max_length = do_max_length +}; + + +#ifdef _LIBC +struct __gconv_trans_data __libio_translit attribute_hidden = +{ + .__trans_fct = __gconv_transliterate +}; +#endif + + +/* Return orientation of stream. If mode is nonzero try to change + the orientation first. */ +#undef _IO_fwide +int +_IO_fwide (fp, mode) + _IO_FILE *fp; + int mode; +{ + /* Normalize the value. */ + mode = mode < 0 ? -1 : (mode == 0 ? 0 : 1); + + if (mode == 0) + /* The caller simply wants to know about the current orientation. */ + return fp->_mode; + +#if defined SHARED && defined _LIBC \ + && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + if (__builtin_expect (&_IO_stdin_used == NULL, 0) + && (fp == _IO_stdin || fp == _IO_stdout || fp == _IO_stderr)) + /* This is for a stream in the glibc 2.0 format. */ + return -1; +#endif + + if (fp->_mode != 0) + /* The orientation already has been determined. */ + return fp->_mode; + + /* Set the orientation appropriately. */ + if (mode > 0) + { + struct _IO_codecvt *cc = fp->_codecvt = &fp->_wide_data->_codecvt; + + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end; + fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_write_base; + + /* Get the character conversion functions based on the currently + selected locale for LC_CTYPE. */ +#ifdef _LIBC + { + struct gconv_fcts fcts; + + /* Clear the state. We start all over again. */ + memset (&fp->_wide_data->_IO_state, '\0', sizeof (__mbstate_t)); + memset (&fp->_wide_data->_IO_last_state, '\0', sizeof (__mbstate_t)); + + __wcsmbs_clone_conv (&fcts); + assert (fcts.towc_nsteps == 1); + assert (fcts.tomb_nsteps == 1); + + /* The functions are always the same. */ + *cc = __libio_codecvt; + + cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps; + cc->__cd_in.__cd.__steps = fcts.towc; + + cc->__cd_in.__cd.__data[0].__invocation_counter = 0; + cc->__cd_in.__cd.__data[0].__internal_use = 1; + cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST; + cc->__cd_in.__cd.__data[0].__statep = &fp->_wide_data->_IO_state; + + /* XXX For now no transliteration. */ + cc->__cd_in.__cd.__data[0].__trans = NULL; + + cc->__cd_out.__cd.__nsteps = fcts.tomb_nsteps; + cc->__cd_out.__cd.__steps = fcts.tomb; + + cc->__cd_out.__cd.__data[0].__invocation_counter = 0; + cc->__cd_out.__cd.__data[0].__internal_use = 1; + cc->__cd_out.__cd.__data[0].__flags = __GCONV_IS_LAST; + cc->__cd_out.__cd.__data[0].__statep = &fp->_wide_data->_IO_state; + + /* And now the transliteration. */ + cc->__cd_out.__cd.__data[0].__trans = &__libio_translit; + } +#else +# ifdef _GLIBCPP_USE_WCHAR_T + { + /* Determine internal and external character sets. + + XXX For now we make our life easy: we assume a fixed internal + encoding (as most sane systems have; hi HP/UX!). If somebody + cares about systems which changing internal charsets they + should come up with a solution for the determination of the + currently used internal character set. */ + const char *internal_ccs = _G_INTERNAL_CCS; + const char *external_ccs = NULL; + +# ifdef HAVE_NL_LANGINFO + external_ccs = nl_langinfo (CODESET); +# endif + if (external_ccs == NULL) + external_ccs = "ISO-8859-1"; + + cc->__cd_in = iconv_open (internal_ccs, external_ccs); + if (cc->__cd_in != (iconv_t) -1) + cc->__cd_out = iconv_open (external_ccs, internal_ccs); + + if (cc->__cd_in == (iconv_t) -1 || cc->__cd_out == (iconv_t) -1) + { + if (cc->__cd_in != (iconv_t) -1) + iconv_close (cc->__cd_in); + /* XXX */ + abort (); + } + } +# else +# error "somehow determine this from LC_CTYPE" +# endif +#endif + + /* From now on use the wide character callback functions. */ + ((struct _IO_FILE_plus *) fp)->vtable = fp->_wide_data->_wide_vtable; + + /* One last twist: we get the current stream position. The wide + char streams have much more problems with not knowing the + current position and so we should disable the optimization + which allows the functions without knowing the position. */ + fp->_offset = _IO_SYSSEEK (fp, 0, _IO_seek_cur); + } + + /* Set the mode now. */ + fp->_mode = mode; + + return mode; +} + + +static enum __codecvt_result +do_out (struct _IO_codecvt *codecvt, __mbstate_t *statep, + const wchar_t *from_start, const wchar_t *from_end, + const wchar_t **from_stop, char *to_start, char *to_end, + char **to_stop) +{ + enum __codecvt_result result; + +#ifdef _LIBC + struct __gconv_step *gs = codecvt->__cd_out.__cd.__steps; + int status; + size_t dummy; + const unsigned char *from_start_copy = (unsigned char *) from_start; + + codecvt->__cd_out.__cd.__data[0].__outbuf = to_start; + codecvt->__cd_out.__cd.__data[0].__outbufend = to_end; + codecvt->__cd_out.__cd.__data[0].__statep = statep; + + status = DL_CALL_FCT (gs->__fct, + (gs, codecvt->__cd_out.__cd.__data, &from_start_copy, + (const unsigned char *) from_end, NULL, + &dummy, 0, 0)); + + *from_stop = (wchar_t *) from_start_copy; + *to_stop = codecvt->__cd_out.__cd.__data[0].__outbuf; + + switch (status) + { + case __GCONV_OK: + case __GCONV_EMPTY_INPUT: + result = __codecvt_ok; + break; + + case __GCONV_FULL_OUTPUT: + case __GCONV_INCOMPLETE_INPUT: + result = __codecvt_partial; + break; + + default: + result = __codecvt_error; + break; + } +#else +# ifdef _GLIBCPP_USE_WCHAR_T + size_t res; + const char *from_start_copy = (const char *) from_start; + size_t from_len = from_end - from_start; + char *to_start_copy = to_start; + size_t to_len = to_end - to_start; + res = iconv (codecvt->__cd_out, &from_start_copy, &from_len, + &to_start_copy, &to_len); + + if (res == 0 || from_len == 0) + result = __codecvt_ok; + else if (to_len < codecvt->__codecvt_do_max_length (codecvt)) + result = __codecvt_partial; + else + result = __codecvt_error; + +# else + /* Decide what to do. */ + result = __codecvt_error; +# endif +#endif + + return result; +} + + +static enum __codecvt_result +do_unshift (struct _IO_codecvt *codecvt, __mbstate_t *statep, + char *to_start, char *to_end, char **to_stop) +{ + enum __codecvt_result result; + +#ifdef _LIBC + struct __gconv_step *gs = codecvt->__cd_out.__cd.__steps; + int status; + size_t dummy; + + codecvt->__cd_out.__cd.__data[0].__outbuf = to_start; + codecvt->__cd_out.__cd.__data[0].__outbufend = to_end; + codecvt->__cd_out.__cd.__data[0].__statep = statep; + + status = DL_CALL_FCT (gs->__fct, + (gs, codecvt->__cd_out.__cd.__data, NULL, NULL, + NULL, &dummy, 1, 0)); + + *to_stop = codecvt->__cd_out.__cd.__data[0].__outbuf; + + switch (status) + { + case __GCONV_OK: + case __GCONV_EMPTY_INPUT: + result = __codecvt_ok; + break; + + case __GCONV_FULL_OUTPUT: + case __GCONV_INCOMPLETE_INPUT: + result = __codecvt_partial; + break; + + default: + result = __codecvt_error; + break; + } +#else +# ifdef _GLIBCPP_USE_WCHAR_T + size_t res; + char *to_start_copy = (char *) to_start; + size_t to_len = to_end - to_start; + + res = iconv (codecvt->__cd_out, NULL, NULL, &to_start_copy, &to_len); + + if (res == 0) + result = __codecvt_ok; + else if (to_len < codecvt->__codecvt_do_max_length (codecvt)) + result = __codecvt_partial; + else + result = __codecvt_error; +# else + /* Decide what to do. */ + result = __codecvt_error; +# endif +#endif + + return result; +} + + +static enum __codecvt_result +do_in (struct _IO_codecvt *codecvt, __mbstate_t *statep, + const char *from_start, const char *from_end, const char **from_stop, + wchar_t *to_start, wchar_t *to_end, wchar_t **to_stop) +{ + enum __codecvt_result result; + +#ifdef _LIBC + struct __gconv_step *gs = codecvt->__cd_in.__cd.__steps; + int status; + size_t dummy; + const unsigned char *from_start_copy = (unsigned char *) from_start; + + codecvt->__cd_in.__cd.__data[0].__outbuf = (char *) to_start; + codecvt->__cd_in.__cd.__data[0].__outbufend = (char *) to_end; + codecvt->__cd_in.__cd.__data[0].__statep = statep; + + status = DL_CALL_FCT (gs->__fct, + (gs, codecvt->__cd_in.__cd.__data, &from_start_copy, + from_end, NULL, &dummy, 0, 0)); + + *from_stop = from_start_copy; + *to_stop = (wchar_t *) codecvt->__cd_in.__cd.__data[0].__outbuf; + + switch (status) + { + case __GCONV_OK: + case __GCONV_EMPTY_INPUT: + result = __codecvt_ok; + break; + + case __GCONV_FULL_OUTPUT: + case __GCONV_INCOMPLETE_INPUT: + result = __codecvt_partial; + break; + + default: + result = __codecvt_error; + break; + } +#else +# ifdef _GLIBCPP_USE_WCHAR_T + size_t res; + const char *from_start_copy = (const char *) from_start; + size_t from_len = from_end - from_start; + char *to_start_copy = (char *) from_start; + size_t to_len = to_end - to_start; + + res = iconv (codecvt->__cd_in, &from_start_copy, &from_len, + &to_start_copy, &to_len); + + if (res == 0) + result = __codecvt_ok; + else if (to_len == 0) + result = __codecvt_partial; + else if (from_len < codecvt->__codecvt_do_max_length (codecvt)) + result = __codecvt_partial; + else + result = __codecvt_error; +# else + /* Decide what to do. */ + result = __codecvt_error; +# endif +#endif + + return result; +} + + +static int +do_encoding (struct _IO_codecvt *codecvt) +{ +#ifdef _LIBC + /* See whether the encoding is stateful. */ + if (codecvt->__cd_in.__cd.__steps[0].__stateful) + return -1; + /* Fortunately not. Now determine the input bytes for the conversion + necessary for each wide character. */ + if (codecvt->__cd_in.__cd.__steps[0].__min_needed_from + != codecvt->__cd_in.__cd.__steps[0].__max_needed_from) + /* Not a constant value. */ + return 0; + + return codecvt->__cd_in.__cd.__steps[0].__min_needed_from; +#else + /* Worst case scenario. */ + return -1; +#endif +} + + +static int +do_always_noconv (struct _IO_codecvt *codecvt) +{ + return 0; +} + + +static int +do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep, + const char *from_start, const char *from_end, _IO_size_t max) +{ + int result; +#ifdef _LIBC + const unsigned char *cp = (const unsigned char *) from_start; + wchar_t to_buf[max]; + struct __gconv_step *gs = codecvt->__cd_in.__cd.__steps; + int status; + size_t dummy; + + codecvt->__cd_in.__cd.__data[0].__outbuf = (char *) to_buf; + codecvt->__cd_in.__cd.__data[0].__outbufend = (char *) &to_buf[max]; + codecvt->__cd_in.__cd.__data[0].__statep = statep; + + status = DL_CALL_FCT (gs->__fct, + (gs, codecvt->__cd_in.__cd.__data, &cp, from_end, + NULL, &dummy, 0, 0)); + + result = cp - (const unsigned char *) from_start; +#else +# ifdef _GLIBCPP_USE_WCHAR_T + const char *from_start_copy = (const char *) from_start; + size_t from_len = from_end - from_start; + wchar_t to_buf[max]; + size_t res; + char *to_start = (char *) to_buf; + + res = iconv (codecvt->__cd_in, &from_start_copy, &from_len, + &to_start, &max); + + result = from_start_copy - (char *) from_start; +# else + /* Decide what to do. */ + result = 0; +# endif +#endif + + return result; +} + + +static int +do_max_length (struct _IO_codecvt *codecvt) +{ +#ifdef _LIBC + return codecvt->__cd_in.__cd.__steps[0].__max_needed_from; +#else + return MB_CUR_MAX; +#endif +} diff --git a/src/kernel/libroot/posix/glibc/libio/iofwrite.c b/src/kernel/libroot/posix/glibc/libio/iofwrite.c new file mode 100644 index 0000000000..67ed6a1f12 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iofwrite.c @@ -0,0 +1,63 @@ +/* Copyright (C) 1993,96,97,98,99,2000,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" + +_IO_size_t +_IO_fwrite (buf, size, count, fp) + const void *buf; + _IO_size_t size; + _IO_size_t count; + _IO_FILE *fp; +{ + _IO_size_t request = size * count; + _IO_size_t written = 0; + CHECK_FILE (fp, 0); + if (request == 0) + return 0; + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + if (fp->_vtable_offset != 0 || _IO_fwide (fp, -1) == -1) + written = _IO_sputn (fp, (const char *) buf, request); + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + if (written == request) + return count; + else + return written / size; +} +INTDEF(_IO_fwrite) + +#ifdef weak_alias +# include +weak_alias (_IO_fwrite, fwrite) +libc_hidden_weak (fwrite) +# ifndef _IO_MTSAFE_IO +weak_alias (_IO_fwrite, fwrite_unlocked) +libc_hidden_weak (fwrite_unlocked) +# endif +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/iofwrite_u.c b/src/kernel/libroot/posix/glibc/libio/iofwrite_u.c new file mode 100644 index 0000000000..738cc5b28f --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iofwrite_u.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1993, 1996-2000, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +#undef fwrite_unlocked + +_IO_size_t +fwrite_unlocked (buf, size, count, fp) + const void *buf; + _IO_size_t size; + _IO_size_t count; + _IO_FILE *fp; +{ + _IO_size_t request = size * count; + _IO_size_t written = 0; + CHECK_FILE (fp, 0); + if (request == 0) + return 0; + if (_IO_fwide (fp, -1) == -1) + { + written = _IO_sputn (fp, (const char *) buf, request); + if (written == request) + return count; + } + + return written / size; +} +libc_hidden_def (fwrite_unlocked) diff --git a/src/kernel/libroot/posix/glibc/libio/iogetdelim.c b/src/kernel/libroot/posix/glibc/libio/iogetdelim.c new file mode 100644 index 0000000000..edc5228693 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iogetdelim.c @@ -0,0 +1,131 @@ +/* Copyright (C) 1994, 1996, 1997, 1998, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#ifdef __STDC__ +#include +#endif +#include "libioP.h" +#include +#include + +/* Read up to (and including) a TERMINATOR from FP into *LINEPTR + (and null-terminate it). *LINEPTR is a pointer returned from malloc (or + NULL), pointing to *N characters of space. It is realloc'ed as + necessary. Returns the number of characters read (not including the + null terminator), or -1 on error or EOF. */ + +_IO_ssize_t +_IO_getdelim (lineptr, n, delimiter, fp) + char **lineptr; + _IO_size_t *n; + int delimiter; + _IO_FILE *fp; +{ + int result; + _IO_ssize_t cur_len = 0; + _IO_ssize_t len; + + if (lineptr == NULL || n == NULL) + { + MAYBE_SET_EINVAL; + return -1; + } + CHECK_FILE (fp, -1); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + if (_IO_ferror_unlocked (fp)) + { + result = -1; + goto unlock_return; + } + + if (*lineptr == NULL || *n == 0) + { + *n = 120; + *lineptr = (char *) malloc (*n); + if (*lineptr == NULL) + { + result = -1; + goto unlock_return; + } + } + + len = fp->_IO_read_end - fp->_IO_read_ptr; + if (len <= 0) + { + if (__underflow (fp) == EOF) + { + result = -1; + goto unlock_return; + } + len = fp->_IO_read_end - fp->_IO_read_ptr; + } + + for (;;) + { + _IO_size_t needed; + char *t; + t = (char *) memchr ((void *) fp->_IO_read_ptr, delimiter, len); + if (t != NULL) + len = (t - fp->_IO_read_ptr) + 1; + /* Make enough space for len+1 (for final NUL) bytes. */ + needed = cur_len + len + 1; + if (needed > *n) + { + char *new_lineptr; + + if (needed < 2 * *n) + needed = 2 * *n; /* Be generous. */ + new_lineptr = (char *) realloc (*lineptr, needed); + if (new_lineptr == NULL) + { + result = -1; + goto unlock_return; + } + *lineptr = new_lineptr; + *n = needed; + } + memcpy (*lineptr + cur_len, (void *) fp->_IO_read_ptr, len); + fp->_IO_read_ptr += len; + cur_len += len; + if (t != NULL || __underflow (fp) == EOF) + break; + len = fp->_IO_read_end - fp->_IO_read_ptr; + } + (*lineptr)[cur_len] = '\0'; + result = cur_len; + +unlock_return: + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} + +#ifdef weak_alias +weak_alias (_IO_getdelim, __getdelim) +weak_alias (_IO_getdelim, getdelim) +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/iogetline.c b/src/kernel/libroot/posix/glibc/libio/iogetline.c new file mode 100644 index 0000000000..eca38cf773 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iogetline.c @@ -0,0 +1,122 @@ +/* Copyright (C) 1993,1997,1998,2000,2001,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +#if defined _LIBC || !_G_HAVE_IO_GETLINE_INFO + +_IO_size_t +_IO_getline (fp, buf, n, delim, extract_delim) + _IO_FILE *fp; + char *buf; + _IO_size_t n; + int delim; + int extract_delim; +{ + return INTUSE(_IO_getline_info) (fp, buf, n, delim, extract_delim, + (int *) 0); +} +INTDEF(_IO_getline) + +/* Algorithm based on that used by Berkeley pre-4.4 fgets implementation. + + Read chars into buf (of size n), until delim is seen. + Return number of chars read (at most n). + Does not put a terminating '\0' in buf. + If extract_delim < 0, leave delimiter unread. + If extract_delim > 0, insert delim in output. */ + +_IO_size_t +_IO_getline_info (fp, buf, n, delim, extract_delim, eof) + _IO_FILE *fp; + char *buf; + _IO_size_t n; + int delim; + int extract_delim; + int *eof; +{ + char *ptr = buf; + if (eof != NULL) + *eof = 0; + if (__builtin_expect (fp->_mode, -1) == 0) + _IO_fwide (fp, -1); + while (n != 0) + { + _IO_ssize_t len = fp->_IO_read_end - fp->_IO_read_ptr; + if (len <= 0) + { + int c = __uflow (fp); + if (c == EOF) + { + if (eof) *eof = c; + break; + } + if (c == delim) + { + if (extract_delim > 0) + *ptr++ = c; + else if (extract_delim < 0) + INTUSE(_IO_sputbackc) (fp, c); + if (extract_delim > 0) + ++len; + return ptr - buf; + } + *ptr++ = c; + n--; + } + else + { + char *t; + if ((_IO_size_t) len >= n) + len = n; + t = (char *) memchr ((void *) fp->_IO_read_ptr, delim, len); + if (t != NULL) + { + _IO_size_t old_len = ptr-buf; + len = t - fp->_IO_read_ptr; + if (extract_delim >= 0) + { + ++t; + if (extract_delim > 0) + ++len; + } + memcpy ((void *) ptr, (void *) fp->_IO_read_ptr, len); + fp->_IO_read_ptr = t; + return old_len + len; + } + memcpy ((void *) ptr, (void *) fp->_IO_read_ptr, len); + fp->_IO_read_ptr += len; + ptr += len; + n -= len; + } + } + return ptr - buf; +} +INTDEF(_IO_getline_info) + +#endif /* Defined _LIBC || !_G_HAVE_IO_GETLINE_INFO */ diff --git a/src/kernel/libroot/posix/glibc/libio/iogets.c b/src/kernel/libroot/posix/glibc/libio/iogets.c new file mode 100644 index 0000000000..95e8368dbb --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iogets.c @@ -0,0 +1,81 @@ +/* Copyright (C) 1993, 1996, 1997, 1998, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +char* +_IO_gets (buf) + char *buf; +{ + _IO_size_t count; + int ch; + char *retval; + + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _IO_stdin); + _IO_flockfile (_IO_stdin); + ch = _IO_getc_unlocked (_IO_stdin); + if (ch == EOF) + { + retval = NULL; + goto unlock_return; + } + if (ch == '\n') + count = 0; + else + { + /* This is very tricky since a file descriptor may be in the + non-blocking mode. The error flag doesn't mean much in this + case. We return an error only when there is a new error. */ + int old_error = _IO_stdin->_IO_file_flags & _IO_ERR_SEEN; + _IO_stdin->_IO_file_flags &= ~_IO_ERR_SEEN; + buf[0] = (char) ch; + count = INTUSE(_IO_getline) (_IO_stdin, buf + 1, INT_MAX, '\n', 0) + 1; + if (_IO_stdin->_IO_file_flags & _IO_ERR_SEEN) + { + retval = NULL; + goto unlock_return; + } + else + _IO_stdin->_IO_file_flags |= old_error; + } + buf[count] = 0; + retval = buf; +unlock_return: + _IO_funlockfile (_IO_stdin); + _IO_cleanup_region_end (0); + return retval; +} + +#ifdef weak_alias +weak_alias (_IO_gets, gets) +#endif + +#ifdef _LIBC +link_warning (gets, "the `gets' function is dangerous and should not be used.") +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/iogetwline.c b/src/kernel/libroot/posix/glibc/libio/iogetwline.c new file mode 100644 index 0000000000..e529b7d832 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iogetwline.c @@ -0,0 +1,127 @@ +/* Copyright (C) 1993,1997,1998,1999,2000,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include +#include + +#ifdef _LIBC +# define wmemcpy __wmemcpy +#endif + +#if defined _LIBC || !_G_HAVE_IO_GETLINE_INFO + +_IO_size_t +_IO_getwline (fp, buf, n, delim, extract_delim) + _IO_FILE *fp; + wchar_t *buf; + _IO_size_t n; + wint_t delim; + int extract_delim; +{ + return _IO_getwline_info (fp, buf, n, delim, extract_delim, (wint_t *) 0); +} + +/* Algorithm based on that used by Berkeley pre-4.4 fgets implementation. + + Read chars into buf (of size n), until delim is seen. + Return number of chars read (at most n). + Does not put a terminating '\0' in buf. + If extract_delim < 0, leave delimiter unread. + If extract_delim > 0, insert delim in output. */ + +_IO_size_t +_IO_getwline_info (fp, buf, n, delim, extract_delim, eof) + _IO_FILE *fp; + wchar_t *buf; + _IO_size_t n; + wint_t delim; + int extract_delim; + wint_t *eof; +{ + wchar_t *ptr = buf; + if (eof != NULL) + *eof = 0; + if (__builtin_expect (fp->_mode, 1) == 0) + _IO_fwide (fp, 1); + while (n != 0) + { + _IO_ssize_t len = (fp->_wide_data->_IO_read_end + - fp->_wide_data->_IO_read_ptr); + if (len <= 0) + { + wint_t wc = __wuflow (fp); + if (wc == WEOF) + { + if (eof) + *eof = wc; + break; + } + if (wc == delim) + { + if (extract_delim > 0) + *ptr++ = wc; + else if (extract_delim < 0) + INTUSE(_IO_sputbackc) (fp, wc); + return ptr - buf; + if (extract_delim > 0) + ++len; + } + *ptr++ = wc; + n--; + } + else + { + wchar_t *t; + if ((_IO_size_t) len >= n) + len = n; + t = wmemchr ((void *) fp->_wide_data->_IO_read_ptr, delim, len); + if (t != NULL) + { + _IO_size_t old_len = ptr - buf; + len = t - fp->_wide_data->_IO_read_ptr; + if (extract_delim >= 0) + { + ++t; + if (extract_delim > 0) + ++len; + } + wmemcpy ((void *) ptr, (void *) fp->_wide_data->_IO_read_ptr, + len); + fp->_wide_data->_IO_read_ptr = t; + return old_len + len; + } + wmemcpy ((void *) ptr, (void *) fp->_wide_data->_IO_read_ptr, len); + fp->_wide_data->_IO_read_ptr += len; + ptr += len; + n -= len; + } + } + return ptr - buf; +} + +#endif /* Defined _LIBC || !_G_HAVE_IO_GETLINE_INFO */ diff --git a/src/kernel/libroot/posix/glibc/libio/iolibio.h b/src/kernel/libroot/posix/glibc/libio/iolibio.h new file mode 100644 index 0000000000..db71be25c8 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iolibio.h @@ -0,0 +1,101 @@ +#include + +/* These emulate stdio functionality, but with a different name + (_IO_ungetc instead of ungetc), and using _IO_FILE instead of FILE. */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int _IO_fclose __P((_IO_FILE*)); +extern int _IO_new_fclose __P((_IO_FILE*)); +extern int _IO_old_fclose __P((_IO_FILE*)); +extern _IO_FILE *_IO_fdopen __P((int, const char*)); +extern _IO_FILE *_IO_old_fdopen __P((int, const char*)); +extern _IO_FILE *_IO_new_fdopen __P((int, const char*)); +extern int _IO_fflush __P((_IO_FILE*)); +extern int _IO_fgetpos __P((_IO_FILE*, _IO_fpos_t*)); +extern int _IO_fgetpos64 __P((_IO_FILE*, _IO_fpos64_t*)); +extern char* _IO_fgets __P((char*, int, _IO_FILE*)); +extern _IO_FILE *_IO_fopen __P((const char*, const char*)); +extern _IO_FILE *_IO_old_fopen __P((const char*, const char*)); +extern _IO_FILE *_IO_new_fopen __P((const char*, const char*)); +extern _IO_FILE *_IO_fopen64 __P((const char*, const char*)); +extern _IO_FILE *__fopen_internal __P((const char*, const char*, int)); +extern _IO_FILE *__fopen_maybe_mmap __P((_IO_FILE *)); +extern int _IO_fprintf __P((_IO_FILE*, const char*, ...)); +extern int _IO_fputs __P((const char*, _IO_FILE*)); +libc_hidden_proto (_IO_fputs) +extern int _IO_fsetpos __P((_IO_FILE*, const _IO_fpos_t *)); +extern int _IO_fsetpos64 __P((_IO_FILE*, const _IO_fpos64_t *)); +extern long int _IO_ftell __P((_IO_FILE*)); +extern _IO_size_t _IO_fread __P((void*, _IO_size_t, _IO_size_t, _IO_FILE*)); +extern _IO_size_t _IO_fwrite __P((const void*, + _IO_size_t, _IO_size_t, _IO_FILE*)); +extern char* _IO_gets __P((char*)); +extern void _IO_perror __P((const char*)); +extern int _IO_printf __P((const char*, ...)); +extern int _IO_puts __P((const char*)); +extern int _IO_scanf __P((const char*, ...)); +extern void _IO_setbuffer __P((_IO_FILE *, char*, _IO_size_t)); +extern int _IO_setvbuf __P((_IO_FILE*, char*, int, _IO_size_t)); +extern int _IO_sscanf __P((const char*, const char*, ...)); +extern int _IO_sprintf __P((char *, const char*, ...)); +extern int _IO_ungetc __P((int, _IO_FILE*)); +extern int _IO_vsscanf __P((const char *, const char *, _IO_va_list)); +extern int _IO_vsprintf __P((char*, const char*, _IO_va_list)); +extern int _IO_vswprintf __P((wchar_t*, _IO_size_t, const wchar_t*, + _IO_va_list)); + +struct obstack; +extern int _IO_obstack_vprintf __P ((struct obstack *, const char *, + _IO_va_list)); +extern int _IO_obstack_printf __P ((struct obstack *, const char *, ...)); +#ifndef _IO_pos_BAD +#define _IO_pos_BAD ((_IO_off64_t)(-1)) +#endif +#define _IO_clearerr(FP) ((FP)->_flags &= ~(_IO_ERR_SEEN|_IO_EOF_SEEN)) +#define _IO_fseek(__fp, __offset, __whence) \ + (_IO_seekoff_unlocked (__fp, __offset, __whence, _IOS_INPUT|_IOS_OUTPUT) \ + == _IO_pos_BAD ? EOF : 0) +#define _IO_rewind(FILE) \ + (void) _IO_seekoff_unlocked (FILE, 0, 0, _IOS_INPUT|_IOS_OUTPUT) +#define _IO_vprintf(FORMAT, ARGS) \ + INTUSE(_IO_vfprintf) (_IO_stdout, FORMAT, ARGS) +#define _IO_freopen(FILENAME, MODE, FP) \ + (INTUSE(_IO_file_close_it)(FP), \ + INTUSE(_IO_file_fopen)(FP, FILENAME, MODE, 1)) +#define _IO_old_freopen(FILENAME, MODE, FP) \ + (_IO_old_file_close_it (FP), _IO_old_file_fopen(FP, FILENAME, MODE)) +#define _IO_freopen64(FILENAME, MODE, FP) \ + (INTUSE(_IO_file_close_it)(FP), \ + INTUSE(_IO_file_fopen)(FP, FILENAME, MODE, 0)) +#define _IO_fileno(FP) ((FP)->_fileno) +extern _IO_FILE* _IO_popen __P((const char*, const char*)); +extern _IO_FILE* _IO_new_popen __P((const char*, const char*)); +extern _IO_FILE* _IO_old_popen __P((const char*, const char*)); +extern int __new_pclose __P((_IO_FILE *)); +extern int __old_pclose __P((_IO_FILE *)); +#define _IO_pclose _IO_fclose +#define _IO_setbuf(_FP, _BUF) INTUSE(_IO_setbuffer)(_FP, _BUF, _IO_BUFSIZ) +#define _IO_setlinebuf(_FP) INTUSE(_IO_setvbuf)(_FP, NULL, 1, 0) + +_IO_FILE *__new_freopen __P ((const char *, const char *, _IO_FILE *)); +_IO_FILE *__old_freopen __P ((const char *, const char *, _IO_FILE *)); + +/* Prototype for functions with alternative entry point. */ +extern void _IO_setbuffer_internal __P((_IO_FILE *, char*, _IO_size_t)); +extern _IO_size_t _IO_fread_internal __P((void*, _IO_size_t, _IO_size_t, + _IO_FILE*)); +extern _IO_FILE *_IO_fdopen_internal __P((int, const char*)); +extern int _IO_vsprintf_internal __P((char*, const char*, _IO_va_list)); +extern int _IO_fflush_internal __P((_IO_FILE*)); +extern _IO_size_t _IO_fwrite_internal __P((const void*, _IO_size_t, + _IO_size_t, _IO_FILE*)); +extern long int _IO_ftell_internal __P((_IO_FILE*)); +extern int _IO_fputs_internal __P((const char*, _IO_FILE*)); +extern int _IO_setvbuf_internal __P((_IO_FILE*, char*, int, _IO_size_t)); + +#ifdef __cplusplus +} +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/iopadn.c b/src/kernel/libroot/posix/glibc/libio/iopadn.c new file mode 100644 index 0000000000..b957394356 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iopadn.c @@ -0,0 +1,73 @@ +/* Copyright (C) 1993, 1997, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" + +#define PADSIZE 16 +static char const blanks[PADSIZE] = +{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; +static char const zeroes[PADSIZE] = +{'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; + +_IO_ssize_t +_IO_padn (fp, pad, count) + _IO_FILE *fp; + int pad; + _IO_ssize_t count; +{ + char padbuf[PADSIZE]; + const char *padptr; + int i; + _IO_size_t written = 0; + _IO_size_t w; + + if (pad == ' ') + padptr = blanks; + else if (pad == '0') + padptr = zeroes; + else + { + for (i = PADSIZE; --i >= 0; ) + padbuf[i] = pad; + padptr = padbuf; + } + for (i = count; i >= PADSIZE; i -= PADSIZE) + { + w = _IO_sputn (fp, padptr, PADSIZE); + written += w; + if (w != PADSIZE) + return written; + } + + if (i > 0) + { + w = _IO_sputn (fp, padptr, i); + written += w; + } + return written; +} +INTDEF(_IO_padn) diff --git a/src/kernel/libroot/posix/glibc/libio/iopopen.c b/src/kernel/libroot/posix/glibc/libio/iopopen.c new file mode 100644 index 0000000000..80a97f1b64 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iopopen.c @@ -0,0 +1,338 @@ +/* Copyright (C) 1993, 1997-2002, 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Per Bothner . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#ifndef _POSIX_SOURCE +# define _POSIX_SOURCE +#endif +#include "libioP.h" +#if _IO_HAVE_SYS_WAIT +#include +#include +#ifdef __STDC__ +#include +#endif +#ifdef _LIBC +# include +# include +#endif +#include +#include + +#ifndef _IO_fork +#ifdef _LIBC +#define _IO_fork __vfork +#else +#define _IO_fork vfork /* defined in libiberty, if needed */ +#endif +extern _IO_pid_t _IO_fork __P ((void)); +#endif + +#endif /* _IO_HAVE_SYS_WAIT */ + +#ifndef _IO_pipe +#ifdef _LIBC +#define _IO_pipe __pipe +#else +#define _IO_pipe pipe +#endif +extern int _IO_pipe __P ((int des[2])); +#endif + +#ifndef _IO_dup2 +#ifdef _LIBC +#define _IO_dup2 __dup2 +#else +#define _IO_dup2 dup2 +#endif +extern int _IO_dup2 __P ((int fd, int fd2)); +#endif + +#ifndef _IO_waitpid +#ifdef _LIBC +#define _IO_waitpid __waitpid +#else +#define _IO_waitpid waitpid +#endif +#endif + +#ifndef _IO_execl +#define _IO_execl execl +#endif +#ifndef _IO__exit +#define _IO__exit _exit +#endif + +#ifndef _IO_close +#ifdef _LIBC +#define _IO_close __close +#else +#define _IO_close close +#endif +#endif + +struct _IO_proc_file +{ + struct _IO_FILE_plus file; + /* Following fields must match those in class procbuf (procbuf.h) */ + _IO_pid_t pid; + struct _IO_proc_file *next; +}; +typedef struct _IO_proc_file _IO_proc_file; + +static struct _IO_jump_t _IO_proc_jumps; +static struct _IO_jump_t _IO_wproc_jumps; + +static struct _IO_proc_file *proc_file_chain; + +#ifdef _IO_MTSAFE_IO +static _IO_lock_t proc_file_chain_lock = _IO_lock_initializer; + +static void +unlock (void *not_used) +{ + _IO_lock_unlock (proc_file_chain_lock); +} +#endif + +_IO_FILE * +_IO_new_proc_open (fp, command, mode) + _IO_FILE *fp; + const char *command; + const char *mode; +{ +#if _IO_HAVE_SYS_WAIT + volatile int read_or_write; + volatile int parent_end, child_end; + int pipe_fds[2]; + _IO_pid_t child_pid; + if (_IO_file_is_open (fp)) + return NULL; + if (_IO_pipe (pipe_fds) < 0) + return NULL; + if (mode[0] == 'r' && mode[1] == '\0') + { + parent_end = pipe_fds[0]; + child_end = pipe_fds[1]; + read_or_write = _IO_NO_WRITES; + } + else if (mode[0] == 'w' && mode[1] == '\0') + { + parent_end = pipe_fds[1]; + child_end = pipe_fds[0]; + read_or_write = _IO_NO_READS; + } + else + { + _IO_close (pipe_fds[0]); + _IO_close (pipe_fds[1]); + __set_errno (EINVAL); + return NULL; + } + ((_IO_proc_file *) fp)->pid = child_pid = _IO_fork (); + if (child_pid == 0) + { + int child_std_end = mode[0] == 'r' ? 1 : 0; + struct _IO_proc_file *p; + + _IO_close (parent_end); + if (child_end != child_std_end) + { + _IO_dup2 (child_end, child_std_end); + _IO_close (child_end); + } + /* POSIX.2: "popen() shall ensure that any streams from previous + popen() calls that remain open in the parent process are closed + in the new child process." */ + for (p = proc_file_chain; p; p = p->next) + _IO_close (_IO_fileno ((_IO_FILE *) p)); + + _IO_execl ("/bin/sh", "sh", "-c", command, (char *) 0); + _IO__exit (127); + } + _IO_close (child_end); + if (child_pid < 0) + { + _IO_close (parent_end); + return NULL; + } + _IO_fileno (fp) = parent_end; + + /* Link into proc_file_chain. */ +#ifdef _IO_MTSAFE_IO + _IO_cleanup_region_start_noarg (unlock); + _IO_lock_lock (proc_file_chain_lock); +#endif + ((_IO_proc_file *) fp)->next = proc_file_chain; + proc_file_chain = (_IO_proc_file *) fp; +#ifdef _IO_MTSAFE_IO + _IO_lock_unlock (proc_file_chain_lock); + _IO_cleanup_region_end (0); +#endif + + _IO_mask_flags (fp, read_or_write, _IO_NO_READS|_IO_NO_WRITES); + return fp; +#else /* !_IO_HAVE_SYS_WAIT */ + return NULL; +#endif +} + +_IO_FILE * +_IO_new_popen (command, mode) + const char *command; + const char *mode; +{ + struct locked_FILE + { + struct _IO_proc_file fpx; +#ifdef _IO_MTSAFE_IO + _IO_lock_t lock; +#endif + struct _IO_wide_data wd; + } *new_f; + _IO_FILE *fp; + + new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); + if (new_f == NULL) + return NULL; +#ifdef _IO_MTSAFE_IO + new_f->fpx.file.file._lock = &new_f->lock; +#endif + fp = &new_f->fpx.file.file; + _IO_no_init (fp, 0, 0, &new_f->wd, &_IO_wproc_jumps); + _IO_JUMPS (&new_f->fpx.file) = &_IO_proc_jumps; + _IO_new_file_init (&new_f->fpx.file); +#if !_IO_UNIFIED_JUMPTABLES + new_f->fpx.file.vtable = NULL; +#endif + if (_IO_new_proc_open (fp, command, mode) != NULL) + return (_IO_FILE *) &new_f->fpx.file; + INTUSE(_IO_un_link) (&new_f->fpx.file); + free (new_f); + return NULL; +} + +int +_IO_new_proc_close (fp) + _IO_FILE *fp; +{ + /* This is not name-space clean. FIXME! */ +#if _IO_HAVE_SYS_WAIT + int wstatus; + _IO_proc_file **ptr = &proc_file_chain; + _IO_pid_t wait_pid; + int status = -1; + + /* Unlink from proc_file_chain. */ +#ifdef _IO_MTSAFE_IO + _IO_cleanup_region_start_noarg (unlock); + _IO_lock_lock (proc_file_chain_lock); +#endif + for ( ; *ptr != NULL; ptr = &(*ptr)->next) + { + if (*ptr == (_IO_proc_file *) fp) + { + *ptr = (*ptr)->next; + status = 0; + break; + } + } +#ifdef _IO_MTSAFE_IO + _IO_lock_unlock (proc_file_chain_lock); + _IO_cleanup_region_end (0); +#endif + + if (status < 0 || _IO_close (_IO_fileno(fp)) < 0) + return -1; + /* POSIX.2 Rationale: "Some historical implementations either block + or ignore the signals SIGINT, SIGQUIT, and SIGHUP while waiting + for the child process to terminate. Since this behavior is not + described in POSIX.2, such implementations are not conforming." */ + do + { + wait_pid = _IO_waitpid (((_IO_proc_file *) fp)->pid, &wstatus, 0); + } + while (wait_pid == -1 && errno == EINTR); + if (wait_pid == -1) + return -1; + return wstatus; +#else /* !_IO_HAVE_SYS_WAIT */ + return -1; +#endif +} + +static struct _IO_jump_t _IO_proc_jumps = { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_new_file_finish), + JUMP_INIT(overflow, _IO_new_file_overflow), + JUMP_INIT(underflow, _IO_new_file_underflow), + JUMP_INIT(uflow, INTUSE(_IO_default_uflow)), + JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)), + JUMP_INIT(xsputn, _IO_new_file_xsputn), + JUMP_INIT(xsgetn, INTUSE(_IO_default_xsgetn)), + JUMP_INIT(seekoff, _IO_new_file_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_new_file_setbuf), + JUMP_INIT(sync, _IO_new_file_sync), + JUMP_INIT(doallocate, INTUSE(_IO_file_doallocate)), + JUMP_INIT(read, INTUSE(_IO_file_read)), + JUMP_INIT(write, _IO_new_file_write), + JUMP_INIT(seek, INTUSE(_IO_file_seek)), + JUMP_INIT(close, _IO_new_proc_close), + JUMP_INIT(stat, INTUSE(_IO_file_stat)), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; + +static struct _IO_jump_t _IO_wproc_jumps = { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_new_file_finish), + JUMP_INIT(overflow, _IO_new_file_overflow), + JUMP_INIT(underflow, _IO_new_file_underflow), + JUMP_INIT(uflow, INTUSE(_IO_default_uflow)), + JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)), + JUMP_INIT(xsputn, _IO_new_file_xsputn), + JUMP_INIT(xsgetn, INTUSE(_IO_default_xsgetn)), + JUMP_INIT(seekoff, _IO_new_file_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_new_file_setbuf), + JUMP_INIT(sync, _IO_new_file_sync), + JUMP_INIT(doallocate, INTUSE(_IO_file_doallocate)), + JUMP_INIT(read, INTUSE(_IO_file_read)), + JUMP_INIT(write, _IO_new_file_write), + JUMP_INIT(seek, INTUSE(_IO_file_seek)), + JUMP_INIT(close, _IO_new_proc_close), + JUMP_INIT(stat, INTUSE(_IO_file_stat)), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; + +strong_alias (_IO_new_popen, __new_popen) +versioned_symbol (libc, _IO_new_popen, _IO_popen, GLIBC_2_1); +versioned_symbol (libc, __new_popen, popen, GLIBC_2_1); +versioned_symbol (libc, _IO_new_proc_open, _IO_proc_open, GLIBC_2_1); +versioned_symbol (libc, _IO_new_proc_close, _IO_proc_close, GLIBC_2_1); diff --git a/src/kernel/libroot/posix/glibc/libio/ioputs.c b/src/kernel/libroot/posix/glibc/libio/ioputs.c new file mode 100644 index 0000000000..8a9a595f90 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/ioputs.c @@ -0,0 +1,53 @@ +/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +int +_IO_puts (str) + const char *str; +{ + int result = EOF; + _IO_size_t len = strlen (str); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _IO_stdout); + _IO_flockfile (_IO_stdout); + + if ((_IO_stdout->_vtable_offset != 0 || _IO_fwide (_IO_stdout, -1) == -1) + && _IO_sputn (_IO_stdout, str, len) == len + && _IO_putc_unlocked ('\n', _IO_stdout) != EOF) + result = len + 1; + + _IO_funlockfile (_IO_stdout); + _IO_cleanup_region_end (0); + return result; +} + +#ifdef weak_alias +weak_alias (_IO_puts, puts) +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/ioseekoff.c b/src/kernel/libroot/posix/glibc/libio/ioseekoff.c new file mode 100644 index 0000000000..fe3f57e74e --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/ioseekoff.c @@ -0,0 +1,91 @@ +/* Copyright (C) 1993,1997,1998,1999,2001,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include +#include +#include +#ifndef errno +extern int errno; +#endif +#ifndef __set_errno +# define __set_errno(Val) errno = (Val) +#endif + +_IO_off64_t +_IO_seekoff_unlocked (fp, offset, dir, mode) + _IO_FILE *fp; + _IO_off64_t offset; + int dir; + int mode; +{ + if (dir != _IO_seek_cur && dir != _IO_seek_set && dir != _IO_seek_end) + { + __set_errno (EINVAL); + return EOF; + } + + /* If we have a backup buffer, get rid of it, since the __seekoff + callback may not know to do the right thing about it. + This may be over-kill, but it'll do for now. TODO */ + if (mode != 0 && ((_IO_fwide (fp, 0) < 0 && _IO_have_backup (fp)) + || (_IO_fwide (fp, 0) > 0 && _IO_have_wbackup (fp)))) + { + if (dir == _IO_seek_cur && _IO_in_backup (fp)) + { + if (fp->_vtable_offset != 0 || fp->_mode <= 0) + offset -= fp->_IO_read_end - fp->_IO_read_ptr; + else + abort (); + } + if (_IO_fwide (fp, 0) < 0) + INTUSE(_IO_free_backup_area) (fp); + else + INTUSE(_IO_free_wbackup_area) (fp); + } + + return _IO_SEEKOFF (fp, offset, dir, mode); +} + + +_IO_off64_t +_IO_seekoff (fp, offset, dir, mode) + _IO_FILE *fp; + _IO_off64_t offset; + int dir; + int mode; +{ + _IO_off64_t retval; + + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + + retval = _IO_seekoff_unlocked (fp, offset, dir, mode); + + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return retval; +} diff --git a/src/kernel/libroot/posix/glibc/libio/ioseekpos.c b/src/kernel/libroot/posix/glibc/libio/ioseekpos.c new file mode 100644 index 0000000000..37d32af340 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/ioseekpos.c @@ -0,0 +1,70 @@ +/* Copyright (C) 1993, 1997, 1998, 1999, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include + +_IO_off64_t +_IO_seekpos_unlocked (fp, pos, mode) + _IO_FILE *fp; + _IO_off64_t pos; + int mode; +{ + /* If we have a backup buffer, get rid of it, since the __seekoff + callback may not know to do the right thing about it. + This may be over-kill, but it'll do for now. TODO */ + if (_IO_fwide (fp, 0) <= 0) + { + if (_IO_have_backup (fp)) + INTUSE(_IO_free_backup_area) (fp); + } + else + { + if (_IO_have_wbackup (fp)) + INTUSE(_IO_free_wbackup_area) (fp); + } + + return _IO_SEEKPOS (fp, pos, mode); +} + + +_IO_off64_t +_IO_seekpos (fp, pos, mode) + _IO_FILE *fp; + _IO_off64_t pos; + int mode; +{ + _IO_off64_t retval; + + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + + retval = _IO_seekpos_unlocked (fp, pos, mode); + + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return retval; +} diff --git a/src/kernel/libroot/posix/glibc/libio/iosetbuffer.c b/src/kernel/libroot/posix/glibc/libio/iosetbuffer.c new file mode 100644 index 0000000000..785fcab4bd --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iosetbuffer.c @@ -0,0 +1,53 @@ +/* Copyright (C) 1993,95,96,97,98,99,2000,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" + +void +_IO_setbuffer (fp, buf, size) + _IO_FILE *fp; + char *buf; + _IO_size_t size; +{ + CHECK_FILE (fp, ); + _IO_cleanup_region_start ((void (*) (void *)) _IO_funlockfile, fp); + _IO_flockfile (fp); + fp->_flags &= ~_IO_LINE_BUF; + if (!buf) + size = 0; + (void) _IO_SETBUF (fp, buf, size); + if (fp->_vtable_offset == 0 && fp->_mode == 0 && _IO_CHECK_WIDE (fp)) + /* We also have to set the buffer using the wide char function. */ + (void) _IO_WSETBUF (fp, buf, size); + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); +} +INTDEF(_IO_setbuffer) + +#ifdef weak_alias +weak_alias (_IO_setbuffer, setbuffer) +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/iosetvbuf.c b/src/kernel/libroot/posix/glibc/libio/iosetvbuf.c new file mode 100644 index 0000000000..06d9f73fc4 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iosetvbuf.c @@ -0,0 +1,107 @@ +/* Copyright (C) 1993,96,97,98,99,2000,2001,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" + +#define _IOFBF 0 /* Fully buffered. */ +#define _IOLBF 1 /* Line buffered. */ +#define _IONBF 2 /* No buffering. */ + +int +_IO_setvbuf (fp, buf, mode, size) + _IO_FILE *fp; + char *buf; + int mode; + _IO_size_t size; +{ + int result; + CHECK_FILE (fp, EOF); + _IO_cleanup_region_start ((void (*) (void *)) _IO_funlockfile, fp); + _IO_flockfile (fp); + switch (mode) + { + case _IOFBF: + fp->_IO_file_flags &= ~_IO_LINE_BUF|_IO_UNBUFFERED; + if (buf == NULL) + { + if (fp->_IO_buf_base == NULL) + { + /* There is no flag to distinguish between "fully buffered + mode has been explicitly set" as opposed to "line + buffering has not been explicitly set". In both + cases, _IO_LINE_BUF is off. If this is a tty, and + _IO_filedoalloc later gets called, it cannot know if + it should set the _IO_LINE_BUF flag (because that is + the default), or not (because we have explicitly asked + for fully buffered mode). So we make sure a buffer + gets allocated now, and explicitly turn off line + buffering. + + A possibly cleaner alternative would be to add an + extra flag, but then flags are a finite resource. */ + if (_IO_DOALLOCATE (fp) < 0) + { + result = EOF; + goto unlock_return; + } + fp->_IO_file_flags &= ~_IO_LINE_BUF; + } + result = 0; + goto unlock_return; + } + break; + case _IOLBF: + fp->_IO_file_flags &= ~_IO_UNBUFFERED; + fp->_IO_file_flags |= _IO_LINE_BUF; + if (buf == NULL) + { + result = 0; + goto unlock_return; + } + break; + case _IONBF: + fp->_IO_file_flags &= ~_IO_LINE_BUF; + fp->_IO_file_flags |= _IO_UNBUFFERED; + buf = NULL; + size = 0; + break; + default: + result = EOF; + goto unlock_return; + } + result = _IO_SETBUF (fp, buf, size) == NULL ? EOF : 0; + +unlock_return: + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} +INTDEF(_IO_setvbuf) + +#ifdef weak_alias +weak_alias (_IO_setvbuf, setvbuf) +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/ioungetc.c b/src/kernel/libroot/posix/glibc/libio/ioungetc.c new file mode 100644 index 0000000000..d32359bd40 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/ioungetc.c @@ -0,0 +1,49 @@ +/* Copyright (C) 1993,1996,1997,1998,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" + +int +_IO_ungetc (c, fp) + int c; + _IO_FILE *fp; +{ + int result; + CHECK_FILE (fp, EOF); + if (c == EOF) + return EOF; + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + result = INTUSE(_IO_sputbackc) (fp, (unsigned char) c); + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} + +#ifdef weak_alias +weak_alias (_IO_ungetc, ungetc) +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/ioungetwc.c b/src/kernel/libroot/posix/glibc/libio/ioungetwc.c new file mode 100644 index 0000000000..1bff41256c --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/ioungetwc.c @@ -0,0 +1,48 @@ +/* Copyright (C) 1993, 1996-1999, 2001, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +wint_t +ungetwc (c, fp) + wint_t c; + _IO_FILE *fp; +{ + int result; + CHECK_FILE (fp, WEOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + _IO_fwide (fp, 1); + if (c == WEOF) + result = WEOF; + else + result = INTUSE(_IO_sputbackwc) (fp, c); + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} diff --git a/src/kernel/libroot/posix/glibc/libio/iovdprintf.c b/src/kernel/libroot/posix/glibc/libio/iovdprintf.c new file mode 100644 index 0000000000..33fac6d8bd --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iovdprintf.c @@ -0,0 +1,69 @@ +/* Copyright (C) 1995, 1997-2000, 2001, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +int +_IO_vdprintf (d, format, arg) + int d; + const char *format; + _IO_va_list arg; +{ + struct _IO_FILE_plus tmpfil; + struct _IO_wide_data wd; + int done; + +#ifdef _IO_MTSAFE_IO + tmpfil.file._lock = NULL; +#endif + _IO_no_init (&tmpfil.file, _IO_USER_LOCK, 0, &wd, &INTUSE(_IO_wfile_jumps)); + _IO_JUMPS (&tmpfil) = &INTUSE(_IO_file_jumps); + INTUSE(_IO_file_init) (&tmpfil); +#if !_IO_UNIFIED_JUMPTABLES + tmpfil.vtable = NULL; +#endif + if (INTUSE(_IO_file_attach) (&tmpfil.file, d) == NULL) + { + INTUSE(_IO_un_link) (&tmpfil); + return EOF; + } + tmpfil.file._IO_file_flags = + (_IO_mask_flags (&tmpfil.file, _IO_NO_READS, + _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING) + | _IO_DELETE_DONT_CLOSE); + + done = INTUSE(_IO_vfprintf) (&tmpfil.file, format, arg); + + _IO_FINISH (&tmpfil.file); + + return done; +} + +#ifdef weak_alias +weak_alias (_IO_vdprintf, vdprintf) +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/iovsprintf.c b/src/kernel/libroot/posix/glibc/libio/iovsprintf.c new file mode 100644 index 0000000000..dbaa53f7c8 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iovsprintf.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1993, 1997-2000, 2001, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "strfile.h" + +int +_IO_vsprintf (string, format, args) + char *string; + const char *format; + _IO_va_list args; +{ + _IO_strfile sf; + int ret; + +#ifdef _IO_MTSAFE_IO + sf._sbf._f._lock = NULL; +#endif + _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, -1, NULL, NULL); + _IO_JUMPS ((struct _IO_FILE_plus *) &sf._sbf) = &_IO_str_jumps; + INTUSE(_IO_str_init_static) (&sf, string, -1, string); + ret = INTUSE(_IO_vfprintf) ((_IO_FILE *) &sf._sbf, format, args); + _IO_putc_unlocked ('\0', (_IO_FILE *) &sf._sbf); + return ret; +} +INTDEF(_IO_vsprintf) + +#ifdef weak_alias +weak_alias (_IO_vsprintf, vsprintf) +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/iovsscanf.c b/src/kernel/libroot/posix/glibc/libio/iovsscanf.c new file mode 100644 index 0000000000..1bb475549c --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iovsscanf.c @@ -0,0 +1,52 @@ +/* Copyright (C) 1993, 1997-2000, 2001, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "strfile.h" + +int +_IO_vsscanf (string, format, args) + const char *string; + const char *format; + _IO_va_list args; +{ + int ret; + _IO_strfile sf; +#ifdef _IO_MTSAFE_IO + sf._sbf._f._lock = NULL; +#endif + _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, -1, NULL, NULL); + _IO_JUMPS ((struct _IO_FILE_plus *) &sf._sbf) = &_IO_str_jumps; + INTUSE(_IO_str_init_static) (&sf, (char*)string, 0, NULL); + ret = INTUSE(_IO_vfscanf) ((_IO_FILE *) &sf._sbf, format, args, NULL); + return ret; +} + +#ifdef weak_alias +weak_alias (_IO_vsscanf, __vsscanf) +weak_alias (_IO_vsscanf, vsscanf) +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/iovswscanf.c b/src/kernel/libroot/posix/glibc/libio/iovswscanf.c new file mode 100644 index 0000000000..1bbddd442f --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iovswscanf.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1993, 1997-2000, 2001, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "strfile.h" +#include + +int +vswscanf (string, format, args) + const wchar_t *string; + const wchar_t *format; + _IO_va_list args; +{ + int ret; + _IO_strfile sf; + struct _IO_wide_data wd; +#ifdef _IO_MTSAFE_IO + sf._sbf._f._lock = NULL; +#endif + _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, 0, &wd, &_IO_wstr_jumps); + _IO_fwide (&sf._sbf._f, 1); + _IO_wstr_init_static (&sf._sbf._f, (wchar_t *)string, 0, NULL); + ret = _IO_vfwscanf ((_IO_FILE *) &sf._sbf, format, args, NULL); + return ret; +} +libc_hidden_def (vswscanf) diff --git a/src/kernel/libroot/posix/glibc/libio/iowpadn.c b/src/kernel/libroot/posix/glibc/libio/iowpadn.c new file mode 100644 index 0000000000..7bbb06192b --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/iowpadn.c @@ -0,0 +1,78 @@ +/* Copyright (C) 1993, 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" + +#define PADSIZE 16 +static wchar_t const blanks[PADSIZE] = +{ + L' ', L' ', L' ', L' ', L' ', L' ', L' ', L' ', + L' ', L' ', L' ', L' ', L' ', L' ', L' ', L' ' +}; +static wchar_t const zeroes[PADSIZE] = +{ + L'0', L'0', L'0', L'0', L'0', L'0', L'0', L'0', + L'0', L'0', L'0', L'0', L'0', L'0', L'0', L'0' +}; + +_IO_ssize_t +_IO_wpadn (fp, pad, count) + _IO_FILE *fp; + wint_t pad; + _IO_ssize_t count; +{ + wchar_t padbuf[PADSIZE]; + const wchar_t *padptr; + int i; + _IO_size_t written = 0; + _IO_size_t w; + + if (pad == L' ') + padptr = blanks; + else if (pad == L'0') + padptr = zeroes; + else + { + for (i = PADSIZE; --i >= 0; ) + padbuf[i] = pad; + padptr = padbuf; + } + for (i = count; i >= PADSIZE; i -= PADSIZE) + { + w = _IO_sputn (fp, (char *) padptr, PADSIZE); + written += w; + if (w != PADSIZE) + return written; + } + + if (i > 0) + { + w = _IO_sputn (fp, (char *) padptr, i); + written += w; + } + return written; +} diff --git a/src/kernel/libroot/posix/glibc/libio/libio.h b/src/kernel/libroot/posix/glibc/libio/libio.h new file mode 100644 index 0000000000..65cfd1f5fb --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/libio.h @@ -0,0 +1,522 @@ +/* Copyright (C) 1991-1995, 1997-2001, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Per Bothner . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#ifndef _IO_STDIO_H +#define _IO_STDIO_H + +#include <_G_config.h> +/* ALL of these should be defined in _G_config.h */ +#define _IO_pos_t _G_fpos_t /* obsolete */ +#define _IO_fpos_t _G_fpos_t +#define _IO_fpos64_t _G_fpos64_t +#define _IO_size_t _G_size_t +#define _IO_ssize_t _G_ssize_t +#define _IO_off_t _G_off_t +#define _IO_off64_t _G_off64_t +#define _IO_pid_t _G_pid_t +#define _IO_uid_t _G_uid_t +#define _IO_iconv_t _G_iconv_t +#define _IO_HAVE_SYS_WAIT _G_HAVE_SYS_WAIT +#define _IO_HAVE_ST_BLKSIZE _G_HAVE_ST_BLKSIZE +#define _IO_BUFSIZ _G_BUFSIZ +#define _IO_va_list _G_va_list +#define _IO_wint_t _G_wint_t + +#ifdef _G_NEED_STDARG_H +/* This define avoids name pollution if we're using GNU stdarg.h */ +# define __need___va_list +# include +# ifdef __GNUC_VA_LIST +# undef _IO_va_list +# define _IO_va_list __gnuc_va_list +# endif /* __GNUC_VA_LIST */ +#endif + +#ifndef __P +# if _G_HAVE_SYS_CDEFS +# include +# else +# ifdef __STDC__ +# define __P(p) p +# define __PMT(p) p +# else +# define __P(p) () +# define __PMT(p) () +# endif +# endif +#endif /*!__P*/ + +/* For backward compatibility */ +#ifndef _PARAMS +# define _PARAMS(protos) __P(protos) +#endif /*!_PARAMS*/ + +#ifndef __STDC__ +# ifndef const +# define const +# endif +#endif +#define _IO_UNIFIED_JUMPTABLES 1 +#ifndef _G_HAVE_PRINTF_FP +# define _IO_USE_DTOA 1 +#endif + +#ifndef EOF +# define EOF (-1) +#endif +#ifndef NULL +# if defined __GNUG__ && \ + (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)) +# define NULL (__null) +# else +# if !defined(__cplusplus) +# define NULL ((void*)0) +# else +# define NULL (0) +# endif +# endif +#endif + +#define _IOS_INPUT 1 +#define _IOS_OUTPUT 2 +#define _IOS_ATEND 4 +#define _IOS_APPEND 8 +#define _IOS_TRUNC 16 +#define _IOS_NOCREATE 32 +#define _IOS_NOREPLACE 64 +#define _IOS_BIN 128 + +/* Magic numbers and bits for the _flags field. + The magic numbers use the high-order bits of _flags; + the remaining bits are available for variable flags. + Note: The magic numbers must all be negative if stdio + emulation is desired. */ + +#define _IO_MAGIC 0xFBAD0000 /* Magic number */ +#define _OLD_STDIO_MAGIC 0xFABC0000 /* Emulate old stdio. */ +#define _IO_MAGIC_MASK 0xFFFF0000 +#define _IO_USER_BUF 1 /* User owns buffer; don't delete it on close. */ +#define _IO_UNBUFFERED 2 +#define _IO_NO_READS 4 /* Reading not allowed */ +#define _IO_NO_WRITES 8 /* Writing not allowd */ +#define _IO_EOF_SEEN 0x10 +#define _IO_ERR_SEEN 0x20 +#define _IO_DELETE_DONT_CLOSE 0x40 /* Don't call close(_fileno) on cleanup. */ +#define _IO_LINKED 0x80 /* Set if linked (using _chain) to streambuf::_list_all.*/ +#define _IO_IN_BACKUP 0x100 +#define _IO_LINE_BUF 0x200 +#define _IO_TIED_PUT_GET 0x400 /* Set if put and get pointer logicly tied. */ +#define _IO_CURRENTLY_PUTTING 0x800 +#define _IO_IS_APPENDING 0x1000 +#define _IO_IS_FILEBUF 0x2000 +#define _IO_BAD_SEEN 0x4000 +#define _IO_USER_LOCK 0x8000 + +#define _IO_FLAGS2_MMAP 1 + +/* These are "formatting flags" matching the iostream fmtflags enum values. */ +#define _IO_SKIPWS 01 +#define _IO_LEFT 02 +#define _IO_RIGHT 04 +#define _IO_INTERNAL 010 +#define _IO_DEC 020 +#define _IO_OCT 040 +#define _IO_HEX 0100 +#define _IO_SHOWBASE 0200 +#define _IO_SHOWPOINT 0400 +#define _IO_UPPERCASE 01000 +#define _IO_SHOWPOS 02000 +#define _IO_SCIENTIFIC 04000 +#define _IO_FIXED 010000 +#define _IO_UNITBUF 020000 +#define _IO_STDIO 040000 +#define _IO_DONT_CLOSE 0100000 +#define _IO_BOOLALPHA 0200000 + + +struct _IO_jump_t; struct _IO_FILE; + +/* Handle lock. */ +#ifdef _IO_MTSAFE_IO +# if defined __GLIBC__ && __GLIBC__ >= 2 +# include +# else +/*# include */ +# endif +#else +typedef void _IO_lock_t; +#endif + + +/* A streammarker remembers a position in a buffer. */ + +struct _IO_marker { + struct _IO_marker *_next; + struct _IO_FILE *_sbuf; + /* If _pos >= 0 + it points to _buf->Gbase()+_pos. FIXME comment */ + /* if _pos < 0, it points to _buf->eBptr()+_pos. FIXME comment */ + int _pos; +#if 0 + void set_streampos(streampos sp) { _spos = sp; } + void set_offset(int offset) { _pos = offset; _spos = (streampos)(-2); } + public: + streammarker(streambuf *sb); + ~streammarker(); + int saving() { return _spos == -2; } + int delta(streammarker&); + int delta(); +#endif +}; + +/* This is the structure from the libstdc++ codecvt class. */ +enum __codecvt_result +{ + __codecvt_ok, + __codecvt_partial, + __codecvt_error, + __codecvt_noconv +}; + +#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T +/* The order of the elements in the following struct must match the order + of the virtual functions in the libstdc++ codecvt class. */ +struct _IO_codecvt +{ + void (*__codecvt_destr) (struct _IO_codecvt *); + enum __codecvt_result (*__codecvt_do_out) (struct _IO_codecvt *, + __mbstate_t *, + const wchar_t *, + const wchar_t *, + const wchar_t **, char *, + char *, char **); + enum __codecvt_result (*__codecvt_do_unshift) (struct _IO_codecvt *, + __mbstate_t *, char *, + char *, char **); + enum __codecvt_result (*__codecvt_do_in) (struct _IO_codecvt *, + __mbstate_t *, + const char *, const char *, + const char **, wchar_t *, + wchar_t *, wchar_t **); + int (*__codecvt_do_encoding) (struct _IO_codecvt *); + int (*__codecvt_do_always_noconv) (struct _IO_codecvt *); + int (*__codecvt_do_length) (struct _IO_codecvt *, __mbstate_t *, + const char *, const char *, _IO_size_t); + int (*__codecvt_do_max_length) (struct _IO_codecvt *); + + _IO_iconv_t __cd_in; + _IO_iconv_t __cd_out; +}; + +/* Extra data for wide character streams. */ +struct _IO_wide_data +{ + wchar_t *_IO_read_ptr; /* Current read pointer */ + wchar_t *_IO_read_end; /* End of get area. */ + wchar_t *_IO_read_base; /* Start of putback+get area. */ + wchar_t *_IO_write_base; /* Start of put area. */ + wchar_t *_IO_write_ptr; /* Current put pointer. */ + wchar_t *_IO_write_end; /* End of put area. */ + wchar_t *_IO_buf_base; /* Start of reserve area. */ + wchar_t *_IO_buf_end; /* End of reserve area. */ + /* The following fields are used to support backing up and undo. */ + wchar_t *_IO_save_base; /* Pointer to start of non-current get area. */ + wchar_t *_IO_backup_base; /* Pointer to first valid character of + backup area */ + wchar_t *_IO_save_end; /* Pointer to end of non-current get area. */ + + __mbstate_t _IO_state; + __mbstate_t _IO_last_state; + struct _IO_codecvt _codecvt; + + wchar_t _shortbuf[1]; + + struct _IO_jump_t *_wide_vtable; +}; +#endif + +struct _IO_FILE { + int _flags; /* High-order word is _IO_MAGIC; rest is flags. */ +#define _IO_file_flags _flags + + /* The following pointers correspond to the C++ streambuf protocol. */ + /* Note: Tk uses the _IO_read_ptr and _IO_read_end fields directly. */ + char* _IO_read_ptr; /* Current read pointer */ + char* _IO_read_end; /* End of get area. */ + char* _IO_read_base; /* Start of putback+get area. */ + char* _IO_write_base; /* Start of put area. */ + char* _IO_write_ptr; /* Current put pointer. */ + char* _IO_write_end; /* End of put area. */ + char* _IO_buf_base; /* Start of reserve area. */ + char* _IO_buf_end; /* End of reserve area. */ + /* The following fields are used to support backing up and undo. */ + char *_IO_save_base; /* Pointer to start of non-current get area. */ + char *_IO_backup_base; /* Pointer to first valid character of backup area */ + char *_IO_save_end; /* Pointer to end of non-current get area. */ + + struct _IO_marker *_markers; + + struct _IO_FILE *_chain; + + int _fileno; +#if 0 + int _blksize; +#else + int _flags2; +#endif + _IO_off_t _old_offset; /* This used to be _offset but it's too small. */ + +#define __HAVE_COLUMN /* temporary */ + /* 1+column number of pbase(); 0 is unknown. */ + unsigned short _cur_column; + signed char _vtable_offset; + char _shortbuf[1]; + + /* char* _save_gptr; char* _save_egptr; */ + + _IO_lock_t *_lock; +#ifdef _IO_USE_OLD_IO_FILE +}; + +struct _IO_FILE_complete +{ + struct _IO_FILE _file; +#endif +#if defined _G_IO_IO_FILE_VERSION && _G_IO_IO_FILE_VERSION == 0x20001 + _IO_off64_t _offset; +# if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T + /* Wide character stream stuff. */ + struct _IO_codecvt *_codecvt; + struct _IO_wide_data *_wide_data; +# else + void *__pad1; + void *__pad2; +# endif + int _mode; + /* Make sure we don't get into trouble again. */ + char _unused2[15 * sizeof (int) - 2 * sizeof (void *)]; +#endif +}; + +#ifndef __cplusplus +typedef struct _IO_FILE _IO_FILE; +#endif + +struct _IO_FILE_plus; + +extern struct _IO_FILE_plus _IO_2_1_stdin_; +extern struct _IO_FILE_plus _IO_2_1_stdout_; +extern struct _IO_FILE_plus _IO_2_1_stderr_; +#ifndef _LIBC +#define _IO_stdin ((_IO_FILE*)(&_IO_2_1_stdin_)) +#define _IO_stdout ((_IO_FILE*)(&_IO_2_1_stdout_)) +#define _IO_stderr ((_IO_FILE*)(&_IO_2_1_stderr_)) +#else +extern _IO_FILE *_IO_stdin attribute_hidden; +extern _IO_FILE *_IO_stdout attribute_hidden; +extern _IO_FILE *_IO_stderr attribute_hidden; +#endif + +/* Functions to do I/O and file management for a stream. */ + +/* Read NBYTES bytes from COOKIE into a buffer pointed to by BUF. + Return number of bytes read. */ +typedef __ssize_t __io_read_fn (void *__cookie, char *__buf, size_t __nbytes); + +/* Write N bytes pointed to by BUF to COOKIE. Write all N bytes + unless there is an error. Return number of bytes written, or -1 if + there is an error without writing anything. If the file has been + opened for append (__mode.__append set), then set the file pointer + to the end of the file and then do the write; if not, just write at + the current file pointer. */ +typedef __ssize_t __io_write_fn (void *__cookie, __const char *__buf, + size_t __n); + +/* Move COOKIE's file position to *POS bytes from the + beginning of the file (if W is SEEK_SET), + the current position (if W is SEEK_CUR), + or the end of the file (if W is SEEK_END). + Set *POS to the new file position. + Returns zero if successful, nonzero if not. */ +typedef int __io_seek_fn (void *__cookie, _IO_off64_t *__pos, int __w); + +/* Close COOKIE. */ +typedef int __io_close_fn (void *__cookie); + + +#ifdef _GNU_SOURCE +/* User-visible names for the above. */ +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; + +/* The structure with the cookie function pointers. */ +typedef struct +{ + __io_read_fn *read; /* Read bytes. */ + __io_write_fn *write; /* Write bytes. */ + __io_seek_fn *seek; /* Seek/tell file position. */ + __io_close_fn *close; /* Close file. */ +} _IO_cookie_io_functions_t; +typedef _IO_cookie_io_functions_t cookie_io_functions_t; + +struct _IO_cookie_file; + +/* Initialize one of those. */ +extern void _IO_cookie_init (struct _IO_cookie_file *__cfile, int __read_write, + void *__cookie, _IO_cookie_io_functions_t __fns); +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +extern int __underflow (_IO_FILE *) __THROW; +extern int __uflow (_IO_FILE *) __THROW; +extern int __overflow (_IO_FILE *, int) __THROW; +extern _IO_wint_t __wunderflow (_IO_FILE *) __THROW; +extern _IO_wint_t __wuflow (_IO_FILE *) __THROW; +extern _IO_wint_t __woverflow (_IO_FILE *, _IO_wint_t) __THROW; + +#define _IO_getc_unlocked(_fp) \ + ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end ? __uflow (_fp) \ + : *(unsigned char *) (_fp)->_IO_read_ptr++) +#define _IO_peekc_unlocked(_fp) \ + ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end \ + && __underflow (_fp) == EOF ? EOF \ + : *(unsigned char *) (_fp)->_IO_read_ptr) +#define _IO_putc_unlocked(_ch, _fp) \ + (((_fp)->_IO_write_ptr >= (_fp)->_IO_write_end) \ + ? __overflow (_fp, (unsigned char) (_ch)) \ + : (unsigned char) (*(_fp)->_IO_write_ptr++ = (_ch))) + +#define _IO_getwc_unlocked(_fp) \ + ((_fp)->_wide_data->_IO_read_ptr >= (_fp)->_wide_data->_IO_read_end \ + ? __wuflow (_fp) : (_IO_wint_t) *(_fp)->_wide_data->_IO_read_ptr++) +#define _IO_putwc_unlocked(_wch, _fp) \ + ((_fp)->_wide_data->_IO_write_ptr >= (_fp)->_wide_data->_IO_write_end \ + ? __woverflow (_fp, _wch) \ + : (_IO_wint_t) (*(_fp)->_wide_data->_IO_write_ptr++ = (_wch))) + +#define _IO_feof_unlocked(__fp) (((__fp)->_flags & _IO_EOF_SEEN) != 0) +#define _IO_ferror_unlocked(__fp) (((__fp)->_flags & _IO_ERR_SEEN) != 0) + +extern int _IO_getc (_IO_FILE *__fp) __THROW; +extern int _IO_putc (int __c, _IO_FILE *__fp) __THROW; +extern int _IO_feof (_IO_FILE *__fp) __THROW; +extern int _IO_ferror (_IO_FILE *__fp) __THROW; + +extern int _IO_peekc_locked (_IO_FILE *__fp) __THROW; + +/* This one is for Emacs. */ +#define _IO_PENDING_OUTPUT_COUNT(_fp) \ + ((_fp)->_IO_write_ptr - (_fp)->_IO_write_base) + +extern void _IO_flockfile (_IO_FILE *) __THROW; +extern void _IO_funlockfile (_IO_FILE *) __THROW; +extern int _IO_ftrylockfile (_IO_FILE *) __THROW; + +#ifdef _IO_MTSAFE_IO +# define _IO_peekc(_fp) _IO_peekc_locked (_fp) +# define _IO_flockfile(_fp) \ + if (((_fp)->_flags & _IO_USER_LOCK) == 0) _IO_flockfile (_fp) +# define _IO_funlockfile(_fp) \ + if (((_fp)->_flags & _IO_USER_LOCK) == 0) _IO_funlockfile (_fp) +#else +# define _IO_peekc(_fp) _IO_peekc_unlocked (_fp) +# define _IO_flockfile(_fp) /**/ +# define _IO_funlockfile(_fp) /**/ +# define _IO_ftrylockfile(_fp) /**/ +# define _IO_cleanup_region_start(_fct, _fp) /**/ +# define _IO_cleanup_region_end(_Doit) /**/ +#endif /* !_IO_MTSAFE_IO */ + +extern int _IO_vfscanf (_IO_FILE * __restrict, const char * __restrict, + _IO_va_list, int *__restrict) __THROW; +extern int _IO_vfprintf (_IO_FILE *__restrict, const char *__restrict, + _IO_va_list) __THROW; +extern _IO_ssize_t _IO_padn (_IO_FILE *, int, _IO_ssize_t) __THROW; +extern _IO_size_t _IO_sgetn (_IO_FILE *, void *, _IO_size_t) __THROW; + +extern _IO_off64_t _IO_seekoff (_IO_FILE *, _IO_off64_t, int, int) __THROW; +extern _IO_off64_t _IO_seekpos (_IO_FILE *, _IO_off64_t, int) __THROW; + +extern void _IO_free_backup_area (_IO_FILE *) __THROW; + +#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T +extern _IO_wint_t _IO_getwc (_IO_FILE *__fp) __THROW; +extern _IO_wint_t _IO_putwc (wchar_t __wc, _IO_FILE *__fp) __THROW; +extern int _IO_fwide (_IO_FILE *__fp, int __mode) __THROW; +# if __GNUC__ >= 2 +/* While compiling glibc we have to handle compatibility with very old + versions. */ +# if defined _LIBC && defined SHARED +# include +# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) +# define _IO_fwide_maybe_incompatible \ + (__builtin_expect (&_IO_stdin_used == NULL, 0)) +extern const int _IO_stdin_used; +weak_extern (_IO_stdin_used); +# endif +# endif +# ifndef _IO_fwide_maybe_incompatible +# define _IO_fwide_maybe_incompatible (0) +# endif +/* A special optimized version of the function above. It optimizes the + case of initializing an unoriented byte stream. */ +# define _IO_fwide(__fp, __mode) \ + ({ int __result = (__mode); \ + if (__result < 0 && ! _IO_fwide_maybe_incompatible) \ + { \ + if ((__fp)->_mode == 0) \ + /* We know that all we have to do is to set the flag. */ \ + (__fp)->_mode = -1; \ + __result = (__fp)->_mode; \ + } \ + else if (__builtin_constant_p (__mode) && (__mode) == 0) \ + __result = (__fp)->_mode; \ + else \ + __result = _IO_fwide (__fp, __result); \ + __result; }) +# endif + +extern int _IO_vfwscanf (_IO_FILE * __restrict, const wchar_t * __restrict, + _IO_va_list, int *__restrict) __THROW; +extern int _IO_vfwprintf (_IO_FILE *__restrict, const wchar_t *__restrict, + _IO_va_list) __THROW; +extern _IO_ssize_t _IO_wpadn (_IO_FILE *, wint_t, _IO_ssize_t) __THROW; +extern void _IO_free_wbackup_area (_IO_FILE *) __THROW; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _IO_STDIO_H */ diff --git a/src/kernel/libroot/posix/glibc/libio/libioP.h b/src/kernel/libroot/posix/glibc/libio/libioP.h new file mode 100644 index 0000000000..64d3025345 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/libioP.h @@ -0,0 +1,973 @@ +/* Copyright (C) 1993, 1997-2002, 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#ifndef _LIBIO_P_H_ +#define _LIBIO_P_H_ + +#include +#ifndef __set_errno +# define __set_errno(Val) errno = (Val) +#endif +#if defined __GLIBC__ && __GLIBC__ >= 2 +# include +#else +/*# include */ +#endif + +#include "iolibio.h" + +/* Control of exported symbols. Used in glibc. By default we don't + do anything. */ +#ifndef INTUSE +# define INTUSE(name) name +#endif +#ifndef INTDEF +# define INTDEF(name) +#endif +#ifndef INTDEF2 +# define INTDEF2(name) +#endif +#ifndef libc_hidden_proto +# define libc_hidden_proto(name) +#endif +#ifndef libc_hidden_def +# define libc_hidden_def(name) +#endif +#ifndef libc_hidden_weak +# define libc_hidden_weak(name) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define _IO_seek_set 0 +#define _IO_seek_cur 1 +#define _IO_seek_end 2 + +/* THE JUMPTABLE FUNCTIONS. + + * The _IO_FILE type is used to implement the FILE type in GNU libc, + * as well as the streambuf class in GNU iostreams for C++. + * These are all the same, just used differently. + * An _IO_FILE (or FILE) object is allows followed by a pointer to + * a jump table (of pointers to functions). The pointer is accessed + * with the _IO_JUMPS macro. The jump table has a eccentric format, + * so as to be compatible with the layout of a C++ virtual function table. + * (as implemented by g++). When a pointer to a streambuf object is + * coerced to an (_IO_FILE*), then _IO_JUMPS on the result just + * happens to point to the virtual function table of the streambuf. + * Thus the _IO_JUMPS function table used for C stdio/libio does + * double duty as the virtual function table for C++ streambuf. + * + * The entries in the _IO_JUMPS function table (and hence also the + * virtual functions of a streambuf) are described below. + * The first parameter of each function entry is the _IO_FILE/streambuf + * object being acted on (i.e. the 'this' parameter). + */ + +#ifdef _LIBC +# include +# if !SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + /* Setting this macro disables the use of the _vtable_offset + bias in _IO_JUMPS_FUNCS, below. That is only needed if we + want to support old binaries (see oldfileops.c). */ +# define _G_IO_NO_BACKWARD_COMPAT 1 +# endif +#endif + +#if (!defined _IO_USE_OLD_IO_FILE \ + && (!defined _G_IO_NO_BACKWARD_COMPAT || _G_IO_NO_BACKWARD_COMPAT == 0)) +# define _IO_JUMPS_OFFSET 1 +#endif + +#define _IO_JUMPS(THIS) (THIS)->vtable +#define _IO_WIDE_JUMPS(THIS) ((struct _IO_FILE *) (THIS))->_wide_data->_wide_vtable +#define _IO_CHECK_WIDE(THIS) (((struct _IO_FILE *) (THIS))->_wide_data != NULL) + +#if _IO_JUMPS_OFFSET +# define _IO_JUMPS_FUNC(THIS) \ + (*(struct _IO_jump_t **) ((void *) &_IO_JUMPS ((struct _IO_FILE_plus *) (THIS)) \ + + (THIS)->_vtable_offset)) +#else +# define _IO_JUMPS_FUNC(THIS) _IO_JUMPS ((struct _IO_FILE_plus *) (THIS)) +#endif +#define _IO_WIDE_JUMPS_FUNC(THIS) _IO_WIDE_JUMPS(THIS) +#ifdef _G_USING_THUNKS +# define JUMP_FIELD(TYPE, NAME) TYPE NAME +# define JUMP0(FUNC, THIS) (_IO_JUMPS_FUNC(THIS)->FUNC) (THIS) +# define JUMP1(FUNC, THIS, X1) (_IO_JUMPS_FUNC(THIS)->FUNC) (THIS, X1) +# define JUMP2(FUNC, THIS, X1, X2) (_IO_JUMPS_FUNC(THIS)->FUNC) (THIS, X1, X2) +# define JUMP3(FUNC, THIS, X1,X2,X3) (_IO_JUMPS_FUNC(THIS)->FUNC) (THIS, X1,X2, X3) +# define JUMP_INIT(NAME, VALUE) VALUE +# define JUMP_INIT_DUMMY JUMP_INIT(dummy, 0), JUMP_INIT (dummy2, 0) + +# define WJUMP0(FUNC, THIS) (_IO_WIDE_JUMPS_FUNC(THIS)->FUNC) (THIS) +# define WJUMP1(FUNC, THIS, X1) (_IO_WIDE_JUMPS_FUNC(THIS)->FUNC) (THIS, X1) +# define WJUMP2(FUNC, THIS, X1, X2) (_IO_WIDE_JUMPS_FUNC(THIS)->FUNC) (THIS, X1, X2) +# define WJUMP3(FUNC, THIS, X1,X2,X3) (_IO_WIDE_JUMPS_FUNC(THIS)->FUNC) (THIS, X1,X2, X3) +#else +/* These macros will change when we re-implement vtables to use "thunks"! */ +# define JUMP_FIELD(TYPE, NAME) struct { short delta1, delta2; TYPE pfn; } NAME +# define JUMP0(FUNC, THIS) _IO_JUMPS_FUNC(THIS)->FUNC.pfn (THIS) +# define JUMP1(FUNC, THIS, X1) _IO_JUMPS_FUNC(THIS)->FUNC.pfn (THIS, X1) +# define JUMP2(FUNC, THIS, X1, X2) _IO_JUMPS_FUNC(THIS)->FUNC.pfn (THIS, X1, X2) +# define JUMP3(FUNC, THIS, X1,X2,X3) _IO_JUMPS_FUNC(THIS)->FUNC.pfn (THIS, X1,X2,X3) +# define JUMP_INIT(NAME, VALUE) {0, 0, VALUE} +# define JUMP_INIT_DUMMY JUMP_INIT(dummy, 0) + +# define WJUMP0(FUNC, THIS) _IO_WIDE_JUMPS_FUNC(THIS)->FUNC.pfn (THIS) +# define WJUMP1(FUNC, THIS, X1) _IO_WIDE_JUMPS_FUNC(THIS)->FUNC.pfn (THIS, X1) +# define WJUMP2(FUNC, THIS, X1, X2) _IO_WIDE_JUMPS_FUNC(THIS)->FUNC.pfn (THIS, X1, X2) +# define WJUMP3(FUNC, THIS, X1,X2,X3) _IO_WIDE_JUMPS_FUNC(THIS)->FUNC.pfn (THIS, X1,X2,X3) +#endif + +/* The 'finish' function does any final cleaning up of an _IO_FILE object. + It does not delete (free) it, but does everything else to finalize it. + It matches the streambuf::~streambuf virtual destructor. */ +typedef void (*_IO_finish_t) __PMT ((_IO_FILE *, int)); /* finalize */ +#define _IO_FINISH(FP) JUMP1 (__finish, FP, 0) +#define _IO_WFINISH(FP) WJUMP1 (__finish, FP, 0) + +/* The 'overflow' hook flushes the buffer. + The second argument is a character, or EOF. + It matches the streambuf::overflow virtual function. */ +typedef int (*_IO_overflow_t) __PMT ((_IO_FILE *, int)); +#define _IO_OVERFLOW(FP, CH) JUMP1 (__overflow, FP, CH) +#define _IO_WOVERFLOW(FP, CH) WJUMP1 (__overflow, FP, CH) + +/* The 'underflow' hook tries to fills the get buffer. + It returns the next character (as an unsigned char) or EOF. The next + character remains in the get buffer, and the get position is not changed. + It matches the streambuf::underflow virtual function. */ +typedef int (*_IO_underflow_t) __PMT ((_IO_FILE *)); +#define _IO_UNDERFLOW(FP) JUMP0 (__underflow, FP) +#define _IO_WUNDERFLOW(FP) WJUMP0 (__underflow, FP) + +/* The 'uflow' hook returns the next character in the input stream + (cast to unsigned char), and increments the read position; + EOF is returned on failure. + It matches the streambuf::uflow virtual function, which is not in the + cfront implementation, but was added to C++ by the ANSI/ISO committee. */ +#define _IO_UFLOW(FP) JUMP0 (__uflow, FP) +#define _IO_WUFLOW(FP) WJUMP0 (__uflow, FP) + +/* The 'pbackfail' hook handles backing up. + It matches the streambuf::pbackfail virtual function. */ +typedef int (*_IO_pbackfail_t) __PMT ((_IO_FILE *, int)); +#define _IO_PBACKFAIL(FP, CH) JUMP1 (__pbackfail, FP, CH) +#define _IO_WPBACKFAIL(FP, CH) WJUMP1 (__pbackfail, FP, CH) + +/* The 'xsputn' hook writes upto N characters from buffer DATA. + Returns the number of character actually written. + It matches the streambuf::xsputn virtual function. */ +typedef _IO_size_t (*_IO_xsputn_t) __PMT ((_IO_FILE *FP, const void *DATA, + _IO_size_t N)); +#define _IO_XSPUTN(FP, DATA, N) JUMP2 (__xsputn, FP, DATA, N) +#define _IO_WXSPUTN(FP, DATA, N) WJUMP2 (__xsputn, FP, DATA, N) + +/* The 'xsgetn' hook reads upto N characters into buffer DATA. + Returns the number of character actually read. + It matches the streambuf::xsgetn virtual function. */ +typedef _IO_size_t (*_IO_xsgetn_t) __PMT ((_IO_FILE *FP, void *DATA, + _IO_size_t N)); +#define _IO_XSGETN(FP, DATA, N) JUMP2 (__xsgetn, FP, DATA, N) +#define _IO_WXSGETN(FP, DATA, N) WJUMP2 (__xsgetn, FP, DATA, N) + +/* The 'seekoff' hook moves the stream position to a new position + relative to the start of the file (if DIR==0), the current position + (MODE==1), or the end of the file (MODE==2). + It matches the streambuf::seekoff virtual function. + It is also used for the ANSI fseek function. */ +typedef _IO_off64_t (*_IO_seekoff_t) __PMT ((_IO_FILE *FP, _IO_off64_t OFF, + int DIR, int MODE)); +#define _IO_SEEKOFF(FP, OFF, DIR, MODE) JUMP3 (__seekoff, FP, OFF, DIR, MODE) +#define _IO_WSEEKOFF(FP, OFF, DIR, MODE) WJUMP3 (__seekoff, FP, OFF, DIR, MODE) + +/* The 'seekpos' hook also moves the stream position, + but to an absolute position given by a fpos64_t (seekpos). + It matches the streambuf::seekpos virtual function. + It is also used for the ANSI fgetpos and fsetpos functions. */ +/* The _IO_seek_cur and _IO_seek_end options are not allowed. */ +typedef _IO_off64_t (*_IO_seekpos_t) __PMT ((_IO_FILE *, _IO_off64_t, int)); +#define _IO_SEEKPOS(FP, POS, FLAGS) JUMP2 (__seekpos, FP, POS, FLAGS) +#define _IO_WSEEKPOS(FP, POS, FLAGS) WJUMP2 (__seekpos, FP, POS, FLAGS) + +/* The 'setbuf' hook gives a buffer to the file. + It matches the streambuf::setbuf virtual function. */ +typedef _IO_FILE* (*_IO_setbuf_t) __PMT ((_IO_FILE *, char *, _IO_ssize_t)); +#define _IO_SETBUF(FP, BUFFER, LENGTH) JUMP2 (__setbuf, FP, BUFFER, LENGTH) +#define _IO_WSETBUF(FP, BUFFER, LENGTH) WJUMP2 (__setbuf, FP, BUFFER, LENGTH) + +/* The 'sync' hook attempts to synchronize the internal data structures + of the file with the external state. + It matches the streambuf::sync virtual function. */ +typedef int (*_IO_sync_t) __PMT ((_IO_FILE *)); +#define _IO_SYNC(FP) JUMP0 (__sync, FP) +#define _IO_WSYNC(FP) WJUMP0 (__sync, FP) + +/* The 'doallocate' hook is used to tell the file to allocate a buffer. + It matches the streambuf::doallocate virtual function, which is not + in the ANSI/ISO C++ standard, but is part traditional implementations. */ +typedef int (*_IO_doallocate_t) __PMT ((_IO_FILE *)); +#define _IO_DOALLOCATE(FP) JUMP0 (__doallocate, FP) +#define _IO_WDOALLOCATE(FP) WJUMP0 (__doallocate, FP) + +/* The following four hooks (sysread, syswrite, sysclose, sysseek, and + sysstat) are low-level hooks specific to this implementation. + There is no correspondence in the ANSI/ISO C++ standard library. + The hooks basically correspond to the Unix system functions + (read, write, close, lseek, and stat) except that a _IO_FILE* + parameter is used instead of a integer file descriptor; the default + implementation used for normal files just calls those functions. + The advantage of overriding these functions instead of the higher-level + ones (underflow, overflow etc) is that you can leave all the buffering + higher-level functions. */ + +/* The 'sysread' hook is used to read data from the external file into + an existing buffer. It generalizes the Unix read(2) function. + It matches the streambuf::sys_read virtual function, which is + specific to this implementation. */ +typedef _IO_ssize_t (*_IO_read_t) __PMT ((_IO_FILE *, void *, _IO_ssize_t)); +#define _IO_SYSREAD(FP, DATA, LEN) JUMP2 (__read, FP, DATA, LEN) +#define _IO_WSYSREAD(FP, DATA, LEN) WJUMP2 (__read, FP, DATA, LEN) + +/* The 'syswrite' hook is used to write data from an existing buffer + to an external file. It generalizes the Unix write(2) function. + It matches the streambuf::sys_write virtual function, which is + specific to this implementation. */ +typedef _IO_ssize_t (*_IO_write_t) __PMT ((_IO_FILE *, const void *, + _IO_ssize_t)); +#define _IO_SYSWRITE(FP, DATA, LEN) JUMP2 (__write, FP, DATA, LEN) +#define _IO_WSYSWRITE(FP, DATA, LEN) WJUMP2 (__write, FP, DATA, LEN) + +/* The 'sysseek' hook is used to re-position an external file. + It generalizes the Unix lseek(2) function. + It matches the streambuf::sys_seek virtual function, which is + specific to this implementation. */ +typedef _IO_off64_t (*_IO_seek_t) __PMT ((_IO_FILE *, _IO_off64_t, int)); +#define _IO_SYSSEEK(FP, OFFSET, MODE) JUMP2 (__seek, FP, OFFSET, MODE) +#define _IO_WSYSSEEK(FP, OFFSET, MODE) WJUMP2 (__seek, FP, OFFSET, MODE) + +/* The 'sysclose' hook is used to finalize (close, finish up) an + external file. It generalizes the Unix close(2) function. + It matches the streambuf::sys_close virtual function, which is + specific to this implementation. */ +typedef int (*_IO_close_t) __PMT ((_IO_FILE *)); /* finalize */ +#define _IO_SYSCLOSE(FP) JUMP0 (__close, FP) +#define _IO_WSYSCLOSE(FP) WJUMP0 (__close, FP) + +/* The 'sysstat' hook is used to get information about an external file + into a struct stat buffer. It generalizes the Unix fstat(2) call. + It matches the streambuf::sys_stat virtual function, which is + specific to this implementation. */ +typedef int (*_IO_stat_t) __PMT ((_IO_FILE *, void *)); +#define _IO_SYSSTAT(FP, BUF) JUMP1 (__stat, FP, BUF) +#define _IO_WSYSSTAT(FP, BUF) WJUMP1 (__stat, FP, BUF) + +/* The 'showmany' hook can be used to get an image how much input is + available. In many cases the answer will be 0 which means unknown + but some cases one can provide real information. */ +typedef int (*_IO_showmanyc_t) __PMT ((_IO_FILE *)); +#define _IO_SHOWMANYC(FP) JUMP0 (__showmanyc, FP) +#define _IO_WSHOWMANYC(FP) WJUMP0 (__showmanyc, FP) + +/* The 'imbue' hook is used to get information about the currently + installed locales. */ +typedef void (*_IO_imbue_t) __PMT ((_IO_FILE *, void *)); +#define _IO_IMBUE(FP, LOCALE) JUMP1 (__imbue, FP, LOCALE) +#define _IO_WIMBUE(FP, LOCALE) WJUMP1 (__imbue, FP, LOCALE) + + +#define _IO_CHAR_TYPE char /* unsigned char ? */ +#define _IO_INT_TYPE int + +struct _IO_jump_t +{ + JUMP_FIELD(_G_size_t, __dummy); +#ifdef _G_USING_THUNKS + JUMP_FIELD(_G_size_t, __dummy2); +#endif + JUMP_FIELD(_IO_finish_t, __finish); + JUMP_FIELD(_IO_overflow_t, __overflow); + JUMP_FIELD(_IO_underflow_t, __underflow); + JUMP_FIELD(_IO_underflow_t, __uflow); + JUMP_FIELD(_IO_pbackfail_t, __pbackfail); + /* showmany */ + JUMP_FIELD(_IO_xsputn_t, __xsputn); + JUMP_FIELD(_IO_xsgetn_t, __xsgetn); + JUMP_FIELD(_IO_seekoff_t, __seekoff); + JUMP_FIELD(_IO_seekpos_t, __seekpos); + JUMP_FIELD(_IO_setbuf_t, __setbuf); + JUMP_FIELD(_IO_sync_t, __sync); + JUMP_FIELD(_IO_doallocate_t, __doallocate); + JUMP_FIELD(_IO_read_t, __read); + JUMP_FIELD(_IO_write_t, __write); + JUMP_FIELD(_IO_seek_t, __seek); + JUMP_FIELD(_IO_close_t, __close); + JUMP_FIELD(_IO_stat_t, __stat); + JUMP_FIELD(_IO_showmanyc_t, __showmanyc); + JUMP_FIELD(_IO_imbue_t, __imbue); +#if 0 + get_column; + set_column; +#endif +}; + +/* We always allocate an extra word following an _IO_FILE. + This contains a pointer to the function jump table used. + This is for compatibility with C++ streambuf; the word can + be used to smash to a pointer to a virtual function table. */ + +struct _IO_FILE_plus +{ + _IO_FILE file; + const struct _IO_jump_t *vtable; +}; + +/* Special file type for fopencookie function. */ +struct _IO_cookie_file +{ + struct _IO_FILE_plus __fp; + void *__cookie; + _IO_cookie_io_functions_t __io_functions; +}; + +_IO_FILE *_IO_fopencookie (void *cookie, const char *mode, + _IO_cookie_io_functions_t io_functions); + + +/* Iterator type for walking global linked list of _IO_FILE objects. */ + +typedef struct _IO_FILE *_IO_ITER; + +/* Generic functions */ + +extern void _IO_switch_to_main_get_area __P ((_IO_FILE *)); +extern void _IO_switch_to_backup_area __P ((_IO_FILE *)); +extern int _IO_switch_to_get_mode __P ((_IO_FILE *)); +extern void _IO_init __P ((_IO_FILE *, int)); +extern int _IO_sputbackc __P ((_IO_FILE *, int)); +extern int _IO_sungetc __P ((_IO_FILE *)); +extern void _IO_un_link __P ((struct _IO_FILE_plus *)); +extern void _IO_link_in __P ((struct _IO_FILE_plus *)); +extern void _IO_doallocbuf __P ((_IO_FILE *)); +extern void _IO_unsave_markers __P ((_IO_FILE *)); +extern void _IO_setb __P ((_IO_FILE *, char *, char *, int)); +extern unsigned _IO_adjust_column __P ((unsigned, const char *, int)); +#define _IO_sputn(__fp, __s, __n) _IO_XSPUTN (__fp, __s, __n) + +extern void _IO_switch_to_main_wget_area __P ((_IO_FILE *)); +extern void _IO_switch_to_wbackup_area __P ((_IO_FILE *)); +extern int _IO_switch_to_wget_mode __P ((_IO_FILE *)); +extern void _IO_wsetb __P ((_IO_FILE *, wchar_t *, wchar_t *, int)); +extern wint_t _IO_sputbackwc __P ((_IO_FILE *, wint_t)); +extern wint_t _IO_sungetwc __P ((_IO_FILE *)); +extern void _IO_wdoallocbuf __P ((_IO_FILE *)); +extern void _IO_unsave_wmarkers __P ((_IO_FILE *)); +extern unsigned _IO_adjust_wcolumn __P ((unsigned, const wchar_t *, int)); + +/* Marker-related function. */ + +extern void _IO_init_marker __P ((struct _IO_marker *, _IO_FILE *)); +extern void _IO_init_wmarker __P ((struct _IO_marker *, _IO_FILE *)); +extern void _IO_remove_marker __P ((struct _IO_marker *)); +extern int _IO_marker_difference __P ((struct _IO_marker *, + struct _IO_marker *)); +extern int _IO_marker_delta __P ((struct _IO_marker *)); +extern int _IO_wmarker_delta __P ((struct _IO_marker *)); +extern int _IO_seekmark __P ((_IO_FILE *, struct _IO_marker *, int)); +extern int _IO_seekwmark __P ((_IO_FILE *, struct _IO_marker *, int)); + +/* Functions for iterating global list and dealing with + its lock */ + +extern _IO_ITER _IO_iter_begin __P ((void)); +libc_hidden_proto (_IO_iter_begin) +extern _IO_ITER _IO_iter_end __P ((void)); +libc_hidden_proto (_IO_iter_end) +extern _IO_ITER _IO_iter_next __P ((_IO_ITER)); +libc_hidden_proto (_IO_iter_next) +extern _IO_FILE *_IO_iter_file __P ((_IO_ITER)); +libc_hidden_proto (_IO_iter_file) +extern void _IO_list_lock __P ((void)); +libc_hidden_proto (_IO_list_lock) +extern void _IO_list_unlock __P ((void)); +libc_hidden_proto (_IO_list_unlock) +extern void _IO_list_resetlock __P ((void)); +libc_hidden_proto (_IO_list_resetlock) + +/* Default jumptable functions. */ + +extern int _IO_default_underflow __P ((_IO_FILE *)); +extern int _IO_default_uflow __P ((_IO_FILE *)); +extern wint_t _IO_wdefault_uflow __P ((_IO_FILE *)); +extern int _IO_default_doallocate __P ((_IO_FILE *)); +extern int _IO_wdefault_doallocate __P ((_IO_FILE *)); +extern void _IO_default_finish __P ((_IO_FILE *, int)); +extern void _IO_wdefault_finish __P ((_IO_FILE *, int)); +extern int _IO_default_pbackfail __P ((_IO_FILE *, int)); +extern wint_t _IO_wdefault_pbackfail __P ((_IO_FILE *, wint_t)); +extern _IO_FILE* _IO_default_setbuf __P ((_IO_FILE *, char *, _IO_ssize_t)); +extern _IO_size_t _IO_default_xsputn __P ((_IO_FILE *, const void *, + _IO_size_t)); +extern _IO_size_t _IO_wdefault_xsputn __P ((_IO_FILE *, const void *, + _IO_size_t)); +extern _IO_size_t _IO_default_xsgetn __P ((_IO_FILE *, void *, _IO_size_t)); +extern _IO_size_t _IO_wdefault_xsgetn __P ((_IO_FILE *, void *, _IO_size_t)); +extern _IO_off64_t _IO_default_seekoff __P ((_IO_FILE *, + _IO_off64_t, int, int)); +extern _IO_off64_t _IO_default_seekpos __P ((_IO_FILE *, _IO_off64_t, int)); +extern _IO_ssize_t _IO_default_write __P ((_IO_FILE *, const void *, + _IO_ssize_t)); +extern _IO_ssize_t _IO_default_read __P ((_IO_FILE *, void *, _IO_ssize_t)); +extern int _IO_default_stat __P ((_IO_FILE *, void *)); +extern _IO_off64_t _IO_default_seek __P ((_IO_FILE *, _IO_off64_t, int)); +extern int _IO_default_sync __P ((_IO_FILE *)); +#define _IO_default_close ((_IO_close_t) _IO_default_sync) +extern int _IO_default_showmanyc __P ((_IO_FILE *)); +extern void _IO_default_imbue __P ((_IO_FILE *, void *)); + +extern struct _IO_jump_t _IO_file_jumps; +extern struct _IO_jump_t _IO_file_jumps_mmap attribute_hidden; +extern struct _IO_jump_t _IO_file_jumps_maybe_mmap attribute_hidden; +extern struct _IO_jump_t _IO_wfile_jumps attribute_hidden; +extern struct _IO_jump_t _IO_wfile_jumps_mmap attribute_hidden; +extern struct _IO_jump_t _IO_wfile_jumps_maybe_mmap attribute_hidden; +extern struct _IO_jump_t _IO_old_file_jumps attribute_hidden; +extern struct _IO_jump_t _IO_streambuf_jumps; +extern struct _IO_jump_t _IO_old_proc_jumps attribute_hidden; +extern struct _IO_jump_t _IO_str_jumps attribute_hidden; +extern struct _IO_jump_t _IO_wstr_jumps attribute_hidden; +extern struct _IO_codecvt __libio_codecvt attribute_hidden; +extern int _IO_do_write __P ((_IO_FILE *, const char *, _IO_size_t)); +extern int _IO_new_do_write __P ((_IO_FILE *, const char *, _IO_size_t)); +extern int _IO_old_do_write __P ((_IO_FILE *, const char *, _IO_size_t)); +extern int _IO_wdo_write __P ((_IO_FILE *, const wchar_t *, _IO_size_t)); +extern int _IO_flush_all_lockp __P ((int)); +extern int _IO_flush_all __P ((void)); +extern int _IO_cleanup __P ((void)); +extern void _IO_flush_all_linebuffered __P ((void)); +extern int _IO_new_fgetpos __P ((_IO_FILE *, _IO_fpos_t *)); +extern int _IO_old_fgetpos __P ((_IO_FILE *, _IO_fpos_t *)); +extern int _IO_new_fsetpos __P ((_IO_FILE *, const _IO_fpos_t *)); +extern int _IO_old_fsetpos __P ((_IO_FILE *, const _IO_fpos_t *)); +extern int _IO_new_fgetpos64 __P ((_IO_FILE *, _IO_fpos64_t *)); +extern int _IO_old_fgetpos64 __P ((_IO_FILE *, _IO_fpos64_t *)); +extern int _IO_new_fsetpos64 __P ((_IO_FILE *, const _IO_fpos64_t *)); +extern int _IO_old_fsetpos64 __P ((_IO_FILE *, const _IO_fpos64_t *)); + + +#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T +# define _IO_do_flush(_f) \ + ((_f)->_mode <= 0 \ + ? INTUSE(_IO_do_write)(_f, (_f)->_IO_write_base, \ + (_f)->_IO_write_ptr-(_f)->_IO_write_base) \ + : INTUSE(_IO_wdo_write)(_f, (_f)->_wide_data->_IO_write_base, \ + ((_f)->_wide_data->_IO_write_ptr \ + - (_f)->_wide_data->_IO_write_base))) +#else +# define _IO_do_flush(_f) \ + INTUSE(_IO_do_write)(_f, (_f)->_IO_write_base, \ + (_f)->_IO_write_ptr-(_f)->_IO_write_base) +#endif +#define _IO_old_do_flush(_f) \ + _IO_old_do_write(_f, (_f)->_IO_write_base, \ + (_f)->_IO_write_ptr-(_f)->_IO_write_base) +#define _IO_in_put_mode(_fp) ((_fp)->_flags & _IO_CURRENTLY_PUTTING) +#define _IO_mask_flags(fp, f, mask) \ + ((fp)->_flags = ((fp)->_flags & ~(mask)) | ((f) & (mask))) +#define _IO_setg(fp, eb, g, eg) ((fp)->_IO_read_base = (eb),\ + (fp)->_IO_read_ptr = (g), (fp)->_IO_read_end = (eg)) +#define _IO_wsetg(fp, eb, g, eg) ((fp)->_wide_data->_IO_read_base = (eb),\ + (fp)->_wide_data->_IO_read_ptr = (g), \ + (fp)->_wide_data->_IO_read_end = (eg)) +#define _IO_setp(__fp, __p, __ep) \ + ((__fp)->_IO_write_base = (__fp)->_IO_write_ptr \ + = __p, (__fp)->_IO_write_end = (__ep)) +#define _IO_wsetp(__fp, __p, __ep) \ + ((__fp)->_wide_data->_IO_write_base \ + = (__fp)->_wide_data->_IO_write_ptr = __p, \ + (__fp)->_wide_data->_IO_write_end = (__ep)) +#define _IO_have_backup(fp) ((fp)->_IO_save_base != NULL) +#define _IO_have_wbackup(fp) ((fp)->_wide_data->_IO_save_base != NULL) +#define _IO_in_backup(fp) ((fp)->_flags & _IO_IN_BACKUP) +#define _IO_have_markers(fp) ((fp)->_markers != NULL) +#define _IO_blen(fp) ((fp)->_IO_buf_end - (fp)->_IO_buf_base) +#define _IO_wblen(fp) ((fp)->_wide_data->_IO_buf_end \ + - (fp)->_wide_data->_IO_buf_base) + +/* Jumptable functions for files. */ + +extern int _IO_file_doallocate __P ((_IO_FILE *)); +extern _IO_FILE* _IO_file_setbuf __P ((_IO_FILE *, char *, _IO_ssize_t)); +extern _IO_off64_t _IO_file_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int)); +extern _IO_off64_t _IO_file_seekoff_mmap __P ((_IO_FILE *, _IO_off64_t, int, + int)); +extern _IO_size_t _IO_file_xsputn __P ((_IO_FILE *, const void *, _IO_size_t)); +extern _IO_size_t _IO_file_xsgetn __P ((_IO_FILE *, void *, _IO_size_t)); +extern int _IO_file_stat __P ((_IO_FILE *, void *)); +extern int _IO_file_close __P ((_IO_FILE *)); +extern int _IO_file_close_mmap __P ((_IO_FILE *)); +extern int _IO_file_underflow __P ((_IO_FILE *)); +extern int _IO_file_underflow_mmap __P ((_IO_FILE *)); +extern int _IO_file_underflow_maybe_mmap __P ((_IO_FILE *)); +extern int _IO_file_overflow __P ((_IO_FILE *, int)); +#define _IO_file_is_open(__fp) ((__fp)->_fileno != -1) +extern void _IO_file_init __P ((struct _IO_FILE_plus *)); +extern _IO_FILE* _IO_file_attach __P ((_IO_FILE *, int)); +extern _IO_FILE* _IO_file_open __P ((_IO_FILE *, const char *, int, int, + int, int)); +libc_hidden_proto (_IO_file_open) +extern _IO_FILE* _IO_file_fopen __P ((_IO_FILE *, const char *, const char *, + int)); +extern _IO_ssize_t _IO_file_write __P ((_IO_FILE *, const void *, + _IO_ssize_t)); +extern _IO_ssize_t _IO_file_read __P ((_IO_FILE *, void *, _IO_ssize_t)); +extern int _IO_file_sync __P ((_IO_FILE *)); +extern int _IO_file_close_it __P ((_IO_FILE *)); +extern _IO_off64_t _IO_file_seek __P ((_IO_FILE *, _IO_off64_t, int)); +extern void _IO_file_finish __P ((_IO_FILE *, int)); + +extern _IO_FILE* _IO_new_file_attach __P ((_IO_FILE *, int)); +extern int _IO_new_file_close_it __P ((_IO_FILE *)); +extern void _IO_new_file_finish __P ((_IO_FILE *, int)); +extern _IO_FILE* _IO_new_file_fopen __P ((_IO_FILE *, const char *, const char *, + int)); +extern void _IO_no_init __P ((_IO_FILE *, int, int, struct _IO_wide_data *, + struct _IO_jump_t *)); +extern void _IO_new_file_init __P ((struct _IO_FILE_plus *)); +extern _IO_FILE* _IO_new_file_setbuf __P ((_IO_FILE *, char *, _IO_ssize_t)); +extern _IO_FILE* _IO_file_setbuf_mmap __P ((_IO_FILE *, char *, _IO_ssize_t)); +extern int _IO_new_file_sync __P ((_IO_FILE *)); +extern int _IO_new_file_underflow __P ((_IO_FILE *)); +extern int _IO_new_file_overflow __P ((_IO_FILE *, int)); +extern _IO_off64_t _IO_new_file_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int)); +extern _IO_ssize_t _IO_new_file_write __P ((_IO_FILE *, const void *, + _IO_ssize_t)); +extern _IO_size_t _IO_new_file_xsputn __P ((_IO_FILE *, const void *, _IO_size_t)); + +extern _IO_FILE* _IO_old_file_setbuf __P ((_IO_FILE *, char *, _IO_ssize_t)); +extern _IO_off64_t _IO_old_file_seekoff __P ((_IO_FILE *, _IO_off64_t, int, + int)); +extern _IO_size_t _IO_old_file_xsputn __P ((_IO_FILE *, const void *, + _IO_size_t)); +extern int _IO_old_file_underflow __P ((_IO_FILE *)); +extern int _IO_old_file_overflow __P ((_IO_FILE *, int)); +extern void _IO_old_file_init __P ((struct _IO_FILE_plus *)); +extern _IO_FILE* _IO_old_file_attach __P ((_IO_FILE *, int)); +extern _IO_FILE* _IO_old_file_fopen __P ((_IO_FILE *, const char *, + const char *)); +extern _IO_ssize_t _IO_old_file_write __P ((_IO_FILE *, const void *, + _IO_ssize_t)); +extern int _IO_old_file_sync __P ((_IO_FILE *)); +extern int _IO_old_file_close_it __P ((_IO_FILE *)); +extern void _IO_old_file_finish __P ((_IO_FILE *, int)); + +extern int _IO_wfile_doallocate __P ((_IO_FILE *)); +extern _IO_size_t _IO_wfile_xsputn __P ((_IO_FILE *, const void *, + _IO_size_t)); +extern _IO_FILE* _IO_wfile_setbuf __P ((_IO_FILE *, wchar_t *, _IO_ssize_t)); +extern wint_t _IO_wfile_sync __P ((_IO_FILE *)); +extern wint_t _IO_wfile_underflow __P ((_IO_FILE *)); +extern wint_t _IO_wfile_overflow __P ((_IO_FILE *, wint_t)); +extern _IO_off64_t _IO_wfile_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int)); + +/* Jumptable functions for proc_files. */ +extern _IO_FILE* _IO_proc_open __P ((_IO_FILE *, const char *, const char *)); +extern _IO_FILE* _IO_new_proc_open __P ((_IO_FILE *, const char *, const char *)); +extern _IO_FILE* _IO_old_proc_open __P ((_IO_FILE *, const char *, const char *)); +extern int _IO_proc_close __P ((_IO_FILE *)); +extern int _IO_new_proc_close __P ((_IO_FILE *)); +extern int _IO_old_proc_close __P ((_IO_FILE *)); + +/* Jumptable functions for strfiles. */ +extern int _IO_str_underflow __P ((_IO_FILE *)); +extern int _IO_str_overflow __P ((_IO_FILE *, int)); +extern int _IO_str_pbackfail __P ((_IO_FILE *, int)); +extern _IO_off64_t _IO_str_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int)); +extern void _IO_str_finish __P ((_IO_FILE *, int)); + +/* Other strfile functions */ +struct _IO_strfile_; +extern void _IO_str_init_static __P ((struct _IO_strfile_ *, char *, int, char *)); +extern void _IO_str_init_readonly __P ((struct _IO_strfile_ *, const char *, int)); +extern _IO_ssize_t _IO_str_count __P ((_IO_FILE *)); + +/* And the wide character versions. */ +extern void _IO_wstr_init_static __P ((_IO_FILE *, wchar_t *, int, wchar_t *)); +extern void _IO_wstr_init_readonly __P ((_IO_FILE *, const char *, int)); +extern _IO_ssize_t _IO_wstr_count __P ((_IO_FILE *)); +extern _IO_wint_t _IO_wstr_overflow __P ((_IO_FILE *, _IO_wint_t)); +extern _IO_wint_t _IO_wstr_underflow __P ((_IO_FILE *)); +extern _IO_off64_t _IO_wstr_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int)); +extern _IO_wint_t _IO_wstr_pbackfail __P ((_IO_FILE *, _IO_wint_t)); +extern void _IO_wstr_finish __P ((_IO_FILE *, int)); + +extern int _IO_vasprintf __P ((char **result_ptr, __const char *format, + _IO_va_list args)); +extern int _IO_vdprintf __P ((int d, __const char *format, _IO_va_list arg)); +extern int _IO_vsnprintf __P ((char *string, _IO_size_t maxlen, + __const char *format, _IO_va_list args)); + + +extern _IO_size_t _IO_getline __P ((_IO_FILE *,char *, _IO_size_t, int, int)); +extern _IO_size_t _IO_getline_info __P ((_IO_FILE *,char *, _IO_size_t, + int, int, int *)); +extern _IO_ssize_t _IO_getdelim __P ((char **, _IO_size_t *, int, _IO_FILE *)); +extern _IO_size_t _IO_getwline __P ((_IO_FILE *,wchar_t *, _IO_size_t, wint_t, + int)); +extern _IO_size_t _IO_getwline_info __P ((_IO_FILE *,wchar_t *, _IO_size_t, + wint_t, int, wint_t *)); +extern double _IO_strtod __P ((const char *, char **)); +extern char *_IO_dtoa __P ((double __d, int __mode, int __ndigits, + int *__decpt, int *__sign, char **__rve)); +extern int _IO_outfloat __P ((double __value, _IO_FILE *__sb, int __type, + int __width, int __precision, int __flags, + int __sign_mode, int __fill)); + +extern struct _IO_FILE_plus *_IO_list_all; +extern void (*_IO_cleanup_registration_needed) __PMT ((void)); + +/* Prototype for functions with alternative entry point. */ +extern int _IO_flush_all_internal __P ((void)); +extern unsigned _IO_adjust_column_internal __P ((unsigned, const char *, int)); + +extern int _IO_default_uflow_internal __P ((_IO_FILE *)); +extern void _IO_default_finish_internal __P ((_IO_FILE *, int)); +extern int _IO_default_pbackfail_internal __P ((_IO_FILE *, int)); +extern _IO_size_t _IO_default_xsputn_internal __P ((_IO_FILE *, const void *, + _IO_size_t)); +extern _IO_size_t _IO_default_xsgetn_internal __P ((_IO_FILE *, void *, + _IO_size_t)); +extern int _IO_default_doallocate_internal __P ((_IO_FILE *)); +extern void _IO_wdefault_finish_internal __P ((_IO_FILE *, int)); +extern wint_t _IO_wdefault_pbackfail_internal __P ((_IO_FILE *, wint_t)); +extern _IO_size_t _IO_wdefault_xsputn_internal __P ((_IO_FILE *, const void *, + _IO_size_t)); +extern _IO_size_t _IO_wdefault_xsgetn_internal __P ((_IO_FILE *, void *, + _IO_size_t)); +extern int _IO_wdefault_doallocate_internal __P ((_IO_FILE *)); +extern wint_t _IO_wdefault_uflow_internal __P ((_IO_FILE *)); + +extern int _IO_file_doallocate_internal __P ((_IO_FILE *)); +extern _IO_FILE* _IO_file_setbuf_internal __P ((_IO_FILE *, char *, + _IO_ssize_t)); +extern _IO_off64_t _IO_file_seekoff_internal __P ((_IO_FILE *, _IO_off64_t, + int, int)); +extern _IO_size_t _IO_file_xsputn_internal __P ((_IO_FILE *, const void *, + _IO_size_t)); +extern _IO_size_t _IO_file_xsgetn_internal __P ((_IO_FILE *, void *, + _IO_size_t)); +extern int _IO_file_stat_internal __P ((_IO_FILE *, void *)); +extern int _IO_file_close_internal __P ((_IO_FILE *)); +extern int _IO_file_close_it_internal __P ((_IO_FILE *)); +extern int _IO_file_underflow_internal __P ((_IO_FILE *)); +extern int _IO_file_overflow_internal __P ((_IO_FILE *, int)); +extern void _IO_file_init_internal __P ((struct _IO_FILE_plus *)); +extern _IO_FILE* _IO_file_attach_internal __P ((_IO_FILE *, int)); +extern _IO_FILE* _IO_file_fopen_internal __P ((_IO_FILE *, const char *, + const char *, int)); +extern _IO_ssize_t _IO_file_read_internal __P ((_IO_FILE *, void *, + _IO_ssize_t)); +extern int _IO_file_sync_internal __P ((_IO_FILE *)); +extern _IO_off64_t _IO_file_seek_internal __P ((_IO_FILE *, _IO_off64_t, int)); +extern void _IO_file_finish_internal __P ((_IO_FILE *, int)); + +extern _IO_size_t _IO_wfile_xsputn_internal __P ((_IO_FILE *, const void *, + _IO_size_t)); +extern _IO_off64_t _IO_wfile_seekoff_internal __P ((_IO_FILE *, _IO_off64_t, + int, int)); +extern wint_t _IO_wfile_sync_internal __P ((_IO_FILE *)); + +extern int _IO_str_underflow_internal __P ((_IO_FILE *)); +extern int _IO_str_overflow_internal __P ((_IO_FILE *, int)); +extern int _IO_str_pbackfail_internal __P ((_IO_FILE *, int)); +extern _IO_off64_t _IO_str_seekoff_internal __P ((_IO_FILE *, _IO_off64_t, + int, int)); +extern void _IO_str_init_static_internal __P ((struct _IO_strfile_ *, char *, + int, char *)); + +extern struct _IO_jump_t _IO_file_jumps_internal attribute_hidden; +extern struct _IO_jump_t _IO_wfile_jumps_internal attribute_hidden; + +extern struct _IO_FILE_plus *_IO_list_all_internal attribute_hidden; + +extern void _IO_link_in_internal __P ((struct _IO_FILE_plus *)); +extern int _IO_sputbackc_internal __P ((_IO_FILE *, int)); +extern void _IO_wdoallocbuf_internal __P ((_IO_FILE *)); + +extern _IO_size_t _IO_sgetn_internal (_IO_FILE *, void *, _IO_size_t); +extern void _IO_flush_all_linebuffered_internal __P ((void)); +extern int _IO_switch_to_wget_mode_internal __P ((_IO_FILE *)); +extern void _IO_unsave_markers_internal __P ((_IO_FILE *)); +extern void _IO_switch_to_main_wget_area_internal __P ((_IO_FILE *)); +extern int _IO_wdo_write_internal __P ((_IO_FILE *, const wchar_t *, + _IO_size_t)); +extern int _IO_do_write_internal __P ((_IO_FILE *, const char *, _IO_size_t)); +extern _IO_ssize_t _IO_padn_internal (_IO_FILE *, int, _IO_ssize_t); +extern _IO_size_t _IO_getline_info_internal __P ((_IO_FILE *,char *, + _IO_size_t, int, int, + int *)); +extern _IO_size_t _IO_getline_internal __P ((_IO_FILE *, char *, _IO_size_t, + int, int)); +extern void _IO_free_wbackup_area_internal (_IO_FILE *); +extern void _IO_free_backup_area_internal (_IO_FILE *); +extern void _IO_switch_to_wbackup_area_internal __P ((_IO_FILE *)); +extern void _IO_setb_internal __P ((_IO_FILE *, char *, char *, int)); +extern wint_t _IO_sputbackwc_internal __P ((_IO_FILE *, wint_t)); +extern int _IO_switch_to_get_mode_internal __P ((_IO_FILE *)); +extern int _IO_vfscanf_internal (_IO_FILE * __restrict, + const char * __restrict, + _IO_va_list, int *__restrict); +extern int _IO_vfprintf_internal (_IO_FILE *__restrict, const char *__restrict, + _IO_va_list); +extern void _IO_doallocbuf_internal __P ((_IO_FILE *)); +extern void _IO_wsetb_internal __P ((_IO_FILE *, wchar_t *, wchar_t *, int)); +extern _IO_off64_t _IO_seekoff_unlocked (_IO_FILE *, _IO_off64_t, int, int) + attribute_hidden; +extern _IO_off64_t _IO_seekpos_unlocked (_IO_FILE *, _IO_off64_t, int) + attribute_hidden; +extern int _IO_putc_internal (int __c, _IO_FILE *__fp); +extern void _IO_init_internal __P ((_IO_FILE *, int)); +extern void _IO_un_link_internal __P ((struct _IO_FILE_plus *)); + +#ifndef EOF +# define EOF (-1) +#endif +#ifndef NULL +# if defined __GNUG__ && \ + (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)) +# define NULL (__null) +# else +# if !defined(__cplusplus) +# define NULL ((void*)0) +# else +# define NULL (0) +# endif +# endif +#endif + +#if _G_HAVE_MMAP + +# include +# include +# include +# include + +# if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) +# define MAP_ANONYMOUS MAP_ANON +# endif + +# if !defined(MAP_ANONYMOUS) || !defined(EXEC_PAGESIZE) +# undef _G_HAVE_MMAP +# define _G_HAVE_MMAP 0 +# endif + +#endif /* _G_HAVE_MMAP */ + +#if _G_HAVE_MMAP + +# ifdef _LIBC +/* When using this code in the GNU libc we must not pollute the name space. */ +# define mmap __mmap +# define munmap __munmap +# define ftruncate __ftruncate +# endif + +# define ROUND_TO_PAGE(_S) \ + (((_S) + EXEC_PAGESIZE - 1) & ~(EXEC_PAGESIZE - 1)) + +# define FREE_BUF(_B, _S) \ + munmap ((_B), ROUND_TO_PAGE (_S)) +# define ALLOC_BUF(_B, _S, _R) \ + do { \ + (_B) = (char *) mmap (0, ROUND_TO_PAGE (_S), \ + PROT_READ | PROT_WRITE, \ + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \ + if ((_B) == (char *) MAP_FAILED) \ + return (_R); \ + } while (0) +# define ALLOC_WBUF(_B, _S, _R) \ + do { \ + (_B) = (wchar_t *) mmap (0, ROUND_TO_PAGE (_S), \ + PROT_READ | PROT_WRITE, \ + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \ + if ((_B) == (wchar_t *) MAP_FAILED) \ + return (_R); \ + } while (0) + +#else /* _G_HAVE_MMAP */ + +# define FREE_BUF(_B, _S) \ + free(_B) +# define ALLOC_BUF(_B, _S, _R) \ + do { \ + (_B) = (char*)malloc(_S); \ + if ((_B) == NULL) \ + return (_R); \ + } while (0) +# define ALLOC_WBUF(_B, _S, _R) \ + do { \ + (_B) = (wchar_t *)malloc(_S); \ + if ((_B) == NULL) \ + return (_R); \ + } while (0) + +#endif /* _G_HAVE_MMAP */ + +#ifndef OS_FSTAT +# define OS_FSTAT fstat +#endif +struct stat; +extern _IO_ssize_t _IO_read __P ((int, void *, _IO_size_t)); +extern _IO_ssize_t _IO_write __P ((int, const void *, _IO_size_t)); +extern _IO_off64_t _IO_lseek __P ((int, _IO_off64_t, int)); +extern int _IO_close __P ((int)); +extern int _IO_fstat __P ((int, struct stat *)); +extern int _IO_vscanf __P ((const char *, _IO_va_list)); + +/* _IO_pos_BAD is an _IO_off64_t value indicating error, unknown, or EOF. */ +#ifndef _IO_pos_BAD +# define _IO_pos_BAD ((_IO_off64_t) -1) +#endif +/* _IO_pos_adjust adjust an _IO_off64_t by some number of bytes. */ +#ifndef _IO_pos_adjust +# define _IO_pos_adjust(pos, delta) ((pos) += (delta)) +#endif +/* _IO_pos_0 is an _IO_off64_t value indicating beginning of file. */ +#ifndef _IO_pos_0 +# define _IO_pos_0 ((_IO_off64_t) 0) +#endif + +#ifdef __cplusplus +} +#endif + +#ifdef _IO_MTSAFE_IO +/* check following! */ +# ifdef _IO_USE_OLD_IO_FILE +# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \ + { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (_IO_FILE *) CHAIN, FD, \ + 0, _IO_pos_BAD, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock } +# else +# if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T +# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \ + { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (_IO_FILE *) CHAIN, FD, \ + 0, _IO_pos_BAD, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock, _IO_pos_BAD,\ + NULL, WDP, 0 } +# else +# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \ + { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (_IO_FILE *) CHAIN, FD, \ + 0, _IO_pos_BAD, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock, _IO_pos_BAD,\ + 0 } +# endif +# endif +#else +# ifdef _IO_USE_OLD_IO_FILE +# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \ + { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (_IO_FILE *) CHAIN, FD, \ + 0, _IO_pos_BAD } +# else +# if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T +# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \ + { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (_IO_FILE *) CHAIN, FD, \ + 0, _IO_pos_BAD, 0, 0, { 0 }, 0, _IO_pos_BAD, \ + NULL, WDP, 0 } +# else +# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \ + { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (_IO_FILE *) CHAIN, FD, \ + 0, _IO_pos_BAD, 0, 0, { 0 }, 0, _IO_pos_BAD, \ + 0 } +# endif +# endif +#endif + +/* VTABLE_LABEL defines NAME as of the CLASS class. + CNLENGTH is strlen(#CLASS). */ +#ifdef __GNUC__ +# if _G_VTABLE_LABEL_HAS_LENGTH +# define VTABLE_LABEL(NAME, CLASS, CNLENGTH) \ + extern char NAME[] asm (_G_VTABLE_LABEL_PREFIX #CNLENGTH #CLASS); +# else +# define VTABLE_LABEL(NAME, CLASS, CNLENGTH) \ + extern char NAME[] asm (_G_VTABLE_LABEL_PREFIX #CLASS); +# endif +#endif /* __GNUC__ */ + +#if !defined(builtinbuf_vtable) && defined(__cplusplus) +# ifdef __GNUC__ +VTABLE_LABEL(builtinbuf_vtable, builtinbuf, 10) +# else +# if _G_VTABLE_LABEL_HAS_LENGTH +# define builtinbuf_vtable _G_VTABLE_LABEL_PREFIX_ID##10builtinbuf +# else +# define builtinbuf_vtable _G_VTABLE_LABEL_PREFIX_ID##builtinbuf +# endif +# endif +#endif /* !defined(builtinbuf_vtable) && defined(__cplusplus) */ + +#if defined(__STDC__) || defined(__cplusplus) +# define _IO_va_start(args, last) va_start(args, last) +#else +# define _IO_va_start(args, last) va_start(args) +#endif + +extern struct _IO_fake_stdiobuf _IO_stdin_buf, _IO_stdout_buf, _IO_stderr_buf; + +#if 1 +# define COERCE_FILE(FILE) /* Nothing */ +#else +/* This is part of the kludge for binary compatibility with old stdio. */ +# define COERCE_FILE(FILE) \ + (((FILE)->_IO_file_flags & _IO_MAGIC_MASK) == _OLD_MAGIC_MASK \ + && (FILE) = *(FILE**)&((int*)fp)[1]) +#endif + +#ifdef EINVAL +# define MAYBE_SET_EINVAL __set_errno (EINVAL) +#else +# define MAYBE_SET_EINVAL /* nothing */ +#endif + +#ifdef IO_DEBUG +# define CHECK_FILE(FILE, RET) \ + if ((FILE) == NULL) { MAYBE_SET_EINVAL; return RET; } \ + else { COERCE_FILE(FILE); \ + if (((FILE)->_IO_file_flags & _IO_MAGIC_MASK) != _IO_MAGIC) \ + { MAYBE_SET_EINVAL; return RET; }} +#else +# define CHECK_FILE(FILE, RET) COERCE_FILE (FILE) +#endif + +#endif /* _LIBIO_P_H_ */ diff --git a/src/kernel/libroot/posix/glibc/libio/memstream.c b/src/kernel/libroot/posix/glibc/libio/memstream.c new file mode 100644 index 0000000000..a3ec964237 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/memstream.c @@ -0,0 +1,226 @@ +/* Copyright (C) 1995,1996,1997,1999,2000,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "libioP.h" +#include "strfile.h" +#include +#include + + +struct _IO_FILE_memstream +{ + _IO_strfile _sf; + char **bufloc; + _IO_size_t *sizeloc; +}; + + +static int _IO_mem_sync __P ((_IO_FILE* fp)); +static void _IO_mem_finish __P ((_IO_FILE* fp, int)); +static int _IO_wmem_sync __P ((_IO_FILE* fp)); +static void _IO_wmem_finish __P ((_IO_FILE* fp, int)); + + +static struct _IO_jump_t _IO_mem_jumps = +{ + JUMP_INIT_DUMMY, + JUMP_INIT (finish, _IO_mem_finish), + JUMP_INIT (overflow, INTUSE(_IO_str_overflow)), + JUMP_INIT (underflow, INTUSE(_IO_str_underflow)), + JUMP_INIT (uflow, INTUSE(_IO_default_uflow)), + JUMP_INIT (pbackfail, INTUSE(_IO_str_pbackfail)), + JUMP_INIT (xsputn, INTUSE(_IO_default_xsputn)), + JUMP_INIT (xsgetn, INTUSE(_IO_default_xsgetn)), + JUMP_INIT (seekoff, INTUSE(_IO_str_seekoff)), + JUMP_INIT (seekpos, _IO_default_seekpos), + JUMP_INIT (setbuf, _IO_default_setbuf), + JUMP_INIT (sync, _IO_mem_sync), + JUMP_INIT (doallocate, INTUSE(_IO_default_doallocate)), + JUMP_INIT (read, _IO_default_read), + JUMP_INIT (write, _IO_default_write), + JUMP_INIT (seek, _IO_default_seek), + JUMP_INIT (close, _IO_default_close), + JUMP_INIT (stat, _IO_default_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; + +static struct _IO_jump_t _IO_wmem_jumps = +{ + JUMP_INIT_DUMMY, + JUMP_INIT (finish, (_IO_finish_t) _IO_wmem_finish), + JUMP_INIT (overflow, (_IO_overflow_t) _IO_wstr_overflow), + JUMP_INIT (underflow, (_IO_underflow_t) _IO_wstr_underflow), + JUMP_INIT (uflow, (_IO_underflow_t) INTUSE(_IO_wdefault_uflow)), + JUMP_INIT (pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail), + JUMP_INIT (xsputn, (_IO_xsputn_t) INTUSE(_IO_wdefault_xsputn)), + JUMP_INIT (xsgetn, (_IO_xsgetn_t) INTUSE(_IO_wdefault_xsgetn)), + JUMP_INIT (seekoff, _IO_wstr_seekoff), + JUMP_INIT (seekpos, _IO_default_seekpos), + JUMP_INIT (setbuf, _IO_default_setbuf), + JUMP_INIT (sync, (_IO_sync_t) _IO_wmem_sync), + JUMP_INIT (doallocate, INTUSE(_IO_wdefault_doallocate)), + JUMP_INIT (read, _IO_default_read), + JUMP_INIT (write, _IO_default_write), + JUMP_INIT (seek, _IO_default_seek), + JUMP_INIT (close, _IO_default_close), + JUMP_INIT (stat, _IO_default_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; + +/* Open a stream that writes into a malloc'd buffer that is expanded as + necessary. *BUFLOC and *SIZELOC are updated with the buffer's location + and the number of characters written on fflush or fclose. */ +_IO_FILE * +open_memstream (bufloc, sizeloc) + char **bufloc; + _IO_size_t *sizeloc; +{ + struct locked_FILE + { + struct _IO_FILE_memstream fp; +#ifdef _IO_MTSAFE_IO + _IO_lock_t lock; +#endif + struct _IO_wide_data wd; + } *new_f; + char *buf; + + new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); + if (new_f == NULL) + return NULL; +#ifdef _IO_MTSAFE_IO + new_f->fp._sf._sbf._f._lock = &new_f->lock; +#endif + + buf = malloc (_IO_BUFSIZ); + if (buf == NULL) + return NULL; + _IO_no_init (&new_f->fp._sf._sbf._f, 0, 0, &new_f->wd, &_IO_wmem_jumps); + _IO_JUMPS ((struct _IO_FILE_plus *) &new_f->fp._sf._sbf) = &_IO_mem_jumps; + INTUSE(_IO_str_init_static) (&new_f->fp._sf, buf, _IO_BUFSIZ, buf); + new_f->fp._sf._sbf._f._flags &= ~_IO_USER_BUF; + new_f->fp._sf._s._allocate_buffer = (_IO_alloc_type) malloc; + new_f->fp._sf._s._free_buffer = (_IO_free_type) free; + + new_f->fp.bufloc = bufloc; + new_f->fp.sizeloc = sizeloc; + + return (_IO_FILE *) &new_f->fp._sf._sbf; +} +libc_hidden_def (open_memstream) + + +static int +_IO_mem_sync (fp) + _IO_FILE* fp; +{ + struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp; + int res; + + res = _IO_default_sync (fp); + if (res < 0) + return res; + + if (fp->_IO_write_ptr == fp->_IO_write_end) + { + INTUSE(_IO_str_overflow) (fp, '\0'); + --fp->_IO_write_ptr; + } + else + *fp->_IO_write_ptr = '\0'; + + *mp->bufloc = fp->_IO_write_base; + *mp->sizeloc = fp->_IO_write_ptr - fp->_IO_write_base; + + return 0; +} + + +static void +_IO_mem_finish (fp, dummy) + _IO_FILE* fp; + int dummy; +{ + struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp; + + *mp->bufloc = (char *) realloc (fp->_IO_write_base, + fp->_IO_write_ptr - fp->_IO_write_base + 1); + if (*mp->bufloc != NULL) + { + (*mp->bufloc)[fp->_IO_write_ptr - fp->_IO_write_base] = '\0'; + *mp->sizeloc = fp->_IO_write_ptr - fp->_IO_write_base; + } + + fp->_IO_buf_base = NULL; + + INTUSE(_IO_default_finish) (fp, 0); +} + + +static int +_IO_wmem_sync (fp) + _IO_FILE* fp; +{ + struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp; + int res; + + res = _IO_default_sync (fp); + if (res < 0) + return res; + + if (fp->_wide_data->_IO_write_ptr == fp->_wide_data->_IO_write_end) + { + _IO_wstr_overflow (fp, L'\0'); + --fp->_wide_data->_IO_write_ptr; + } + else + *fp->_wide_data->_IO_write_ptr = '\0'; + + *mp->bufloc = (char *) fp->_wide_data->_IO_write_base; + *mp->sizeloc = (fp->_wide_data->_IO_write_ptr + - fp->_wide_data->_IO_write_base); + + return 0; +} + + +static void +_IO_wmem_finish (fp, dummy) + _IO_FILE* fp; + int dummy; +{ + struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp; + + *mp->bufloc = (char *) realloc (fp->_wide_data->_IO_write_base, + (fp->_wide_data->_IO_write_ptr + - fp->_wide_data->_IO_write_base + 1) + * sizeof (wchar_t)); + if (*mp->bufloc != NULL) + { + ((wchar_t *) (*mp->bufloc))[fp->_wide_data->_IO_write_ptr + - fp->_wide_data->_IO_write_base] = '\0'; + *mp->sizeloc = (fp->_wide_data->_IO_write_ptr + - fp->_wide_data->_IO_write_base); + } + + fp->_wide_data->_IO_buf_base = NULL; + + INTUSE(_IO_default_finish) (fp, 0); +} diff --git a/src/kernel/libroot/posix/glibc/libio/obprintf.c b/src/kernel/libroot/posix/glibc/libio/obprintf.c new file mode 100644 index 0000000000..b4625ae9ea --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/obprintf.c @@ -0,0 +1,191 @@ +/* Print output of stream to given obstack. + Copyright (C) 1996,1997,1999,2000,2001,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1996. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "libioP.h" +#include +#include +#include +#include +#include +#include +#include + + +struct _IO_obstack_file +{ + struct _IO_FILE_plus file; + struct obstack *obstack; +}; + + +static int +_IO_obstack_overflow (_IO_FILE *fp, int c) +{ + struct obstack *obstack = ((struct _IO_obstack_file *) fp)->obstack; + int size; + + /* Make room for another character. This might as well allocate a + new chunk a memory and moves the old contents over. */ + assert (c != EOF); + obstack_1grow (obstack, c); + + /* Setup the buffer pointers again. */ + fp->_IO_write_base = obstack_base (obstack); + fp->_IO_write_ptr = obstack_next_free (obstack); + size = obstack_room (obstack); + fp->_IO_write_end = fp->_IO_write_ptr + size; + /* Now allocate the rest of the current chunk. */ + obstack_blank_fast (obstack, size); + + return c; +} + + +static _IO_size_t +_IO_obstack_xsputn (_IO_FILE *fp, const void *data, _IO_size_t n) +{ + struct obstack *obstack = ((struct _IO_obstack_file *) fp)->obstack; + + if (fp->_IO_write_ptr + n > fp->_IO_write_end) + { + int size; + + /* We need some more memory. First shrink the buffer to the + space we really currently need. */ + obstack_blank_fast (obstack, fp->_IO_write_ptr - fp->_IO_write_end); + + /* Now grow for N bytes, and put the data there. */ + obstack_grow (obstack, data, n); + + /* Setup the buffer pointers again. */ + fp->_IO_write_base = obstack_base (obstack); + fp->_IO_write_ptr = obstack_next_free (obstack); + size = obstack_room (obstack); + fp->_IO_write_end = fp->_IO_write_ptr + size; + /* Now allocate the rest of the current chunk. */ + obstack_blank_fast (obstack, size); + } + else + fp->_IO_write_ptr = __mempcpy (fp->_IO_write_ptr, data, n); + + return n; +} + + +/* the jump table. */ +static struct _IO_jump_t _IO_obstack_jumps = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, NULL), + JUMP_INIT(overflow, _IO_obstack_overflow), + JUMP_INIT(underflow, NULL), + JUMP_INIT(uflow, NULL), + JUMP_INIT(pbackfail, NULL), + JUMP_INIT(xsputn, _IO_obstack_xsputn), + JUMP_INIT(xsgetn, NULL), + JUMP_INIT(seekoff, NULL), + JUMP_INIT(seekpos, NULL), + JUMP_INIT(setbuf, NULL), + JUMP_INIT(sync, NULL), + JUMP_INIT(doallocate, NULL), + JUMP_INIT(read, NULL), + JUMP_INIT(write, NULL), + JUMP_INIT(seek, NULL), + JUMP_INIT(close, NULL), + JUMP_INIT(stat, NULL), + JUMP_INIT(showmanyc, NULL), + JUMP_INIT(imbue, NULL) +}; + + +int +_IO_obstack_vprintf (struct obstack *obstack, const char *format, va_list args) +{ + struct obstack_FILE + { + struct _IO_obstack_file ofile; + } new_f; + int result; + int size; + int room; + +#ifdef _IO_MTSAFE_IO + new_f.ofile.file.file._lock = NULL; +#endif + + _IO_no_init (&new_f.ofile.file.file, _IO_USER_LOCK, -1, NULL, NULL); + _IO_JUMPS (&new_f.ofile.file) = &_IO_obstack_jumps; + room = obstack_room (obstack); + size = obstack_object_size (obstack) + room; + if (size == 0) + { + /* We have to handle the allocation a bit different since the + `_IO_str_init_static' function would handle a size of zero + different from what we expect. */ + + /* Get more memory. */ + obstack_make_room (obstack, 64); + + /* Recompute how much room we have. */ + room = obstack_room (obstack); + size = room; + + assert (size != 0); + } + + INTUSE(_IO_str_init_static) ((struct _IO_strfile_ *) &new_f.ofile, + obstack_base (obstack), + size, obstack_next_free (obstack)); + /* Now allocate the rest of the current chunk. */ + assert (size == (new_f.ofile.file.file._IO_write_end + - new_f.ofile.file.file._IO_write_base)); + assert (new_f.ofile.file.file._IO_write_ptr + == (new_f.ofile.file.file._IO_write_base + + obstack_object_size (obstack))); + obstack_blank_fast (obstack, room); + + new_f.ofile.obstack = obstack; + + result = INTUSE(_IO_vfprintf) (&new_f.ofile.file.file, format, args); + + /* Shrink the buffer to the space we really currently need. */ + obstack_blank_fast (obstack, (new_f.ofile.file.file._IO_write_ptr + - new_f.ofile.file.file._IO_write_end)); + + return result; +} +#ifdef weak_alias +weak_alias (_IO_obstack_vprintf, obstack_vprintf) +#endif + + +int +_IO_obstack_printf (struct obstack *obstack, const char *format, ...) +{ + int result; + va_list ap; + va_start (ap, format); + result = _IO_obstack_vprintf (obstack, format, ap); + va_end (ap); + return result; +} +#ifdef weak_alias +weak_alias (_IO_obstack_printf, obstack_printf) +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/oldfileops.c b/src/kernel/libroot/posix/glibc/libio/oldfileops.c new file mode 100644 index 0000000000..2efbadb44e --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/oldfileops.c @@ -0,0 +1,793 @@ +/* Copyright (C) 1993,95,97,98,99,2000,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Per Bothner . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +/* This is a compatibility file. If we don't build the libc with + versioning don't compile this file. */ +#include +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + +#ifndef _POSIX_SOURCE +# define _POSIX_SOURCE +#endif +#define _IO_USE_OLD_IO_FILE +#include "libioP.h" +#include +#include +#include +#include +#include +#ifdef __STDC__ +#include +#endif +#ifndef errno +extern int errno; +#endif +#ifndef __set_errno +# define __set_errno(Val) errno = (Val) +#endif + + +#ifdef _LIBC +# define open(Name, Flags, Prot) __open (Name, Flags, Prot) +# define close(FD) __close (FD) +# define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence) +# define read(FD, Buf, NBytes) __read (FD, Buf, NBytes) +# define write(FD, Buf, NBytes) __write (FD, Buf, NBytes) +#endif + +/* An fstream can be in at most one of put mode, get mode, or putback mode. + Putback mode is a variant of get mode. + + In a filebuf, there is only one current position, instead of two + separate get and put pointers. In get mode, the current position + is that of gptr(); in put mode that of pptr(). + + The position in the buffer that corresponds to the position + in external file system is normally _IO_read_end, except in putback + mode, when it is _IO_save_end. + If the field _fb._offset is >= 0, it gives the offset in + the file as a whole corresponding to eGptr(). (?) + + PUT MODE: + If a filebuf is in put mode, then all of _IO_read_ptr, _IO_read_end, + and _IO_read_base are equal to each other. These are usually equal + to _IO_buf_base, though not necessarily if we have switched from + get mode to put mode. (The reason is to maintain the invariant + that _IO_read_end corresponds to the external file position.) + _IO_write_base is non-NULL and usually equal to _IO_base_base. + We also have _IO_write_end == _IO_buf_end, but only in fully buffered mode. + The un-flushed character are those between _IO_write_base and _IO_write_ptr. + + GET MODE: + If a filebuf is in get or putback mode, eback() != egptr(). + In get mode, the unread characters are between gptr() and egptr(). + The OS file position corresponds to that of egptr(). + + PUTBACK MODE: + Putback mode is used to remember "excess" characters that have + been sputbackc'd in a separate putback buffer. + In putback mode, the get buffer points to the special putback buffer. + The unread characters are the characters between gptr() and egptr() + in the putback buffer, as well as the area between save_gptr() + and save_egptr(), which point into the original reserve buffer. + (The pointers save_gptr() and save_egptr() are the values + of gptr() and egptr() at the time putback mode was entered.) + The OS position corresponds to that of save_egptr(). + + LINE BUFFERED OUTPUT: + During line buffered output, _IO_write_base==base() && epptr()==base(). + However, ptr() may be anywhere between base() and ebuf(). + This forces a call to filebuf::overflow(int C) on every put. + If there is more space in the buffer, and C is not a '\n', + then C is inserted, and pptr() incremented. + + UNBUFFERED STREAMS: + If a filebuf is unbuffered(), the _shortbuf[1] is used as the buffer. +*/ + +#define CLOSED_FILEBUF_FLAGS \ + (_IO_IS_FILEBUF+_IO_NO_READS+_IO_NO_WRITES+_IO_TIED_PUT_GET) + + +void +_IO_old_file_init (fp) + struct _IO_FILE_plus *fp; +{ + /* POSIX.1 allows another file handle to be used to change the position + of our file descriptor. Hence we actually don't know the actual + position before we do the first fseek (and until a following fflush). */ + fp->file._old_offset = _IO_pos_BAD; + fp->file._IO_file_flags |= CLOSED_FILEBUF_FLAGS; + + INTUSE(_IO_link_in) (fp); + fp->file._vtable_offset = ((int) sizeof (struct _IO_FILE) + - (int) sizeof (struct _IO_FILE_complete)); + fp->file._fileno = -1; +} + +int +_IO_old_file_close_it (fp) + _IO_FILE *fp; +{ + int write_status, close_status; + if (!_IO_file_is_open (fp)) + return EOF; + + write_status = _IO_old_do_flush (fp); + + INTUSE(_IO_unsave_markers) (fp); + + close_status = _IO_SYSCLOSE (fp); + + /* Free buffer. */ + INTUSE(_IO_setb) (fp, NULL, NULL, 0); + _IO_setg (fp, NULL, NULL, NULL); + _IO_setp (fp, NULL, NULL); + + INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp); + fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS; + fp->_fileno = -1; + fp->_old_offset = _IO_pos_BAD; + + return close_status ? close_status : write_status; +} + +void +_IO_old_file_finish (fp, dummy) + _IO_FILE *fp; + int dummy; +{ + if (_IO_file_is_open (fp)) + { + _IO_old_do_flush (fp); + if (!(fp->_flags & _IO_DELETE_DONT_CLOSE)) + _IO_SYSCLOSE (fp); + } + INTUSE(_IO_default_finish) (fp, 0); +} + +_IO_FILE * +_IO_old_file_fopen (fp, filename, mode) + _IO_FILE *fp; + const char *filename; + const char *mode; +{ + int oflags = 0, omode; + int read_write, fdesc; + int oprot = 0666; + if (_IO_file_is_open (fp)) + return 0; + switch (*mode++) + { + case 'r': + omode = O_RDONLY; + read_write = _IO_NO_WRITES; + break; + case 'w': + omode = O_WRONLY; + oflags = O_CREAT|O_TRUNC; + read_write = _IO_NO_READS; + break; + case 'a': + omode = O_WRONLY; + oflags = O_CREAT|O_APPEND; + read_write = _IO_NO_READS|_IO_IS_APPENDING; + break; + default: + __set_errno (EINVAL); + return NULL; + } + if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+')) + { + omode = O_RDWR; + read_write &= _IO_IS_APPENDING; + } + fdesc = open (filename, omode|oflags, oprot); + if (fdesc < 0) + return NULL; + fp->_fileno = fdesc; + _IO_mask_flags (fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); + if (read_write & _IO_IS_APPENDING) + if (_IO_SEEKOFF (fp, (_IO_off_t)0, _IO_seek_end, _IOS_INPUT|_IOS_OUTPUT) + == _IO_pos_BAD && errno != ESPIPE) + return NULL; + INTUSE(_IO_link_in) ((struct _IO_FILE_plus *) fp); + return fp; +} + +_IO_FILE * +_IO_old_file_attach (fp, fd) + _IO_FILE *fp; + int fd; +{ + if (_IO_file_is_open (fp)) + return NULL; + fp->_fileno = fd; + fp->_flags &= ~(_IO_NO_READS+_IO_NO_WRITES); + fp->_flags |= _IO_DELETE_DONT_CLOSE; + /* Get the current position of the file. */ + /* We have to do that since that may be junk. */ + fp->_old_offset = _IO_pos_BAD; + if (_IO_SEEKOFF (fp, (_IO_off_t)0, _IO_seek_cur, _IOS_INPUT|_IOS_OUTPUT) + == _IO_pos_BAD && errno != ESPIPE) + return NULL; + return fp; +} + +_IO_FILE * +_IO_old_file_setbuf (fp, p, len) + _IO_FILE *fp; + char *p; + _IO_ssize_t len; +{ + if (_IO_default_setbuf (fp, p, len) == NULL) + return NULL; + + fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end + = fp->_IO_buf_base; + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); + + return fp; +} + +static int old_do_write __P ((_IO_FILE *, const char *, _IO_size_t)); + +/* Write TO_DO bytes from DATA to FP. + Then mark FP as having empty buffers. */ + +int +_IO_old_do_write (fp, data, to_do) + _IO_FILE *fp; + const char *data; + _IO_size_t to_do; +{ + return (to_do == 0 || (_IO_size_t) old_do_write (fp, data, to_do) == to_do) + ? 0 : EOF; +} + +static +int +old_do_write (fp, data, to_do) + _IO_FILE *fp; + const char *data; + _IO_size_t to_do; +{ + _IO_size_t count; + if (fp->_flags & _IO_IS_APPENDING) + /* On a system without a proper O_APPEND implementation, + you would need to sys_seek(0, SEEK_END) here, but is + is not needed nor desirable for Unix- or Posix-like systems. + Instead, just indicate that offset (before and after) is + unpredictable. */ + fp->_old_offset = _IO_pos_BAD; + else if (fp->_IO_read_end != fp->_IO_write_base) + { + _IO_off_t new_pos + = _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1); + if (new_pos == _IO_pos_BAD) + return 0; + fp->_old_offset = new_pos; + } + count = _IO_SYSWRITE (fp, data, to_do); + if (fp->_cur_column && count) + fp->_cur_column = INTUSE(_IO_adjust_column) (fp->_cur_column - 1, data, + count) + 1; + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); + fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base; + fp->_IO_write_end = ((fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED)) + ? fp->_IO_buf_base : fp->_IO_buf_end); + return count; +} + +int +_IO_old_file_underflow (fp) + _IO_FILE *fp; +{ + _IO_ssize_t count; +#if 0 + /* SysV does not make this test; take it out for compatibility */ + if (fp->_flags & _IO_EOF_SEEN) + return (EOF); +#endif + + if (fp->_flags & _IO_NO_READS) + { + fp->_flags |= _IO_ERR_SEEN; + __set_errno (EBADF); + return EOF; + } + if (fp->_IO_read_ptr < fp->_IO_read_end) + return *(unsigned char *) fp->_IO_read_ptr; + + if (fp->_IO_buf_base == NULL) + { + /* Maybe we already have a push back pointer. */ + if (fp->_IO_save_base != NULL) + { + free (fp->_IO_save_base); + fp->_flags &= ~_IO_IN_BACKUP; + } + INTUSE(_IO_doallocbuf) (fp); + } + + /* Flush all line buffered files before reading. */ + /* FIXME This can/should be moved to genops ?? */ + if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED)) + INTUSE(_IO_flush_all_linebuffered) (); + + INTUSE(_IO_switch_to_get_mode) (fp); + + /* This is very tricky. We have to adjust those + pointers before we call _IO_SYSREAD () since + we may longjump () out while waiting for + input. Those pointers may be screwed up. H.J. */ + fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base; + fp->_IO_read_end = fp->_IO_buf_base; + fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end + = fp->_IO_buf_base; + + count = _IO_SYSREAD (fp, fp->_IO_buf_base, + fp->_IO_buf_end - fp->_IO_buf_base); + if (count <= 0) + { + if (count == 0) + fp->_flags |= _IO_EOF_SEEN; + else + fp->_flags |= _IO_ERR_SEEN, count = 0; + } + fp->_IO_read_end += count; + if (count == 0) + return EOF; + if (fp->_old_offset != _IO_pos_BAD) + _IO_pos_adjust (fp->_old_offset, count); + return *(unsigned char *) fp->_IO_read_ptr; +} + +int +_IO_old_file_overflow (f, ch) + _IO_FILE *f; + int ch; +{ + if (f->_flags & _IO_NO_WRITES) /* SET ERROR */ + { + f->_flags |= _IO_ERR_SEEN; + __set_errno (EBADF); + return EOF; + } + /* If currently reading or no buffer allocated. */ + if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0) + { + /* Allocate a buffer if needed. */ + if (f->_IO_write_base == 0) + { + INTUSE(_IO_doallocbuf) (f); + _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base); + } + /* Otherwise must be currently reading. + If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end, + logically slide the buffer forwards one block (by setting the + read pointers to all point at the beginning of the block). This + makes room for subsequent output. + Otherwise, set the read pointers to _IO_read_end (leaving that + alone, so it can continue to correspond to the external position). */ + if (f->_IO_read_ptr == f->_IO_buf_end) + f->_IO_read_end = f->_IO_read_ptr = f->_IO_buf_base; + f->_IO_write_ptr = f->_IO_read_ptr; + f->_IO_write_base = f->_IO_write_ptr; + f->_IO_write_end = f->_IO_buf_end; + f->_IO_read_base = f->_IO_read_ptr = f->_IO_read_end; + + if (f->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED)) + f->_IO_write_end = f->_IO_write_ptr; + f->_flags |= _IO_CURRENTLY_PUTTING; + } + if (ch == EOF) + return _IO_old_do_flush (f); + if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */ + if (_IO_old_do_flush (f) == EOF) + return EOF; + *f->_IO_write_ptr++ = ch; + if ((f->_flags & _IO_UNBUFFERED) + || ((f->_flags & _IO_LINE_BUF) && ch == '\n')) + if (_IO_old_do_flush (f) == EOF) + return EOF; + return (unsigned char) ch; +} + +int +_IO_old_file_sync (fp) + _IO_FILE *fp; +{ + _IO_ssize_t delta; + int retval = 0; + + /* char* ptr = cur_ptr(); */ + if (fp->_IO_write_ptr > fp->_IO_write_base) + if (_IO_old_do_flush(fp)) return EOF; + delta = fp->_IO_read_ptr - fp->_IO_read_end; + if (delta != 0) + { +#ifdef TODO + if (_IO_in_backup (fp)) + delta -= eGptr () - Gbase (); +#endif + _IO_off_t new_pos = _IO_SYSSEEK (fp, delta, 1); + if (new_pos != (_IO_off_t) EOF) + fp->_IO_read_end = fp->_IO_read_ptr; +#ifdef ESPIPE + else if (errno == ESPIPE) + ; /* Ignore error from unseekable devices. */ +#endif + else + retval = EOF; + } + if (retval != EOF) + fp->_old_offset = _IO_pos_BAD; + /* FIXME: Cleanup - can this be shared? */ + /* setg(base(), ptr, ptr); */ + return retval; +} + +_IO_off64_t +_IO_old_file_seekoff (fp, offset, dir, mode) + _IO_FILE *fp; + _IO_off64_t offset; + int dir; + int mode; +{ + _IO_off_t result; + _IO_off64_t delta, new_offset; + long count; + /* POSIX.1 8.2.3.7 says that after a call the fflush() the file + offset of the underlying file must be exact. */ + int must_be_exact = (fp->_IO_read_base == fp->_IO_read_end + && fp->_IO_write_base == fp->_IO_write_ptr); + + if (mode == 0) + dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */ + + /* Flush unwritten characters. + (This may do an unneeded write if we seek within the buffer. + But to be able to switch to reading, we would need to set + egptr to ptr. That can't be done in the current design, + which assumes file_ptr() is eGptr. Anyway, since we probably + end up flushing when we close(), it doesn't make much difference.) + FIXME: simulate mem-papped files. */ + + if (fp->_IO_write_ptr > fp->_IO_write_base || _IO_in_put_mode (fp)) + if (INTUSE(_IO_switch_to_get_mode) (fp)) + return EOF; + + if (fp->_IO_buf_base == NULL) + { + /* It could be that we already have a pushback buffer. */ + if (fp->_IO_read_base != NULL) + { + free (fp->_IO_read_base); + fp->_flags &= ~_IO_IN_BACKUP; + } + INTUSE(_IO_doallocbuf) (fp); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); + } + + switch (dir) + { + case _IO_seek_cur: + /* Adjust for read-ahead (bytes is buffer). */ + offset -= fp->_IO_read_end - fp->_IO_read_ptr; + if (fp->_old_offset == _IO_pos_BAD) + goto dumb; + /* Make offset absolute, assuming current pointer is file_ptr(). */ + offset += fp->_old_offset; + + dir = _IO_seek_set; + break; + case _IO_seek_set: + break; + case _IO_seek_end: + { + struct _G_stat64 st; + if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode)) + { + offset += st.st_size; + dir = _IO_seek_set; + } + else + goto dumb; + } + } + /* At this point, dir==_IO_seek_set. */ + + /* If we are only interested in the current position we've found it now. */ + if (mode == 0) + return offset; + + /* If destination is within current buffer, optimize: */ + if (fp->_old_offset != _IO_pos_BAD && fp->_IO_read_base != NULL + && !_IO_in_backup (fp)) + { + /* Offset relative to start of main get area. */ + _IO_off_t rel_offset = (offset - fp->_old_offset + + (fp->_IO_read_end - fp->_IO_read_base)); + if (rel_offset >= 0) + { +#if 0 + if (_IO_in_backup (fp)) + _IO_switch_to_main_get_area (fp); +#endif + if (rel_offset <= fp->_IO_read_end - fp->_IO_read_base) + { + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + rel_offset, + fp->_IO_read_end); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + { + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + goto resync; + } + } +#ifdef TODO + /* If we have streammarkers, seek forward by reading ahead. */ + if (_IO_have_markers (fp)) + { + int to_skip = rel_offset + - (fp->_IO_read_ptr - fp->_IO_read_base); + if (ignore (to_skip) != to_skip) + goto dumb; + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + goto resync; + } +#endif + } +#ifdef TODO + if (rel_offset < 0 && rel_offset >= Bbase () - Bptr ()) + { + if (!_IO_in_backup (fp)) + _IO_switch_to_backup_area (fp); + gbump (fp->_IO_read_end + rel_offset - fp->_IO_read_ptr); + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + goto resync; + } +#endif + } + +#ifdef TODO + INTUSE(_IO_unsave_markers) (fp); +#endif + + if (fp->_flags & _IO_NO_READS) + goto dumb; + + /* Try to seek to a block boundary, to improve kernel page management. */ + new_offset = offset & ~(fp->_IO_buf_end - fp->_IO_buf_base - 1); + delta = offset - new_offset; + if (delta > fp->_IO_buf_end - fp->_IO_buf_base) + { + new_offset = offset; + delta = 0; + } + result = _IO_SYSSEEK (fp, new_offset, 0); + if (result < 0) + return EOF; + if (delta == 0) + count = 0; + else + { + count = _IO_SYSREAD (fp, fp->_IO_buf_base, + (must_be_exact + ? delta : fp->_IO_buf_end - fp->_IO_buf_base)); + if (count < delta) + { + /* We weren't allowed to read, but try to seek the remainder. */ + offset = count == EOF ? delta : delta-count; + dir = _IO_seek_cur; + goto dumb; + } + } + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + delta, + fp->_IO_buf_base + count); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + fp->_old_offset = result + count; + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + return offset; + dumb: + + INTUSE(_IO_unsave_markers) (fp); + result = _IO_SYSSEEK (fp, offset, dir); + if (result != EOF) + { + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + fp->_old_offset = result; + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + } + return result; + +resync: + /* We need to do it since it is possible that the file offset in + the kernel may be changed behind our back. It may happen when + we fopen a file and then do a fork. One process may access the + the file and the kernel file offset will be changed. */ + if (fp->_old_offset >= 0) + _IO_SYSSEEK (fp, fp->_old_offset, 0); + + return offset; +} + +_IO_ssize_t +_IO_old_file_write (f, data, n) + _IO_FILE *f; + const void *data; + _IO_ssize_t n; +{ + _IO_ssize_t to_do = n; + while (to_do > 0) + { + _IO_ssize_t count = write (f->_fileno, data, to_do); + if (count == EOF) + { + f->_flags |= _IO_ERR_SEEN; + break; + } + to_do -= count; + data = (void *) ((char *) data + count); + } + n -= to_do; + if (f->_old_offset >= 0) + f->_old_offset += n; + return n; +} + +_IO_size_t +_IO_old_file_xsputn (f, data, n) + _IO_FILE *f; + const void *data; + _IO_size_t n; +{ + register const char *s = (char *) data; + _IO_size_t to_do = n; + int must_flush = 0; + _IO_size_t count; + + if (n <= 0) + return 0; + /* This is an optimized implementation. + If the amount to be written straddles a block boundary + (or the filebuf is unbuffered), use sys_write directly. */ + + /* First figure out how much space is available in the buffer. */ + count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */ + if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING)) + { + count = f->_IO_buf_end - f->_IO_write_ptr; + if (count >= n) + { + register const char *p; + for (p = s + n; p > s; ) + { + if (*--p == '\n') + { + count = p - s + 1; + must_flush = 1; + break; + } + } + } + } + /* Then fill the buffer. */ + if (count > 0) + { + if (count > to_do) + count = to_do; + if (count > 20) + { +#ifdef _LIBC + f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count); +#else + memcpy (f->_IO_write_ptr, s, count); + f->_IO_write_ptr += count; +#endif + s += count; + } + else + { + register char *p = f->_IO_write_ptr; + register int i = (int) count; + while (--i >= 0) + *p++ = *s++; + f->_IO_write_ptr = p; + } + to_do -= count; + } + if (to_do + must_flush > 0) + { + _IO_size_t block_size, do_write; + /* Next flush the (full) buffer. */ + if (__overflow (f, EOF) == EOF) + return n - to_do; + + /* Try to maintain alignment: write a whole number of blocks. + dont_write is what gets left over. */ + block_size = f->_IO_buf_end - f->_IO_buf_base; + do_write = to_do - (block_size >= 128 ? to_do % block_size : 0); + + if (do_write) + { + count = old_do_write (f, s, do_write); + to_do -= count; + if (count < do_write) + return n - to_do; + } + + /* Now write out the remainder. Normally, this will fit in the + buffer, but it's somewhat messier for line-buffered files, + so we let _IO_default_xsputn handle the general case. */ + if (to_do) + to_do -= INTUSE(_IO_default_xsputn) (f, s+do_write, to_do); + } + return n - to_do; +} + + +struct _IO_jump_t _IO_old_file_jumps = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_old_file_finish), + JUMP_INIT(overflow, _IO_old_file_overflow), + JUMP_INIT(underflow, _IO_old_file_underflow), + JUMP_INIT(uflow, INTUSE(_IO_default_uflow)), + JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)), + JUMP_INIT(xsputn, _IO_old_file_xsputn), + JUMP_INIT(xsgetn, INTUSE(_IO_default_xsgetn)), + JUMP_INIT(seekoff, _IO_old_file_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_old_file_setbuf), + JUMP_INIT(sync, _IO_old_file_sync), + JUMP_INIT(doallocate, INTUSE(_IO_file_doallocate)), + JUMP_INIT(read, INTUSE(_IO_file_read)), + JUMP_INIT(write, _IO_old_file_write), + JUMP_INIT(seek, INTUSE(_IO_file_seek)), + JUMP_INIT(close, INTUSE(_IO_file_close)), + JUMP_INIT(stat, INTUSE(_IO_file_stat)) +}; + +compat_symbol (libc, _IO_old_do_write, _IO_do_write, GLIBC_2_0); +compat_symbol (libc, _IO_old_file_attach, _IO_file_attach, GLIBC_2_0); +compat_symbol (libc, _IO_old_file_close_it, _IO_file_close_it, GLIBC_2_0); +compat_symbol (libc, _IO_old_file_finish, _IO_file_finish, GLIBC_2_0); +compat_symbol (libc, _IO_old_file_fopen, _IO_file_fopen, GLIBC_2_0); +compat_symbol (libc, _IO_old_file_init, _IO_file_init, GLIBC_2_0); +compat_symbol (libc, _IO_old_file_setbuf, _IO_file_setbuf, GLIBC_2_0); +compat_symbol (libc, _IO_old_file_sync, _IO_file_sync, GLIBC_2_0); +compat_symbol (libc, _IO_old_file_overflow, _IO_file_overflow, GLIBC_2_0); +compat_symbol (libc, _IO_old_file_seekoff, _IO_file_seekoff, GLIBC_2_0); +compat_symbol (libc, _IO_old_file_underflow, _IO_file_underflow, GLIBC_2_0); +compat_symbol (libc, _IO_old_file_write, _IO_file_write, GLIBC_2_0); +compat_symbol (libc, _IO_old_file_xsputn, _IO_file_xsputn, GLIBC_2_0); + +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/oldiofclose.c b/src/kernel/libroot/posix/glibc/libio/oldiofclose.c new file mode 100644 index 0000000000..18db7b814f --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/oldiofclose.c @@ -0,0 +1,79 @@ +/* Copyright (C) 1993, 1995, 1997-2001, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + +#define _IO_USE_OLD_IO_FILE +#include "libioP.h" +#ifdef __STDC__ +#include +#endif + +int +_IO_old_fclose (fp) + _IO_FILE *fp; +{ + int status; + + CHECK_FILE(fp, EOF); + + /* We desperately try to help programs which are using streams in a + strange way and mix old and new functions. Detect new streams + here. */ + if (fp->_vtable_offset == 0) + return _IO_new_fclose (fp); + + /* First unlink the stream. */ + if (fp->_IO_file_flags & _IO_IS_FILEBUF) + INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp); + + _IO_cleanup_region_start ((void (*) (void *)) _IO_funlockfile, fp); + _IO_flockfile (fp); + if (fp->_IO_file_flags & _IO_IS_FILEBUF) + status = _IO_old_file_close_it (fp); + else + status = fp->_flags & _IO_ERR_SEEN ? -1 : 0; + _IO_FINISH (fp); + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + if (_IO_have_backup (fp)) + INTUSE(_IO_free_backup_area) (fp); + if (fp != _IO_stdin && fp != _IO_stdout && fp != _IO_stderr) + { + fp->_IO_file_flags = 0; + free(fp); + } + + return status; +} + +strong_alias (_IO_old_fclose, __old_fclose) +compat_symbol (libc, _IO_old_fclose, _IO_fclose, GLIBC_2_0); +compat_symbol (libc, __old_fclose, fclose, GLIBC_2_0); + +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/oldiofdopen.c b/src/kernel/libroot/posix/glibc/libio/oldiofdopen.c new file mode 100644 index 0000000000..9015504970 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/oldiofdopen.c @@ -0,0 +1,142 @@ +/* Copyright (C) 1993,94,97,99,2000,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + +#define _IO_USE_OLD_IO_FILE +#ifdef __STDC__ +# include +#endif +#include "libioP.h" +#include + +#ifndef _IO_fcntl +# define _IO_fcntl __fcntl +#endif + +_IO_FILE * +_IO_old_fdopen (fd, mode) + int fd; + const char *mode; +{ + int read_write; + int posix_mode = 0; + struct locked_FILE + { + struct _IO_FILE_plus fp; +#ifdef _IO_MTSAFE_IO + _IO_lock_t lock; +#endif + } *new_f; + int fd_flags; + + switch (*mode++) + { + case 'r': + read_write = _IO_NO_WRITES; + break; + case 'w': + read_write = _IO_NO_READS; + break; + case 'a': + posix_mode = O_APPEND; + read_write = _IO_NO_READS|_IO_IS_APPENDING; + break; + default: + MAYBE_SET_EINVAL; + return NULL; + } + if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+')) + read_write &= _IO_IS_APPENDING; +#ifdef F_GETFL + fd_flags = _IO_fcntl (fd, F_GETFL); +#ifndef O_ACCMODE +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) +#endif + if (fd_flags == -1 + || ((fd_flags & O_ACCMODE) == O_RDONLY && !(read_write & _IO_NO_WRITES)) + || ((fd_flags & O_ACCMODE) == O_WRONLY && !(read_write & _IO_NO_READS))) + return NULL; + + /* The May 93 draft of P1003.4/D14.1 (redesignated as 1003.1b) + [System Application Program Interface (API) Amendment 1: + Realtime Extensions], Rationale B.8.3.3 + Open a Stream on a File Descriptor says: + + Although not explicitly required by POSIX.1, a good + implementation of append ("a") mode would cause the + O_APPEND flag to be set. + + (Historical implementations [such as Solaris2] do a one-time + seek in fdopen.) + + However, we do not turn O_APPEND off if the mode is "w" (even + though that would seem consistent) because that would be more + likely to break historical programs. + */ + if ((posix_mode & O_APPEND) && !(fd_flags & O_APPEND)) + { +#ifdef F_SETFL + if (_IO_fcntl (fd, F_SETFL, fd_flags | O_APPEND) == -1) +#endif + return NULL; + } +#endif + + new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); + if (new_f == NULL) + return NULL; +#ifdef _IO_MTSAFE_IO + new_f->fp.file._lock = &new_f->lock; +#endif + INTUSE(_IO_init) (&new_f->fp.file, 0); + _IO_JUMPS (&new_f->fp) = &_IO_old_file_jumps; + _IO_old_file_init (&new_f->fp); +#if !_IO_UNIFIED_JUMPTABLES + new_f->fp.vtable = NULL; +#endif + if (_IO_old_file_attach (&new_f->fp.file, fd) == NULL) + { + INTUSE(_IO_un_link) (&new_f->fp); + free (new_f); + return NULL; + } + new_f->fp.file._flags &= ~_IO_DELETE_DONT_CLOSE; + + new_f->fp.file._IO_file_flags = + _IO_mask_flags (&new_f->fp.file, read_write, + _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); + + return (_IO_FILE *) &new_f->fp; +} + +strong_alias (_IO_old_fdopen, __old_fdopen) +compat_symbol (libc, _IO_old_fdopen, _IO_fdopen, GLIBC_2_0); +compat_symbol (libc, __old_fdopen, fdopen, GLIBC_2_0); + +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/oldiofgetpos.c b/src/kernel/libroot/posix/glibc/libio/oldiofgetpos.c new file mode 100644 index 0000000000..596c40599f --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/oldiofgetpos.c @@ -0,0 +1,68 @@ +/* Copyright (C) 1993,95,96,97,98,99,2000, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +#include +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) + +int +_IO_old_fgetpos (fp, posp) + _IO_FILE *fp; + _IO_fpos_t *posp; +{ + _IO_off_t pos; + CHECK_FILE (fp, EOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0); + if (_IO_in_backup (fp)) + pos -= fp->_IO_save_end - fp->_IO_save_base; + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + if (pos == _IO_pos_BAD) + { + /* ANSI explicitly requires setting errno to a positive value on + failure. */ +#ifdef EIO + if (errno == 0) + __set_errno (EIO); +#endif + return EOF; + } + posp->__pos = pos; + return 0; +} + +#ifdef weak_alias +compat_symbol (libc, _IO_old_fgetpos, _IO_fgetpos, GLIBC_2_0); +strong_alias (_IO_old_fgetpos, __old_fgetpos) +compat_symbol (libc, __old_fgetpos, fgetpos, GLIBC_2_0); +#endif + +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/oldiofgetpos64.c b/src/kernel/libroot/posix/glibc/libio/oldiofgetpos64.c new file mode 100644 index 0000000000..4a38c38e86 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/oldiofgetpos64.c @@ -0,0 +1,73 @@ +/* Copyright (C) 1993,95,96,97,98,99,2000, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +#include +#if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_2) + +int +_IO_old_fgetpos64 (fp, posp) + _IO_FILE *fp; + _IO_fpos64_t *posp; +{ +#ifdef _G_LSEEK64 + _IO_off64_t pos; + CHECK_FILE (fp, EOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0); + if (_IO_in_backup (fp)) + pos -= fp->_IO_save_end - fp->_IO_save_base; + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + if (pos == _IO_pos_BAD) + { + /* ANSI explicitly requires setting errno to a positive value on + failure. */ +#ifdef EIO + if (errno == 0) + __set_errno (EIO); +#endif + return EOF; + } + posp->__pos = pos; + return 0; +#else + __set_errno (ENOSYS); + return EOF; +#endif +} + +#ifdef weak_alias +compat_symbol (libc, _IO_old_fgetpos64, _IO_fgetpos64, GLIBC_2_1); +strong_alias (_IO_old_fgetpos64, __old_fgetpos64) +compat_symbol (libc, __old_fgetpos64, fgetpos64, GLIBC_2_1); +#endif + +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/oldiofopen.c b/src/kernel/libroot/posix/glibc/libio/oldiofopen.c new file mode 100644 index 0000000000..67a9eba6a6 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/oldiofopen.c @@ -0,0 +1,72 @@ +/* Copyright (C) 1993, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + +#define _IO_USE_OLD_IO_FILE +#include "libioP.h" +#ifdef __STDC__ +#include +#endif + + +_IO_FILE * +_IO_old_fopen (filename, mode) + const char *filename; + const char *mode; +{ + struct locked_FILE + { + struct _IO_FILE_plus fp; +#ifdef _IO_MTSAFE_IO + _IO_lock_t lock; +#endif + } *new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); + + if (new_f == NULL) + return NULL; +#ifdef _IO_MTSAFE_IO + new_f->fp.file._lock = &new_f->lock; +#endif + INTUSE(_IO_init) (&new_f->fp.file, 0); + _IO_JUMPS (&new_f->fp) = &_IO_old_file_jumps; + _IO_old_file_init (&new_f->fp); +#if !_IO_UNIFIED_JUMPTABLES + new_f->fp.vtable = NULL; +#endif + if (_IO_old_file_fopen ((_IO_FILE *) &new_f->fp, filename, mode) != NULL) + return (_IO_FILE *) &new_f->fp; + INTUSE(_IO_un_link) (&new_f->fp); + free (new_f); + return NULL; +} + +strong_alias (_IO_old_fopen, __old_fopen) +compat_symbol (libc, _IO_old_fopen, _IO_fopen, GLIBC_2_0); +compat_symbol (libc, __old_fopen, fopen, GLIBC_2_0); +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/oldiofsetpos.c b/src/kernel/libroot/posix/glibc/libio/oldiofsetpos.c new file mode 100644 index 0000000000..ce3bb12363 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/oldiofsetpos.c @@ -0,0 +1,66 @@ +/* Copyright (C) 1993,95,97,98,99,2000,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include +#include + +#include +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) +int +_IO_old_fsetpos (fp, posp) + _IO_FILE *fp; + const _IO_fpos_t *posp; +{ + int result; + CHECK_FILE (fp, EOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + if (_IO_seekpos_unlocked (fp, posp->__pos, _IOS_INPUT|_IOS_OUTPUT) + == _IO_pos_BAD) + { + /* ANSI explicitly requires setting errno to a positive value on + failure. */ +#ifdef EIO + if (errno == 0) + __set_errno (EIO); +#endif + result = EOF; + } + else + result = 0; + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} + +#ifdef weak_alias +compat_symbol (libc, _IO_old_fsetpos, _IO_fsetpos, GLIBC_2_0); +strong_alias (_IO_old_fsetpos, __old_fsetpos) +compat_symbol (libc, __old_fsetpos, fsetpos, GLIBC_2_0); +#endif + +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/oldiofsetpos64.c b/src/kernel/libroot/posix/glibc/libio/oldiofsetpos64.c new file mode 100644 index 0000000000..834f154c21 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/oldiofsetpos64.c @@ -0,0 +1,72 @@ +/* Copyright (C) 1993,95,97,98,99,2000,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include +#include + +#include +#if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_2) + +int +_IO_old_fsetpos64 (fp, posp) + _IO_FILE *fp; + const _IO_fpos64_t *posp; +{ +#ifdef _G_LSEEK64 + int result; + CHECK_FILE (fp, EOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + if (_IO_seekpos_unlocked (fp, posp->__pos, _IOS_INPUT|_IOS_OUTPUT) + == _IO_pos_BAD) + { + /* ANSI explicitly requires setting errno to a positive value on + failure. */ +#ifdef EIO + if (errno == 0) + __set_errno (EIO); +#endif + result = EOF; + } + else + result = 0; + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +#else + __set_errno (ENOSYS); + return EOF; +#endif +} + +#ifdef weak_alias +compat_symbol (libc, _IO_old_fsetpos64, _IO_fsetpos64, GLIBC_2_1); +strong_alias (_IO_old_fsetpos64, __old_fsetpos64) +compat_symbol (libc, __old_fsetpos64, fsetpos64, GLIBC_2_1); +#endif + +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/oldiopopen.c b/src/kernel/libroot/posix/glibc/libio/oldiopopen.c new file mode 100644 index 0000000000..b818af4180 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/oldiopopen.c @@ -0,0 +1,316 @@ +/* Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Per Bothner . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#define _IO_USE_OLD_IO_FILE +#ifndef _POSIX_SOURCE +# define _POSIX_SOURCE +#endif +#include "libioP.h" +#if _IO_HAVE_SYS_WAIT +#include +#include +#ifdef __STDC__ +#include +#endif +#ifdef _LIBC +# include +#endif +#include +#include + +#ifndef _IO_fork +#ifdef _LIBC +#define _IO_fork __vfork +#else +#define _IO_fork vfork /* defined in libiberty, if needed */ +#endif +extern _IO_pid_t _IO_fork __P ((void)); +#endif + +#endif /* _IO_HAVE_SYS_WAIT */ + +#include +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + +#ifndef _IO_pipe +#ifdef _LIBC +#define _IO_pipe __pipe +#else +#define _IO_pipe pipe +#endif +extern int _IO_pipe __P ((int des[2])); +#endif + +#ifndef _IO_dup2 +#ifdef _LIBC +#define _IO_dup2 __dup2 +#else +#define _IO_dup2 dup2 +#endif +extern int _IO_dup2 __P ((int fd, int fd2)); +#endif + +#ifndef _IO_waitpid +#ifdef _LIBC +#define _IO_waitpid __waitpid +#else +#define _IO_waitpid waitpid +#endif +#endif + +#ifndef _IO_execl +#define _IO_execl execl +#endif +#ifndef _IO__exit +#define _IO__exit _exit +#endif + +#ifndef _IO_close +#ifdef _LIBC +#define _IO_close __close +#else +#define _IO_close close +#endif +#endif + +struct _IO_proc_file +{ + struct _IO_FILE_plus file; + /* Following fields must match those in class procbuf (procbuf.h) */ + _IO_pid_t pid; + struct _IO_proc_file *next; +}; +typedef struct _IO_proc_file _IO_proc_file; + +static struct _IO_proc_file *old_proc_file_chain; + +#ifdef _IO_MTSAFE_IO +static _IO_lock_t proc_file_chain_lock = _IO_lock_initializer; + +static void +unlock (void *not_used) +{ + _IO_lock_unlock (proc_file_chain_lock); +} +#endif + +_IO_FILE * +_IO_old_proc_open (fp, command, mode) + _IO_FILE *fp; + const char *command; + const char *mode; +{ +#if _IO_HAVE_SYS_WAIT + volatile int read_or_write; + volatile int parent_end, child_end; + int pipe_fds[2]; + _IO_pid_t child_pid; + if (_IO_file_is_open (fp)) + return NULL; + if (_IO_pipe (pipe_fds) < 0) + return NULL; + if (mode[0] == 'r' && mode[1] == '\0') + { + parent_end = pipe_fds[0]; + child_end = pipe_fds[1]; + read_or_write = _IO_NO_WRITES; + } + else if (mode[0] == 'w' && mode[1] == '\0') + { + parent_end = pipe_fds[1]; + child_end = pipe_fds[0]; + read_or_write = _IO_NO_READS; + } + else + { + _IO_close (pipe_fds[0]); + _IO_close (pipe_fds[1]); + __set_errno (EINVAL); + return NULL; + } + ((_IO_proc_file *) fp)->pid = child_pid = _IO_fork (); + if (child_pid == 0) + { + int child_std_end = mode[0] == 'r' ? 1 : 0; + struct _IO_proc_file *p; + + _IO_close (parent_end); + if (child_end != child_std_end) + { + _IO_dup2 (child_end, child_std_end); + _IO_close (child_end); + } + /* POSIX.2: "popen() shall ensure that any streams from previous + popen() calls that remain open in the parent process are closed + in the new child process." */ + for (p = old_proc_file_chain; p; p = p->next) + _IO_close (_IO_fileno ((_IO_FILE *) p)); + + _IO_execl ("/bin/sh", "sh", "-c", command, (char *) 0); + _IO__exit (127); + } + _IO_close (child_end); + if (child_pid < 0) + { + _IO_close (parent_end); + return NULL; + } + _IO_fileno (fp) = parent_end; + + /* Link into old_proc_file_chain. */ +#ifdef _IO_MTSAFE_IO + _IO_cleanup_region_start_noarg (unlock); + _IO_lock_lock (proc_file_chain_lock); +#endif + ((_IO_proc_file *) fp)->next = old_proc_file_chain; + old_proc_file_chain = (_IO_proc_file *) fp; +#ifdef _IO_MTSAFE_IO + _IO_lock_unlock (proc_file_chain_lock); + _IO_cleanup_region_end (0); +#endif + + _IO_mask_flags (fp, read_or_write, _IO_NO_READS|_IO_NO_WRITES); + return fp; +#else /* !_IO_HAVE_SYS_WAIT */ + return NULL; +#endif +} + +_IO_FILE * +_IO_old_popen (command, mode) + const char *command; + const char *mode; +{ + struct locked_FILE + { + struct _IO_proc_file fpx; +#ifdef _IO_MTSAFE_IO + _IO_lock_t lock; +#endif + } *new_f; + _IO_FILE *fp; + + new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); + if (new_f == NULL) + return NULL; +#ifdef _IO_MTSAFE_IO + new_f->fpx.file.file._lock = &new_f->lock; +#endif + fp = &new_f->fpx.file.file; + INTUSE(_IO_init) (fp, 0); + _IO_JUMPS (&new_f->fpx.file) = &_IO_old_proc_jumps; + _IO_old_file_init (&new_f->fpx.file); +#if !_IO_UNIFIED_JUMPTABLES + new_f->fpx.file.vtable = NULL; +#endif + if (_IO_old_proc_open (fp, command, mode) != NULL) + return fp; + INTUSE(_IO_un_link) (&new_f->fpx.file); + free (new_f); + return NULL; +} + +int +_IO_old_proc_close (fp) + _IO_FILE *fp; +{ + /* This is not name-space clean. FIXME! */ +#if _IO_HAVE_SYS_WAIT + int wstatus; + _IO_proc_file **ptr = &old_proc_file_chain; + _IO_pid_t wait_pid; + int status = -1; + + /* Unlink from old_proc_file_chain. */ +#ifdef _IO_MTSAFE_IO + _IO_cleanup_region_start_noarg (unlock); + _IO_lock_lock (proc_file_chain_lock); +#endif + for ( ; *ptr != NULL; ptr = &(*ptr)->next) + { + if (*ptr == (_IO_proc_file *) fp) + { + *ptr = (*ptr)->next; + status = 0; + break; + } + } +#ifdef _IO_MTSAFE_IO + _IO_lock_unlock (proc_file_chain_lock); + _IO_cleanup_region_end (0); +#endif + + if (status < 0 || _IO_close (_IO_fileno(fp)) < 0) + return -1; + /* POSIX.2 Rationale: "Some historical implementations either block + or ignore the signals SIGINT, SIGQUIT, and SIGHUP while waiting + for the child process to terminate. Since this behavior is not + described in POSIX.2, such implementations are not conforming." */ + do + { + wait_pid = _IO_waitpid (((_IO_proc_file *) fp)->pid, &wstatus, 0); + } + while (wait_pid == -1 && errno == EINTR); + if (wait_pid == -1) + return -1; + return wstatus; +#else /* !_IO_HAVE_SYS_WAIT */ + return -1; +#endif +} + +struct _IO_jump_t _IO_old_proc_jumps = { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_old_file_finish), + JUMP_INIT(overflow, _IO_old_file_overflow), + JUMP_INIT(underflow, _IO_old_file_underflow), + JUMP_INIT(uflow, INTUSE(_IO_default_uflow)), + JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)), + JUMP_INIT(xsputn, _IO_old_file_xsputn), + JUMP_INIT(xsgetn, INTUSE(_IO_default_xsgetn)), + JUMP_INIT(seekoff, _IO_old_file_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_old_file_setbuf), + JUMP_INIT(sync, _IO_old_file_sync), + JUMP_INIT(doallocate, INTUSE(_IO_file_doallocate)), + JUMP_INIT(read, INTUSE(_IO_file_read)), + JUMP_INIT(write, _IO_old_file_write), + JUMP_INIT(seek, INTUSE(_IO_file_seek)), + JUMP_INIT(close, _IO_old_proc_close), + JUMP_INIT(stat, INTUSE(_IO_file_stat)), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; + +strong_alias (_IO_old_popen, __old_popen) +compat_symbol (libc, _IO_old_popen, _IO_popen, GLIBC_2_0); +compat_symbol (libc, __old_popen, popen, GLIBC_2_0); +compat_symbol (libc, _IO_old_proc_open, _IO_proc_open, GLIBC_2_0); +compat_symbol (libc, _IO_old_proc_close, _IO_proc_close, GLIBC_2_0); + +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/oldpclose.c b/src/kernel/libroot/posix/glibc/libio/oldpclose.c new file mode 100644 index 0000000000..ecc58bb4c6 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/oldpclose.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1998,2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + +#define _IO_USE_OLD_IO_FILE +#include "libioP.h" +#include "stdio.h" +#include + +int +__old_pclose (fp) + FILE *fp; +{ +#if 0 + /* Does not actually test that stream was created by popen(). Instead, + it depends on the filebuf::sys_close() virtual to Do The Right Thing. */ + if (fp is not a proc_file) + return -1; +#endif + return _IO_old_fclose (fp); +} + +compat_symbol (libc, __old_pclose, pclose, GLIBC_2_0); +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/oldstdfiles.c b/src/kernel/libroot/posix/glibc/libio/oldstdfiles.c new file mode 100644 index 0000000000..83749db871 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/oldstdfiles.c @@ -0,0 +1,96 @@ +/* Copyright (C) 1993,94,96,97,99,2000,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + +/* This file provides definitions of _IO_stdin, _IO_stdout, and _IO_stderr + for C code. Compare stdstreams.cc. + (The difference is that here the vtable field is set to 0, + so the objects defined are not valid C++ objects. On the other + hand, we don't need a C++ compiler to build this file.) */ + +#define _IO_USE_OLD_IO_FILE +#include "libioP.h" + +#ifdef _IO_MTSAFE_IO +#define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \ + static _IO_lock_t _IO_stdfile_##FD##_lock = _IO_lock_initializer; \ + struct _IO_FILE_plus NAME \ + = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, NULL), &_IO_old_file_jumps}; +#else +#define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \ + struct _IO_FILE_plus NAME \ + = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, NULL), &_IO_old_file_jumps}; +#endif + +DEF_STDFILE(_IO_stdin_, 0, 0, _IO_NO_WRITES); +DEF_STDFILE(_IO_stdout_, 1, &_IO_stdin_, _IO_NO_READS); +DEF_STDFILE(_IO_stderr_, 2, &_IO_stdout_, _IO_NO_READS+_IO_UNBUFFERED); + +#if defined __GNUC__ && __GNUC__ >= 2 + +#include + +extern const int _IO_stdin_used; +weak_extern (_IO_stdin_used); + +#undef stdin +#undef stdout +#undef stderr + +extern FILE *stdin; +extern FILE *stdout; +extern FILE *stderr; + +static void _IO_check_libio __P ((void)) __attribute__ ((constructor)); + +/* This function determines which shared C library the application + was linked against. We then set up the stdin/stdout/stderr and + _IO_list_all accordingly. */ + +static void +_IO_check_libio () +{ + if (&_IO_stdin_used == NULL) + { + /* We are using the old one. */ + _IO_stdin = stdin = (_IO_FILE *) &_IO_stdin_; + _IO_stdout = stdout = (_IO_FILE *) &_IO_stdout_; + _IO_stderr = stderr = (_IO_FILE *) &_IO_stderr_; + INTUSE(_IO_list_all) = &_IO_stderr_; + _IO_stdin->_vtable_offset = _IO_stdout->_vtable_offset = + _IO_stderr->_vtable_offset = stdin->_vtable_offset = + stdout->_vtable_offset = stderr->_vtable_offset = + ((int) sizeof (struct _IO_FILE) + - (int) sizeof (struct _IO_FILE_complete)); + } +} + +#endif + +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/oldtmpfile.c b/src/kernel/libroot/posix/glibc/libio/oldtmpfile.c new file mode 100644 index 0000000000..22dd6681a5 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/oldtmpfile.c @@ -0,0 +1,55 @@ +/* Copyright (C) 1991, 1993, 1996-1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + +#define _IO_USE_OLD_IO_FILE +#include +#include +#include + +/* This returns a new stream opened on a temporary file (generated + by tmpnam). The file is opened with mode "w+b" (binary read/write). + If we couldn't generate a unique filename or the file couldn't + be opened, NULL is returned. */ +FILE * +__old_tmpfile (void) +{ + char buf[FILENAME_MAX]; + int fd; + FILE *f; + + if (__path_search (buf, FILENAME_MAX, NULL, "tmpf", 0)) + return NULL; + fd = __gen_tempname (buf, __GT_FILE); + if (fd < 0) + return NULL; + + /* Note that this relies on the Unix semantics that + a file is not really removed until it is closed. */ + (void) remove (buf); + + if ((f = _IO_old_fdopen (fd, "w+b")) == NULL) + __close (fd); + + return f; +} + +compat_symbol (libc, __old_tmpfile, tmpfile, GLIBC_2_0); +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/pclose.c b/src/kernel/libroot/posix/glibc/libio/pclose.c new file mode 100644 index 0000000000..848c5a5b00 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/pclose.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1993, 1995, 1996-1998, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" +#include +#include + +int +__new_pclose (fp) + FILE *fp; +{ +#if 0 + /* Does not actually test that stream was created by popen(). Instead, + it depends on the filebuf::sys_close() virtual to Do The Right Thing. */ + if (fp is not a proc_file) + return -1; +#endif + return _IO_new_fclose (fp); +} + +versioned_symbol (libc, __new_pclose, pclose, GLIBC_2_1); diff --git a/src/kernel/libroot/posix/glibc/libio/peekc.c b/src/kernel/libroot/posix/glibc/libio/peekc.c new file mode 100644 index 0000000000..95ba8aea0e --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/peekc.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +#undef _IO_peekc + +int +_IO_peekc_locked (fp) + _IO_FILE *fp; +{ + int result; + CHECK_FILE (fp, EOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + result = _IO_peekc_unlocked (fp); + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} diff --git a/src/kernel/libroot/posix/glibc/libio/putc.c b/src/kernel/libroot/posix/glibc/libio/putc.c new file mode 100644 index 0000000000..649574494f --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/putc.c @@ -0,0 +1,49 @@ +/* Copyright (C) 1991,1995,1996,1997,1998,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "libioP.h" +#include "stdio.h" + +#undef _IO_putc + +int +_IO_putc (c, fp) + int c; + _IO_FILE *fp; +{ + int result; + CHECK_FILE (fp, EOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + result = _IO_putc_unlocked (c, fp); + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} +INTDEF(_IO_putc) + +#undef putc + +#ifdef weak_alias +weak_alias (_IO_putc, putc) + +#ifndef _IO_MTSAFE_IO +#undef putc_unlocked +weak_alias (_IO_putc, putc_unlocked) +#endif +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/putc_u.c b/src/kernel/libroot/posix/glibc/libio/putc_u.c new file mode 100644 index 0000000000..ad8ca4eb05 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/putc_u.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991, 1995, 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "libioP.h" +#include "stdio.h" + +#undef putc_unlocked + +int +putc_unlocked (c, fp) + int c; + _IO_FILE *fp; +{ + CHECK_FILE (fp, EOF); + return _IO_putc_unlocked (c, fp); +} diff --git a/src/kernel/libroot/posix/glibc/libio/putchar.c b/src/kernel/libroot/posix/glibc/libio/putchar.c new file mode 100644 index 0000000000..ac20727c58 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/putchar.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1991, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "libioP.h" +#include "stdio.h" + +#undef putchar + +int +putchar (c) + int c; +{ + int result; + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _IO_stdout); + _IO_flockfile (_IO_stdout); + result = _IO_putc_unlocked (c, _IO_stdout); + _IO_funlockfile (_IO_stdout); + _IO_cleanup_region_end (0); + return result; +} + +#if defined weak_alias && !defined _IO_MTSAFE_IO +#undef putchar_unlocked +weak_alias (putchar, putchar_unlocked) +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/putchar_u.c b/src/kernel/libroot/posix/glibc/libio/putchar_u.c new file mode 100644 index 0000000000..248574b5d9 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/putchar_u.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1991, 1995, 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "libioP.h" +#include "stdio.h" + +#undef putchar_unlocked + +int +putchar_unlocked (c) + int c; +{ + CHECK_FILE (_IO_stdout, EOF); + return _IO_putc_unlocked (c, _IO_stdout); +} diff --git a/src/kernel/libroot/posix/glibc/libio/putwc.c b/src/kernel/libroot/posix/glibc/libio/putwc.c new file mode 100644 index 0000000000..33da712f7f --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/putwc.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1991,95,96,97,98,99,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "libioP.h" +#include + +wint_t +putwc (wc, fp) + wchar_t wc; + _IO_FILE *fp; +{ + wint_t result; + CHECK_FILE (fp, WEOF); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + result = _IO_putwc_unlocked (wc, fp); + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); + return result; +} +libc_hidden_def (putwc) diff --git a/src/kernel/libroot/posix/glibc/libio/putwc_u.c b/src/kernel/libroot/posix/glibc/libio/putwc_u.c new file mode 100644 index 0000000000..f0914c5d1a --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/putwc_u.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1991,1995-1997,1999,2002,2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "libioP.h" +#include + +wint_t +putwc_unlocked (wc, fp) + wchar_t wc; + _IO_FILE *fp; +{ + CHECK_FILE (fp, WEOF); + return _IO_putwc_unlocked (wc, fp); +} +libc_hidden_def (putwc_unlocked) diff --git a/src/kernel/libroot/posix/glibc/libio/putwchar.c b/src/kernel/libroot/posix/glibc/libio/putwchar.c new file mode 100644 index 0000000000..56fec58aab --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/putwchar.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1991, 95, 96, 97, 98, 99 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "libioP.h" +#include + +wint_t +putwchar (wc) + wchar_t wc; +{ + wint_t result; + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _IO_stdout); + _IO_flockfile (_IO_stdout); + result = _IO_putwc_unlocked (wc, _IO_stdout); + _IO_funlockfile (_IO_stdout); + _IO_cleanup_region_end (0); + return result; +} diff --git a/src/kernel/libroot/posix/glibc/libio/putwchar_u.c b/src/kernel/libroot/posix/glibc/libio/putwchar_u.c new file mode 100644 index 0000000000..9db179fc1a --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/putwchar_u.c @@ -0,0 +1,28 @@ +/* Copyright (C) 1991, 1995, 1996, 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "libioP.h" +#include + +wint_t +putwchar_unlocked (wc) + wchar_t wc; +{ + CHECK_FILE (_IO_stdout, WEOF); + return _IO_putwc_unlocked (wc, _IO_stdout); +} diff --git a/src/kernel/libroot/posix/glibc/libio/rewind.c b/src/kernel/libroot/posix/glibc/libio/rewind.c new file mode 100644 index 0000000000..e1bdc571e0 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/rewind.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1993,96,97,98,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +void +rewind (fp) + _IO_FILE *fp; +{ + CHECK_FILE (fp, ); + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp); + _IO_flockfile (fp); + _IO_rewind (fp); + _IO_clearerr (fp); + _IO_funlockfile (fp); + _IO_cleanup_region_end (0); +} +libc_hidden_def (rewind) diff --git a/src/kernel/libroot/posix/glibc/libio/setbuf.c b/src/kernel/libroot/posix/glibc/libio/setbuf.c new file mode 100644 index 0000000000..229cccb2df --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/setbuf.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1993, 1997, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +void +setbuf (fp, buf) + _IO_FILE *fp; + char *buf; +{ + INTUSE(_IO_setbuffer) (fp, buf, _IO_BUFSIZ); +} diff --git a/src/kernel/libroot/posix/glibc/libio/setlinebuf.c b/src/kernel/libroot/posix/glibc/libio/setlinebuf.c new file mode 100644 index 0000000000..ded3c8f58c --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/setlinebuf.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1993, 1997, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +#undef setlinebuf + +void +setlinebuf (stream) + _IO_FILE *stream; +{ + INTUSE(_IO_setvbuf) (stream, NULL, 1, 0); +} diff --git a/src/kernel/libroot/posix/glibc/libio/stdfiles.c b/src/kernel/libroot/posix/glibc/libio/stdfiles.c new file mode 100644 index 0000000000..cbc1407900 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/stdfiles.c @@ -0,0 +1,74 @@ +/* Copyright (C) 1993-1997,1999,2000,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + + +/* This file provides definitions of _IO_stdin, _IO_stdout, and _IO_stderr + for C code. Compare stdstreams.cc. + (The difference is that here the vtable field is set to 0, + so the objects defined are not valid C++ objects. On the other + hand, we don't need a C++ compiler to build this file.) */ + +#include "libioP.h" + +#ifdef _IO_MTSAFE_IO +# if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T +# define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \ + static _IO_lock_t _IO_stdfile_##FD##_lock = _IO_lock_initializer; \ + static struct _IO_wide_data _IO_wide_data_##FD \ + = { ._wide_vtable = &INTUSE(_IO_wfile_jumps) }; \ + struct _IO_FILE_plus NAME \ + = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, &_IO_wide_data_##FD), \ + &INTUSE(_IO_file_jumps)}; +# else +# define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \ + static _IO_lock_t _IO_stdfile_##FD##_lock = _IO_lock_initializer; \ + struct _IO_FILE_plus NAME \ + = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, NULL), \ + &INTUSE(_IO_file_jumps)}; +# endif +#else +# if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T +# define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \ + static struct _IO_wide_data _IO_wide_data_##FD \ + = { ._wide_vtable = &INTUSE(_IO_wfile_jumps) }; \ + struct _IO_FILE_plus NAME \ + = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, &_IO_wide_data_##FD), \ + &INTUSE(_IO_file_jumps)}; +# else +# define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \ + struct _IO_FILE_plus NAME \ + = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, NULL), \ + &INTUSE(_IO_file_jumps)}; +# endif +#endif + +DEF_STDFILE(_IO_2_1_stdin_, 0, 0, _IO_NO_WRITES); +DEF_STDFILE(_IO_2_1_stdout_, 1, &_IO_2_1_stdin_, _IO_NO_READS); +DEF_STDFILE(_IO_2_1_stderr_, 2, &_IO_2_1_stdout_, _IO_NO_READS+_IO_UNBUFFERED); + +struct _IO_FILE_plus *_IO_list_all = &_IO_2_1_stderr_; +INTVARDEF(_IO_list_all) diff --git a/src/kernel/libroot/posix/glibc/libio/stdio.c b/src/kernel/libroot/posix/glibc/libio/stdio.c new file mode 100644 index 0000000000..8dc24ed98f --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/stdio.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1993,1994,1996,1997,2000,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +#undef stdin +#undef stdout +#undef stderr +_IO_FILE *stdin = (FILE *) &_IO_2_1_stdin_; +_IO_FILE *stdout = (FILE *) &_IO_2_1_stdout_; +_IO_FILE *stderr = (FILE *) &_IO_2_1_stderr_; + +#undef _IO_stdin +#undef _IO_stdout +#undef _IO_stderr +#ifdef _LIBC +# define AL(name) AL2 (name, _IO_##name) +# if defined HAVE_VISIBILITY_ATTRIBUTE +# define AL2(name, al) \ + extern __typeof (name) al __attribute__ ((alias (#name), \ + visibility ("hidden"))) +# else +# define AL2(name, al) \ + extern __typeof (name) al __attribute__ ((alias (#name))) +# endif +AL(stdin); +AL(stdout); +AL(stderr); +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/stdio.h b/src/kernel/libroot/posix/glibc/libio/stdio.h new file mode 100644 index 0000000000..3f64b6cdfe --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/stdio.h @@ -0,0 +1,683 @@ +/* Define ISO C stdio on top of C++ iostreams. + Copyright (C) 1991,1994-1999,2000,01,02 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* + * ISO C99 Standard: 7.19 Input/output + */ + +#ifndef _STDIO_H + +#include + +#if !defined __need_FILE && !defined __need___FILE +# define _STDIO_H 1 +# include + +__BEGIN_DECLS + +# define __need_size_t +# define __need_NULL +# include + +# include +# define __need_FILE +# define __need___FILE +#endif /* Don't need FILE. */ + + +#if !defined __FILE_defined && defined __need_FILE + +__BEGIN_NAMESPACE_STD +/* The opaque type of streams. This is the definition used elsewhere. */ +typedef struct _IO_FILE FILE; +__END_NAMESPACE_STD +#if defined __USE_LARGEFILE64 || defined __USE_SVID || defined __USE_POSIX \ + || defined __USE_BSD || defined __USE_ISOC99 || defined __USE_XOPEN \ + || defined __USE_POSIX2 +__USING_NAMESPACE_STD(FILE) +#endif + +# define __FILE_defined 1 +#endif /* FILE not defined. */ +#undef __need_FILE + + +#if !defined ____FILE_defined && defined __need___FILE + +/* The opaque type of streams. This is the definition used elsewhere. */ +typedef struct _IO_FILE __FILE; + +# define ____FILE_defined 1 +#endif /* __FILE not defined. */ +#undef __need___FILE + + +#ifdef _STDIO_H +#define _STDIO_USES_IOSTREAM + +#include + +#ifdef __USE_XOPEN +# ifdef __GNUC__ +# ifndef _VA_LIST_DEFINED +typedef _G_va_list va_list; +# define _VA_LIST_DEFINED +# endif +# else +# include +# endif +#endif + +/* The type of the second argument to `fgetpos' and `fsetpos'. */ +__BEGIN_NAMESPACE_STD +#ifndef __USE_FILE_OFFSET64 +typedef _G_fpos_t fpos_t; +#else +typedef _G_fpos64_t fpos_t; +#endif +__END_NAMESPACE_STD +#ifdef __USE_LARGEFILE64 +typedef _G_fpos64_t fpos64_t; +#endif + +/* The possibilities for the third argument to `setvbuf'. */ +#define _IOFBF 0 /* Fully buffered. */ +#define _IOLBF 1 /* Line buffered. */ +#define _IONBF 2 /* No buffering. */ + + +/* Default buffer size. */ +#ifndef BUFSIZ +# define BUFSIZ _IO_BUFSIZ +#endif + + +/* End of file character. + Some things throughout the library rely on this being -1. */ +#ifndef EOF +# define EOF (-1) +#endif + + +/* The possibilities for the third argument to `fseek'. + These values should not be changed. */ +#define SEEK_SET 0 /* Seek from beginning of file. */ +#define SEEK_CUR 1 /* Seek from current position. */ +#define SEEK_END 2 /* Seek from end of file. */ + + +#if defined __USE_SVID || defined __USE_XOPEN +/* Default path prefix for `tempnam' and `tmpnam'. */ +# define P_tmpdir "/tmp" +#endif + + +/* Get the values: + L_tmpnam How long an array of chars must be to be passed to `tmpnam'. + TMP_MAX The minimum number of unique filenames generated by tmpnam + (and tempnam when it uses tmpnam's name space), + or tempnam (the two are separate). + L_ctermid How long an array to pass to `ctermid'. + L_cuserid How long an array to pass to `cuserid'. + FOPEN_MAX Minimum number of files that can be open at once. + FILENAME_MAX Maximum length of a filename. */ +#include + + +/* Standard streams. */ +extern struct _IO_FILE *stdin; /* Standard input stream. */ +extern struct _IO_FILE *stdout; /* Standard output stream. */ +extern struct _IO_FILE *stderr; /* Standard error output stream. */ +/* C89/C99 say they're macros. Make them happy. */ +#define stdin stdin +#define stdout stdout +#define stderr stderr + +__BEGIN_NAMESPACE_STD +/* Remove file FILENAME. */ +extern int remove (__const char *__filename) __THROW; +/* Rename file OLD to NEW. */ +extern int rename (__const char *__old, __const char *__new) __THROW; +__END_NAMESPACE_STD + + +__BEGIN_NAMESPACE_STD +/* Create a temporary file and open it read/write. */ +#ifndef __USE_FILE_OFFSET64 +extern FILE *tmpfile (void) __THROW; +#else +# ifdef __REDIRECT +extern FILE *__REDIRECT (tmpfile, (void) __THROW, tmpfile64); +# else +# define tmpfile tmpfile64 +# endif +#endif + +/* Generate a temporary filename. */ +extern char *tmpnam (char *__s) __THROW; +__END_NAMESPACE_STD + +#ifdef __USE_LARGEFILE64 +extern FILE *tmpfile64 (void) __THROW; +#endif + +#ifdef __USE_MISC +/* This is the reentrant variant of `tmpnam'. The only difference is + that it does not allow S to be NULL. */ +extern char *tmpnam_r (char *__s) __THROW; +#endif + + +#if defined __USE_SVID || defined __USE_XOPEN +/* Generate a unique temporary filename using up to five characters of PFX + if it is not NULL. The directory to put this file in is searched for + as follows: First the environment variable "TMPDIR" is checked. + If it contains the name of a writable directory, that directory is used. + If not and if DIR is not NULL, that value is checked. If that fails, + P_tmpdir is tried and finally "/tmp". The storage for the filename + is allocated by `malloc'. */ +extern char *tempnam (__const char *__dir, __const char *__pfx) + __THROW __attribute_malloc__; +#endif + + +__BEGIN_NAMESPACE_STD +/* Close STREAM. */ +extern int fclose (FILE *__stream) __THROW; +/* Flush STREAM, or all streams if STREAM is NULL. */ +extern int fflush (FILE *__stream) __THROW; +__END_NAMESPACE_STD + +#ifdef __USE_MISC +/* Faster versions when locking is not required. */ +extern int fflush_unlocked (FILE *__stream) __THROW; +#endif + +#ifdef __USE_GNU +/* Close all streams. */ +extern int fcloseall (void) __THROW; +#endif + + +__BEGIN_NAMESPACE_STD +#ifndef __USE_FILE_OFFSET64 +/* Open a file and create a new stream for it. */ +extern FILE *fopen (__const char *__restrict __filename, + __const char *__restrict __modes) __THROW; +/* Open a file, replacing an existing stream with it. */ +extern FILE *freopen (__const char *__restrict __filename, + __const char *__restrict __modes, + FILE *__restrict __stream) __THROW; +#else +# ifdef __REDIRECT +extern FILE *__REDIRECT (fopen, (__const char *__restrict __filename, + __const char *__restrict __modes) __THROW, + fopen64); +extern FILE *__REDIRECT (freopen, (__const char *__restrict __filename, + __const char *__restrict __modes, + FILE *__restrict __stream) __THROW, + freopen64); +# else +# define fopen fopen64 +# define freopen freopen64 +# endif +#endif +__END_NAMESPACE_STD +#ifdef __USE_LARGEFILE64 +extern FILE *fopen64 (__const char *__restrict __filename, + __const char *__restrict __modes) __THROW; +extern FILE *freopen64 (__const char *__restrict __filename, + __const char *__restrict __modes, + FILE *__restrict __stream) __THROW; +#endif + +#ifdef __USE_POSIX +/* Create a new stream that refers to an existing system file descriptor. */ +extern FILE *fdopen (int __fd, __const char *__modes) __THROW; +#endif + +#ifdef __USE_GNU +/* Create a new stream that refers to the given magic cookie, + and uses the given functions for input and output. */ +extern FILE *fopencookie (void *__restrict __magic_cookie, + __const char *__restrict __modes, + _IO_cookie_io_functions_t __io_funcs) __THROW; + +/* Create a new stream that refers to a memory buffer. */ +extern FILE *fmemopen (void *__s, size_t __len, __const char *__modes) __THROW; + +/* Open a stream that writes into a malloc'd buffer that is expanded as + necessary. *BUFLOC and *SIZELOC are updated with the buffer's location + and the number of characters written on fflush or fclose. */ +extern FILE *open_memstream (char **__restrict __bufloc, + size_t *__restrict __sizeloc) __THROW; +#endif + + +__BEGIN_NAMESPACE_STD +/* If BUF is NULL, make STREAM unbuffered. + Else make it use buffer BUF, of size BUFSIZ. */ +extern void setbuf (FILE *__restrict __stream, char *__restrict __buf) __THROW; +/* Make STREAM use buffering mode MODE. + If BUF is not NULL, use N bytes of it for buffering; + else allocate an internal buffer N bytes long. */ +extern int setvbuf (FILE *__restrict __stream, char *__restrict __buf, + int __modes, size_t __n) __THROW; +__END_NAMESPACE_STD + +#ifdef __USE_BSD +/* If BUF is NULL, make STREAM unbuffered. + Else make it use SIZE bytes of BUF for buffering. */ +extern void setbuffer (FILE *__restrict __stream, char *__restrict __buf, + size_t __size) __THROW; + +/* Make STREAM line-buffered. */ +extern void setlinebuf (FILE *__stream) __THROW; +#endif + + +__BEGIN_NAMESPACE_STD +/* Write formatted output to STREAM. */ +extern int fprintf (FILE *__restrict __stream, + __const char *__restrict __format, ...) __THROW; +/* Write formatted output to stdout. */ +extern int printf (__const char *__restrict __format, ...) __THROW; +/* Write formatted output to S. */ +extern int sprintf (char *__restrict __s, + __const char *__restrict __format, ...) __THROW; + +/* Write formatted output to S from argument list ARG. */ +extern int vfprintf (FILE *__restrict __s, __const char *__restrict __format, + _G_va_list __arg) __THROW; +/* Write formatted output to stdout from argument list ARG. */ +extern int vprintf (__const char *__restrict __format, _G_va_list __arg) + __THROW; +/* Write formatted output to S from argument list ARG. */ +extern int vsprintf (char *__restrict __s, __const char *__restrict __format, + _G_va_list __arg) __THROW; +__END_NAMESPACE_STD + +#if defined __USE_BSD || defined __USE_ISOC99 || defined __USE_UNIX98 +__BEGIN_NAMESPACE_C99 +/* Maximum chars of output to write in MAXLEN. */ +extern int snprintf (char *__restrict __s, size_t __maxlen, + __const char *__restrict __format, ...) + __THROW __attribute__ ((__format__ (__printf__, 3, 4))); + +extern int vsnprintf (char *__restrict __s, size_t __maxlen, + __const char *__restrict __format, _G_va_list __arg) + __THROW __attribute__ ((__format__ (__printf__, 3, 0))); +__END_NAMESPACE_C99 +#endif + +#ifdef __USE_GNU +/* Write formatted output to a string dynamically allocated with `malloc'. + Store the address of the string in *PTR. */ +extern int vasprintf (char **__restrict __ptr, __const char *__restrict __f, + _G_va_list __arg) + __THROW __attribute__ ((__format__ (__printf__, 2, 0))); +extern int __asprintf (char **__restrict __ptr, + __const char *__restrict __fmt, ...) + __THROW __attribute__ ((__format__ (__printf__, 2, 3))); +extern int asprintf (char **__restrict __ptr, + __const char *__restrict __fmt, ...) + __THROW __attribute__ ((__format__ (__printf__, 2, 3))); + +/* Write formatted output to a file descriptor. */ +extern int vdprintf (int __fd, __const char *__restrict __fmt, + _G_va_list __arg) + __THROW __attribute__ ((__format__ (__printf__, 2, 0))); +extern int dprintf (int __fd, __const char *__restrict __fmt, ...) + __THROW __attribute__ ((__format__ (__printf__, 2, 3))); +#endif + + +__BEGIN_NAMESPACE_STD +/* Read formatted input from STREAM. */ +extern int fscanf (FILE *__restrict __stream, + __const char *__restrict __format, ...) __THROW; +/* Read formatted input from stdin. */ +extern int scanf (__const char *__restrict __format, ...) __THROW; +/* Read formatted input from S. */ +extern int sscanf (__const char *__restrict __s, + __const char *__restrict __format, ...) __THROW; +__END_NAMESPACE_STD + +#ifdef __USE_ISOC99 +__BEGIN_NAMESPACE_C99 +/* Read formatted input from S into argument list ARG. */ +extern int vfscanf (FILE *__restrict __s, __const char *__restrict __format, + _G_va_list __arg) + __THROW __attribute__ ((__format__ (__scanf__, 2, 0))); + +/* Read formatted input from stdin into argument list ARG. */ +extern int vscanf (__const char *__restrict __format, _G_va_list __arg) + __THROW __attribute__ ((__format__ (__scanf__, 1, 0))); + +/* Read formatted input from S into argument list ARG. */ +extern int vsscanf (__const char *__restrict __s, + __const char *__restrict __format, _G_va_list __arg) + __THROW __attribute__ ((__format__ (__scanf__, 2, 0))); +__END_NAMESPACE_C99 +#endif /* Use ISO C9x. */ + + +__BEGIN_NAMESPACE_STD +/* Read a character from STREAM. */ +extern int fgetc (FILE *__stream) __THROW; +extern int getc (FILE *__stream) __THROW; + +/* Read a character from stdin. */ +extern int getchar (void) __THROW; +__END_NAMESPACE_STD + +/* The C standard explicitly says this is a macro, so we always do the + optimization for it. */ +#define getc(_fp) _IO_getc (_fp) + +#if defined __USE_POSIX || defined __USE_MISC +/* These are defined in POSIX.1:1996. */ +extern int getc_unlocked (FILE *__stream) __THROW; +extern int getchar_unlocked (void) __THROW; +#endif /* Use POSIX or MISC. */ + +#ifdef __USE_MISC +/* Faster version when locking is not necessary. */ +extern int fgetc_unlocked (FILE *__stream) __THROW; +#endif /* Use MISC. */ + + +__BEGIN_NAMESPACE_STD +/* Write a character to STREAM. */ +extern int fputc (int __c, FILE *__stream) __THROW; +extern int putc (int __c, FILE *__stream) __THROW; + +/* Write a character to stdout. */ +extern int putchar (int __c) __THROW; +__END_NAMESPACE_STD + +/* The C standard explicitly says this can be a macro, + so we always do the optimization for it. */ +#define putc(_ch, _fp) _IO_putc (_ch, _fp) + +#ifdef __USE_MISC +/* Faster version when locking is not necessary. */ +extern int fputc_unlocked (int __c, FILE *__stream) __THROW; +#endif /* Use MISC. */ + +#if defined __USE_POSIX || defined __USE_MISC +/* These are defined in POSIX.1:1996. */ +extern int putc_unlocked (int __c, FILE *__stream) __THROW; +extern int putchar_unlocked (int __c) __THROW; +#endif /* Use POSIX or MISC. */ + + +#if defined __USE_SVID || defined __USE_MISC || defined __USE_XOPEN +/* Get a word (int) from STREAM. */ +extern int getw (FILE *__stream) __THROW; + +/* Write a word (int) to STREAM. */ +extern int putw (int __w, FILE *__stream) __THROW; +#endif + + +__BEGIN_NAMESPACE_STD +/* Get a newline-terminated string of finite length from STREAM. */ +extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream) + __THROW; + +/* Get a newline-terminated string from stdin, removing the newline. + DO NOT USE THIS FUNCTION!! There is no limit on how much it will read. */ +extern char *gets (char *__s) __THROW; +__END_NAMESPACE_STD + +#ifdef __USE_GNU +/* This function does the same as `fgets' but does not lock the stream. */ +extern char *fgets_unlocked (char *__restrict __s, int __n, + FILE *__restrict __stream) __THROW; +#endif + + +#ifdef __USE_GNU +/* Read up to (and including) a DELIMITER from STREAM into *LINEPTR + (and null-terminate it). *LINEPTR is a pointer returned from malloc (or + NULL), pointing to *N characters of space. It is realloc'd as + necessary. Returns the number of characters read (not including the + null terminator), or -1 on error or EOF. */ +extern _IO_ssize_t __getdelim (char **__restrict __lineptr, + size_t *__restrict __n, int __delimiter, + FILE *__restrict __stream) __THROW; +extern _IO_ssize_t getdelim (char **__restrict __lineptr, + size_t *__restrict __n, int __delimiter, + FILE *__restrict __stream) __THROW; + +/* Like `getdelim', but reads up to a newline. */ +extern _IO_ssize_t getline (char **__restrict __lineptr, + size_t *__restrict __n, + FILE *__restrict __stream) __THROW; +#endif + + +__BEGIN_NAMESPACE_STD +/* Write a string to STREAM. */ +extern int fputs (__const char *__restrict __s, FILE *__restrict __stream) + __THROW; + +/* Write a string, followed by a newline, to stdout. */ +extern int puts (__const char *__s) __THROW; + + +/* Push a character back onto the input buffer of STREAM. */ +extern int ungetc (int __c, FILE *__stream) __THROW; + + +/* Read chunks of generic data from STREAM. */ +extern size_t fread (void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __stream) __THROW; +/* Write chunks of generic data to STREAM. */ +extern size_t fwrite (__const void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __s) __THROW; +__END_NAMESPACE_STD + +#ifdef __USE_GNU +/* This function does the same as `fputs' but does not lock the stream. */ +extern int fputs_unlocked (__const char *__restrict __s, + FILE *__restrict __stream) __THROW; +#endif + +#ifdef __USE_MISC +/* Faster versions when locking is not necessary. */ +extern size_t fread_unlocked (void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __stream) __THROW; +extern size_t fwrite_unlocked (__const void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __stream) __THROW; +#endif + + +__BEGIN_NAMESPACE_STD +/* Seek to a certain position on STREAM. */ +extern int fseek (FILE *__stream, long int __off, int __whence) __THROW; +/* Return the current position of STREAM. */ +extern long int ftell (FILE *__stream) __THROW; +/* Rewind to the beginning of STREAM. */ +extern void rewind (FILE *__stream) __THROW; +__END_NAMESPACE_STD + +/* The Single Unix Specification, Version 2, specifies an alternative, + more adequate interface for the two functions above which deal with + file offset. `long int' is not the right type. These definitions + are originally defined in the Large File Support API. */ + +#ifdef __USE_LARGEFILE +# ifndef __USE_FILE_OFFSET64 +/* Seek to a certain position on STREAM. */ +extern int fseeko (FILE *__stream, off_t __off, int __whence) __THROW; +/* Return the current position of STREAM. */ +extern off_t ftello (FILE *__stream) __THROW; +# else +# ifdef __REDIRECT +extern int __REDIRECT (fseeko, + (FILE *__stream, __off64_t __off, int __whence) __THROW, + fseeko64); +extern __off64_t __REDIRECT (ftello, (FILE *__stream) __THROW, ftello64); +# else +# define fseeko fseeko64 +# define ftello ftello64 +# endif +# endif +#endif + +__BEGIN_NAMESPACE_STD +#ifndef __USE_FILE_OFFSET64 +/* Get STREAM's position. */ +extern int fgetpos (FILE *__restrict __stream, fpos_t *__restrict __pos) + __THROW; +/* Set STREAM's position. */ +extern int fsetpos (FILE *__stream, __const fpos_t *__pos) __THROW; +#else +# ifdef __REDIRECT +extern int __REDIRECT (fgetpos, (FILE *__restrict __stream, + fpos_t *__restrict __pos) __THROW, fgetpos64); +extern int __REDIRECT (fsetpos, + (FILE *__stream, __const fpos_t *__pos) __THROW, + fsetpos64); +# else +# define fgetpos fgetpos64 +# define fsetpos fsetpos64 +# endif +#endif +__END_NAMESPACE_STD + +#ifdef __USE_LARGEFILE64 +extern int fseeko64 (FILE *__stream, __off64_t __off, int __whence) __THROW; +extern __off64_t ftello64 (FILE *__stream) __THROW; +extern int fgetpos64 (FILE *__restrict __stream, fpos64_t *__restrict __pos) + __THROW; +extern int fsetpos64 (FILE *__stream, __const fpos64_t *__pos) __THROW; +#endif + +__BEGIN_NAMESPACE_STD +/* Clear the error and EOF indicators for STREAM. */ +extern void clearerr (FILE *__stream) __THROW; +/* Return the EOF indicator for STREAM. */ +extern int feof (FILE *__stream) __THROW; +/* Return the error indicator for STREAM. */ +extern int ferror (FILE *__stream) __THROW; +__END_NAMESPACE_STD + +#ifdef __USE_MISC +/* Faster versions when locking is not required. */ +extern void clearerr_unlocked (FILE *__stream) __THROW; +extern int feof_unlocked (FILE *__stream) __THROW; +extern int ferror_unlocked (FILE *__stream) __THROW; +#endif + + +__BEGIN_NAMESPACE_STD +/* Print a message describing the meaning of the value of errno. */ +extern void perror (__const char *__s) __THROW; +__END_NAMESPACE_STD + +/* Provide the declarations for `sys_errlist' and `sys_nerr' if they + are available on this system. Even if available, these variables + should not be used directly. The `strerror' function provides + all the necessary functionality. */ +#include + + +#ifdef __USE_POSIX +/* Return the system file descriptor for STREAM. */ +extern int fileno (FILE *__stream) __THROW; +#endif /* Use POSIX. */ + +#ifdef __USE_MISC +/* Faster version when locking is not required. */ +extern int fileno_unlocked (FILE *__stream) __THROW; +#endif + + +#if (defined __USE_POSIX2 || defined __USE_SVID || defined __USE_BSD || \ + defined __USE_MISC) +/* Create a new stream connected to a pipe running the given command. */ +extern FILE *popen (__const char *__command, __const char *__modes) __THROW; + +/* Close a stream opened by popen and return the status of its child. */ +extern int pclose (FILE *__stream) __THROW; +#endif + + +#ifdef __USE_POSIX +/* Return the name of the controlling terminal. */ +extern char *ctermid (char *__s) __THROW; +#endif /* Use POSIX. */ + + +#ifdef __USE_XOPEN +/* Return the name of the current user. */ +extern char *cuserid (char *__s) __THROW; +#endif /* Use X/Open, but not issue 6. */ + + +#ifdef __USE_GNU +struct obstack; /* See . */ + +/* Write formatted output to an obstack. */ +extern int obstack_printf (struct obstack *__restrict __obstack, + __const char *__restrict __format, ...) + __THROW __attribute__ ((__format__ (__printf__, 2, 3))); +extern int obstack_vprintf (struct obstack *__restrict __obstack, + __const char *__restrict __format, + _G_va_list __args) + __THROW __attribute__ ((__format__ (__printf__, 2, 0))); +#endif /* Use GNU. */ + + +#if defined __USE_POSIX || defined __USE_MISC +/* These are defined in POSIX.1:1996. */ + +/* Acquire ownership of STREAM. */ +extern void flockfile (FILE *__stream) __THROW; + +/* Try to acquire ownership of STREAM but do not block if it is not + possible. */ +extern int ftrylockfile (FILE *__stream) __THROW; + +/* Relinquish the ownership granted for STREAM. */ +extern void funlockfile (FILE *__stream) __THROW; +#endif /* POSIX || misc */ + +#if defined __USE_XOPEN && !defined __USE_XOPEN2K && !defined __USE_GNU +/* The X/Open standard requires some functions and variables to be + declared here which do not belong into this header. But we have to + follow. In GNU mode we don't do this nonsense. */ +# define __need_getopt +# include +#endif /* X/Open, but not issue 6 and not for GNU. */ + +/* If we are compiling with optimizing read this file. It contains + several optimizing inline functions and macros. */ +#ifdef __USE_EXTERN_INLINES +# include +#endif + +__END_DECLS + +#endif /* included. */ + +#endif /* !_STDIO_H */ diff --git a/src/kernel/libroot/posix/glibc/libio/strfile.h b/src/kernel/libroot/posix/glibc/libio/strfile.h new file mode 100644 index 0000000000..bcac784717 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/strfile.h @@ -0,0 +1,65 @@ +/* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include +#ifdef TODO +Merge into libio.h ? +#endif + +typedef void *(*_IO_alloc_type) (_IO_size_t); +typedef void (*_IO_free_type) (void*); + +struct _IO_str_fields +{ + _IO_alloc_type _allocate_buffer; + _IO_free_type _free_buffer; +}; + +/* This is needed for the Irix6 N32 ABI, which has a 64 bit off_t type, + but a 32 bit pointer type. In this case, we get 4 bytes of padding + after the vtable pointer. Putting them in a structure together solves + this problem. */ + +struct _IO_streambuf +{ + struct _IO_FILE _f; + const void *_vtable; +}; + +typedef struct _IO_strfile_ +{ + struct _IO_streambuf _sbf; + struct _IO_str_fields _s; +} _IO_strfile; + +/* dynamic: set when the array object is allocated (or reallocated) as + necessary to hold a character sequence that can change in length. */ +#define _IO_STR_DYNAMIC(FP) ((FP)->_s._allocate_buffer != (_IO_alloc_type)0) + +/* frozen: set when the program has requested that the array object not + be altered, reallocated, or freed. */ +#define _IO_STR_FROZEN(FP) ((FP)->_f._IO_file_flags & _IO_USER_BUF) diff --git a/src/kernel/libroot/posix/glibc/libio/strops.c b/src/kernel/libroot/posix/glibc/libio/strops.c new file mode 100644 index 0000000000..591546b71d --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/strops.c @@ -0,0 +1,332 @@ +/* Copyright (C) 1993, 1997-2000, 2001, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "strfile.h" +#include +#include + +#if 0 +/* The following definitions are for exposition only. + They map the terminology used in the ANSI/ISO C++ draft standard + to the implementation. */ + +/* allocated: set when a dynamic array object has been allocated, and + hence should be freed by the destructor for the strstreambuf object. */ +#define ALLOCATED(FP) ((FP)->_f._IO_buf_base && DYNAMIC(FP)) + +/* constant: set when the array object has const elements, + so the output sequence cannot be written. */ +#define CONSTANT(FP) ((FP)->_f._IO_file_flags & _IO_NO_WRITES) + +/* alsize: the suggested minimum size for a dynamic array object. */ +#define ALSIZE(FP) ??? /* not stored */ + +/* palloc: points to the function to call to allocate a dynamic array object.*/ +#define PALLOC(FP) \ + ((FP)->_s._allocate_buffer == default_alloc ? 0 : (FP)->_s._allocate_buffer) + +/* pfree: points to the function to call to free a dynamic array object. */ +#define PFREE(FP) \ + ((FP)->_s._free_buffer == default_free ? 0 : (FP)->_s._free_buffer) + +#endif + +#ifdef TODO +/* An "unbounded buffer" is when a buffer is supplied, but with no + specified length. An example is the buffer argument to sprintf. + */ +#endif + +void +_IO_str_init_static (sf, ptr, size, pstart) + _IO_strfile *sf; + char *ptr; + int size; + char *pstart; +{ + _IO_FILE *fp = &sf->_sbf._f; + + if (size == 0) + size = strlen (ptr); + else if (size < 0) + { + /* If size is negative 'the characters are assumed to + continue indefinitely.' This is kind of messy ... */ + int s; + size = 512; + /* Try increasing powers of 2, as long as we don't wrap around. */ + for (; s = 2*size, s > 0 && ptr + s > ptr && s < 0x4000000L; ) + size = s; + /* Try increasing size as much as we can without wrapping around. */ + for (s = size >> 1; s > 0; s >>= 1) + { + if (ptr + size + s > ptr) + size += s; + } + } + INTUSE(_IO_setb) (fp, ptr, ptr + size, 0); + + fp->_IO_write_base = ptr; + fp->_IO_read_base = ptr; + fp->_IO_read_ptr = ptr; + if (pstart) + { + fp->_IO_write_ptr = pstart; + fp->_IO_write_end = ptr + size; + fp->_IO_read_end = pstart; + } + else + { + fp->_IO_write_ptr = ptr; + fp->_IO_write_end = ptr; + fp->_IO_read_end = ptr+size; + } + /* A null _allocate_buffer function flags the strfile as being static. */ + sf->_s._allocate_buffer = (_IO_alloc_type) 0; +} +INTDEF(_IO_str_init_static) + +void +_IO_str_init_readonly (sf, ptr, size) + _IO_strfile *sf; + const char *ptr; + int size; +{ + INTUSE(_IO_str_init_static) (sf, (char *) ptr, size, NULL); + sf->_sbf._f._IO_file_flags |= _IO_NO_WRITES; +} + +int +_IO_str_overflow (fp, c) + _IO_FILE *fp; + int c; +{ + int flush_only = c == EOF; + _IO_size_t pos; + if (fp->_flags & _IO_NO_WRITES) + return flush_only ? 0 : EOF; + if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING)) + { + fp->_flags |= _IO_CURRENTLY_PUTTING; + fp->_IO_write_ptr = fp->_IO_read_ptr; + fp->_IO_read_ptr = fp->_IO_read_end; + } + pos = fp->_IO_write_ptr - fp->_IO_write_base; + if (pos >= (_IO_size_t) (_IO_blen (fp) + flush_only)) + { + if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */ + return EOF; + else + { + char *new_buf; + char *old_buf = fp->_IO_buf_base; + _IO_size_t new_size = 2 * _IO_blen (fp) + 100; + new_buf + = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size); + if (new_buf == NULL) + { + /* __ferror(fp) = 1; */ + return EOF; + } + if (old_buf) + { + memcpy (new_buf, old_buf, _IO_blen (fp)); + (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf); + /* Make sure _IO_setb won't try to delete _IO_buf_base. */ + fp->_IO_buf_base = NULL; + } +#if 0 + if (lenp == &LEN(fp)) /* use '\0'-filling */ + memset (new_buf + pos, 0, blen() - pos); +#endif + INTUSE(_IO_setb) (fp, new_buf, new_buf + new_size, 1); + fp->_IO_read_base = new_buf + (fp->_IO_read_base - old_buf); + fp->_IO_read_ptr = new_buf + (fp->_IO_read_ptr - old_buf); + fp->_IO_read_end = new_buf + (fp->_IO_read_end - old_buf); + fp->_IO_write_ptr = new_buf + (fp->_IO_write_ptr - old_buf); + + fp->_IO_write_base = new_buf; + fp->_IO_write_end = fp->_IO_buf_end; + } + } + + if (!flush_only) + *fp->_IO_write_ptr++ = (unsigned char) c; + if (fp->_IO_write_ptr > fp->_IO_read_end) + fp->_IO_read_end = fp->_IO_write_ptr; + return c; +} +INTDEF(_IO_str_overflow) + +int +_IO_str_underflow (fp) + _IO_FILE *fp; +{ + if (fp->_IO_write_ptr > fp->_IO_read_end) + fp->_IO_read_end = fp->_IO_write_ptr; + if ((fp->_flags & _IO_TIED_PUT_GET) && (fp->_flags & _IO_CURRENTLY_PUTTING)) + { + fp->_flags &= ~_IO_CURRENTLY_PUTTING; + fp->_IO_read_ptr = fp->_IO_write_ptr; + fp->_IO_write_ptr = fp->_IO_write_end; + } + if (fp->_IO_read_ptr < fp->_IO_read_end) + return *((unsigned char *) fp->_IO_read_ptr); + else + return EOF; +} +INTDEF(_IO_str_underflow) + +/* The size of the valid part of the buffer. */ + +_IO_ssize_t +_IO_str_count (fp) + _IO_FILE *fp; +{ + return ((fp->_IO_write_ptr > fp->_IO_read_end + ? fp->_IO_write_ptr : fp->_IO_read_end) + - fp->_IO_read_base); +} + +_IO_off64_t +_IO_str_seekoff (fp, offset, dir, mode) + _IO_FILE *fp; + _IO_off64_t offset; + int dir; + int mode; +{ + _IO_off64_t new_pos; + + if (mode == 0 && (fp->_flags & _IO_TIED_PUT_GET)) + mode = (fp->_flags & _IO_CURRENTLY_PUTTING ? _IOS_OUTPUT : _IOS_INPUT); + + if (mode == 0) + { + /* Don't move any pointers. But there is no clear indication what + mode FP is in. Let's guess. */ + if (fp->_IO_file_flags & _IO_NO_WRITES) + new_pos = fp->_IO_read_ptr - fp->_IO_read_base; + else + new_pos = fp->_IO_write_ptr - fp->_IO_write_base; + } + else + { + _IO_ssize_t cur_size = _IO_str_count(fp); + new_pos = EOF; + + /* Move the get pointer, if requested. */ + if (mode & _IOS_INPUT) + { + switch (dir) + { + case _IO_seek_end: + offset += cur_size; + break; + case _IO_seek_cur: + offset += fp->_IO_read_ptr - fp->_IO_read_base; + break; + default: /* case _IO_seek_set: */ + break; + } + if (offset < 0 || (_IO_ssize_t) offset > cur_size) + return EOF; + fp->_IO_read_ptr = fp->_IO_read_base + offset; + fp->_IO_read_end = fp->_IO_read_base + cur_size; + new_pos = offset; + } + + /* Move the put pointer, if requested. */ + if (mode & _IOS_OUTPUT) + { + switch (dir) + { + case _IO_seek_end: + offset += cur_size; + break; + case _IO_seek_cur: + offset += fp->_IO_write_ptr - fp->_IO_write_base; + break; + default: /* case _IO_seek_set: */ + break; + } + if (offset < 0 || (_IO_ssize_t) offset > cur_size) + return EOF; + fp->_IO_write_ptr = fp->_IO_write_base + offset; + new_pos = offset; + } + } + return new_pos; +} +INTDEF(_IO_str_seekoff) + +int +_IO_str_pbackfail (fp, c) + _IO_FILE *fp; + int c; +{ + if ((fp->_flags & _IO_NO_WRITES) && c != EOF) + return EOF; + return INTUSE(_IO_default_pbackfail) (fp, c); +} +INTDEF(_IO_str_pbackfail) + +void +_IO_str_finish (fp, dummy) + _IO_FILE *fp; + int dummy; +{ + if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF)) + (((_IO_strfile *) fp)->_s._free_buffer) (fp->_IO_buf_base); + fp->_IO_buf_base = NULL; + + INTUSE(_IO_default_finish) (fp, 0); +} + +struct _IO_jump_t _IO_str_jumps = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_str_finish), + JUMP_INIT(overflow, INTUSE(_IO_str_overflow)), + JUMP_INIT(underflow, INTUSE(_IO_str_underflow)), + JUMP_INIT(uflow, INTUSE(_IO_default_uflow)), + JUMP_INIT(pbackfail, INTUSE(_IO_str_pbackfail)), + JUMP_INIT(xsputn, INTUSE(_IO_default_xsputn)), + JUMP_INIT(xsgetn, INTUSE(_IO_default_xsgetn)), + JUMP_INIT(seekoff, INTUSE(_IO_str_seekoff)), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_default_setbuf), + JUMP_INIT(sync, _IO_default_sync), + JUMP_INIT(doallocate, INTUSE(_IO_default_doallocate)), + JUMP_INIT(read, _IO_default_read), + JUMP_INIT(write, _IO_default_write), + JUMP_INIT(seek, _IO_default_seek), + JUMP_INIT(close, _IO_default_close), + JUMP_INIT(stat, _IO_default_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; diff --git a/src/kernel/libroot/posix/glibc/libio/swprintf.c b/src/kernel/libroot/posix/glibc/libio/swprintf.c new file mode 100644 index 0000000000..298c1e7537 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/swprintf.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1991,1995,1997,1998,1999,2000,2003 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include + +/* Write formatted output into S, according to the format string FORMAT. */ +/* VARARGS3 */ +int +swprintf (wchar_t *s, size_t n, const wchar_t *format, ...) +{ + va_list arg; + int done; + + va_start (arg, format); + done = __vswprintf (s, n, format, arg); + va_end (arg); + + return done; +} diff --git a/src/kernel/libroot/posix/glibc/libio/swscanf.c b/src/kernel/libroot/posix/glibc/libio/swscanf.c new file mode 100644 index 0000000000..c837ad14f6 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/swscanf.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1991,1995,1996,1998,1999,2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include + +/* Read formatted input from S, according to the format string FORMAT. */ +/* VARARGS2 */ +int +swscanf (const wchar_t *s, const wchar_t *format, ...) +{ + va_list arg; + int done; + + va_start (arg, format); + done = vswscanf (s, format, arg); + va_end (arg); + + return done; +} diff --git a/src/kernel/libroot/posix/glibc/libio/vasprintf.c b/src/kernel/libroot/posix/glibc/libio/vasprintf.c new file mode 100644 index 0000000000..fb7e00675a --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/vasprintf.c @@ -0,0 +1,93 @@ +/* Copyright (C) 1995,1997,1999,2000,2001,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include +#include +#include "libioP.h" +#include "stdio.h" +#include +#include "strfile.h" + +int +_IO_vasprintf (result_ptr, format, args) + char **result_ptr; + const char *format; + _IO_va_list args; +{ + /* Initial size of the buffer to be used. Will be doubled each time an + overflow occurs. */ + const _IO_size_t init_string_size = 100; + char *string; + _IO_strfile sf; + int ret; + _IO_size_t needed; + _IO_size_t allocated; + string = (char *) malloc (init_string_size); + if (string == NULL) + return -1; +#ifdef _IO_MTSAFE_IO + sf._sbf._f._lock = NULL; +#endif + _IO_no_init ((_IO_FILE *) &sf._sbf, _IO_USER_LOCK, -1, NULL, NULL); + _IO_JUMPS ((struct _IO_FILE_plus *) &sf._sbf) = &_IO_str_jumps; + INTUSE(_IO_str_init_static) (&sf, string, init_string_size, string); + sf._sbf._f._flags &= ~_IO_USER_BUF; + sf._s._allocate_buffer = (_IO_alloc_type) malloc; + sf._s._free_buffer = (_IO_free_type) free; + ret = INTUSE(_IO_vfprintf) (&sf._sbf._f, format, args); + if (ret < 0) + { + free (sf._sbf._f._IO_buf_base); + return ret; + } + /* Only use realloc if the size we need is of the same order of + magnitude then the memory we allocated. */ + needed = sf._sbf._f._IO_write_ptr - sf._sbf._f._IO_write_base + 1; + allocated = sf._sbf._f._IO_write_end - sf._sbf._f._IO_write_base; + if ((allocated << 1) <= needed) + *result_ptr = (char *) realloc (sf._sbf._f._IO_buf_base, needed); + else + { + *result_ptr = (char *) malloc (needed); + if (*result_ptr != NULL) + { + memcpy (*result_ptr, sf._sbf._f._IO_buf_base, needed - 1); + free (sf._sbf._f._IO_buf_base); + } + else + /* We have no choice, use the buffer we already have. */ + *result_ptr = (char *) realloc (sf._sbf._f._IO_buf_base, needed); + } + if (*result_ptr == NULL) + *result_ptr = sf._sbf._f._IO_buf_base; + (*result_ptr)[needed - 1] = '\0'; + return ret; +} + +#ifdef weak_alias +weak_alias (_IO_vasprintf, vasprintf) +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/vscanf.c b/src/kernel/libroot/posix/glibc/libio/vscanf.c new file mode 100644 index 0000000000..477cbaee84 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/vscanf.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1993, 1997, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +#undef vscanf + +int +_IO_vscanf (format, args) + const char *format; + _IO_va_list args; +{ + return INTUSE(_IO_vfscanf) (_IO_stdin, format, args, NULL); +} + +#ifdef weak_alias +weak_alias (_IO_vscanf, vscanf) +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/vsnprintf.c b/src/kernel/libroot/posix/glibc/libio/vsnprintf.c new file mode 100644 index 0000000000..8a3afc46bd --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/vsnprintf.c @@ -0,0 +1,140 @@ +/* Copyright (C) 1994,1997,1999,2000,2001,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "strfile.h" + + +typedef struct +{ + _IO_strfile f; + /* This is used for the characters which do not fit in the buffer + provided by the user. */ + char overflow_buf[64]; +} _IO_strnfile; + + +static int _IO_strn_overflow __P ((_IO_FILE *fp, int c)); + +static int +_IO_strn_overflow (fp, c) + _IO_FILE *fp; + int c; +{ + /* When we come to here this means the user supplied buffer is + filled. But since we must return the number of characters which + would have been written in total we must provide a buffer for + further use. We can do this by writing on and on in the overflow + buffer in the _IO_strnfile structure. */ + _IO_strnfile *snf = (_IO_strnfile *) fp; + + if (fp->_IO_buf_base != snf->overflow_buf) + { + /* Terminate the string. We know that there is room for at + least one more character since we initialized the stream with + a size to make this possible. */ + *fp->_IO_write_ptr = '\0'; + + INTUSE(_IO_setb) (fp, snf->overflow_buf, + snf->overflow_buf + sizeof (snf->overflow_buf), 0); + + fp->_IO_write_base = snf->overflow_buf; + fp->_IO_read_base = snf->overflow_buf; + fp->_IO_read_ptr = snf->overflow_buf; + fp->_IO_read_end = snf->overflow_buf + sizeof (snf->overflow_buf); + } + + fp->_IO_write_ptr = snf->overflow_buf; + fp->_IO_write_end = snf->overflow_buf; + + /* Since we are not really interested in storing the characters + which do not fit in the buffer we simply ignore it. */ + return c; +} + + +static struct _IO_jump_t _IO_strn_jumps = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_str_finish), + JUMP_INIT(overflow, _IO_strn_overflow), + JUMP_INIT(underflow, INTUSE(_IO_str_underflow)), + JUMP_INIT(uflow, INTUSE(_IO_default_uflow)), + JUMP_INIT(pbackfail, INTUSE(_IO_str_pbackfail)), + JUMP_INIT(xsputn, INTUSE(_IO_default_xsputn)), + JUMP_INIT(xsgetn, INTUSE(_IO_default_xsgetn)), + JUMP_INIT(seekoff, INTUSE(_IO_str_seekoff)), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_default_setbuf), + JUMP_INIT(sync, _IO_default_sync), + JUMP_INIT(doallocate, INTUSE(_IO_default_doallocate)), + JUMP_INIT(read, _IO_default_read), + JUMP_INIT(write, _IO_default_write), + JUMP_INIT(seek, _IO_default_seek), + JUMP_INIT(close, _IO_default_close), + JUMP_INIT(stat, _IO_default_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; + + +int +_IO_vsnprintf (string, maxlen, format, args) + char *string; + _IO_size_t maxlen; + const char *format; + _IO_va_list args; +{ + _IO_strnfile sf; + int ret; +#ifdef _IO_MTSAFE_IO + sf.f._sbf._f._lock = NULL; +#endif + + /* We need to handle the special case where MAXLEN is 0. Use the + overflow buffer right from the start. */ + if (maxlen == 0) + { + string = sf.overflow_buf; + maxlen = sizeof (sf.overflow_buf); + } + + _IO_no_init (&sf.f._sbf._f, _IO_USER_LOCK, -1, NULL, NULL); + _IO_JUMPS ((struct _IO_FILE_plus *) &sf.f._sbf) = &_IO_strn_jumps; + string[0] = '\0'; + INTUSE(_IO_str_init_static) (&sf.f, string, maxlen - 1, string); + ret = INTUSE(_IO_vfprintf) ((_IO_FILE *) &sf.f._sbf, format, args); + + if (sf.f._sbf._f._IO_buf_base != sf.overflow_buf) + *sf.f._sbf._f._IO_write_ptr = '\0'; + return ret; +} + +#ifdef weak_alias +weak_alias (_IO_vsnprintf, __vsnprintf) +weak_alias (_IO_vsnprintf, vsnprintf) +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/vswprintf.c b/src/kernel/libroot/posix/glibc/libio/vswprintf.c new file mode 100644 index 0000000000..3ec44d1463 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/vswprintf.c @@ -0,0 +1,142 @@ +/* Copyright (C) 1994,1997,1999,2000,2001,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "strfile.h" + + +typedef struct +{ + _IO_strfile f; + /* This is used for the characters which do not fit in the buffer + provided by the user. */ + wchar_t overflow_buf[64]; +} _IO_strnfile; + + +static wint_t _IO_wstrn_overflow __P ((_IO_FILE *fp, wint_t c)); + +static wint_t +_IO_wstrn_overflow (fp, c) + _IO_FILE *fp; + wint_t c; +{ + /* When we come to here this means the user supplied buffer is + filled. But since we must return the number of characters which + would have been written in total we must provide a buffer for + further use. We can do this by writing on and on in the overflow + buffer in the _IO_strnfile structure. */ + _IO_strnfile *snf = (_IO_strnfile *) fp; + + if (fp->_wide_data->_IO_buf_base != snf->overflow_buf) + { + INTUSE(_IO_wsetb) (fp, snf->overflow_buf, + snf->overflow_buf + (sizeof (snf->overflow_buf) + / sizeof (wchar_t)), 0); + + fp->_wide_data->_IO_write_base = snf->overflow_buf; + fp->_wide_data->_IO_read_base = snf->overflow_buf; + fp->_wide_data->_IO_read_ptr = snf->overflow_buf; + fp->_wide_data->_IO_read_end = (snf->overflow_buf + + (sizeof (snf->overflow_buf) + / sizeof (wchar_t))); + } + + fp->_wide_data->_IO_write_ptr = snf->overflow_buf; + fp->_wide_data->_IO_write_end = snf->overflow_buf; + + /* Since we are not really interested in storing the characters + which do not fit in the buffer we simply ignore it. */ + return c; +} + + +static struct _IO_jump_t _IO_wstrn_jumps = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_wstr_finish), + JUMP_INIT(overflow, (_IO_overflow_t) _IO_wstrn_overflow), + JUMP_INIT(underflow, (_IO_underflow_t) _IO_wstr_underflow), + JUMP_INIT(uflow, (_IO_underflow_t) INTUSE(_IO_wdefault_uflow)), + JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail), + JUMP_INIT(xsputn, INTUSE(_IO_wdefault_xsputn)), + JUMP_INIT(xsgetn, INTUSE(_IO_wdefault_xsgetn)), + JUMP_INIT(seekoff, _IO_wstr_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_default_setbuf), + JUMP_INIT(sync, _IO_default_sync), + JUMP_INIT(doallocate, INTUSE(_IO_wdefault_doallocate)), + JUMP_INIT(read, _IO_default_read), + JUMP_INIT(write, _IO_default_write), + JUMP_INIT(seek, _IO_default_seek), + JUMP_INIT(close, _IO_default_close), + JUMP_INIT(stat, _IO_default_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; + + +int +_IO_vswprintf (string, maxlen, format, args) + wchar_t *string; + _IO_size_t maxlen; + const wchar_t *format; + _IO_va_list args; +{ + _IO_strnfile sf; + int ret; + struct _IO_wide_data wd; +#ifdef _IO_MTSAFE_IO + sf.f._sbf._f._lock = NULL; +#endif + + if (maxlen == 0) + /* Since we have to write at least the terminating L'\0' a buffer + length of zero always makes the function fail. */ + return -1; + + _IO_no_init (&sf.f._sbf._f, _IO_USER_LOCK, 0, &wd, &_IO_wstrn_jumps); + _IO_fwide (&sf.f._sbf._f, 1); + string[0] = L'\0'; + _IO_wstr_init_static (&sf.f._sbf._f, string, maxlen - 1, string); + ret = _IO_vfwprintf ((_IO_FILE *) &sf.f._sbf, format, args); + + if (sf.f._sbf._f._wide_data->_IO_buf_base == sf.overflow_buf) + /* ISO C99 requires swprintf/vswprintf to return an error if the + output does not fit int he provided buffer. */ + return -1; + + /* Terminate the string. */ + *sf.f._sbf._f._wide_data->_IO_write_ptr = '\0'; + + return ret; +} + +#ifdef weak_alias +weak_alias (_IO_vswprintf, __vswprintf) +weak_alias (_IO_vswprintf, vswprintf) +#endif diff --git a/src/kernel/libroot/posix/glibc/libio/vwprintf.c b/src/kernel/libroot/posix/glibc/libio/vwprintf.c new file mode 100644 index 0000000000..814fdf32bf --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/vwprintf.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991,1993,1995,1997,1999,2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include + +/* Write formatted output to stdout according to the + format string FORMAT, using the argument list in ARG. */ +int +vwprintf (format, arg) + const wchar_t *format; + __gnuc_va_list arg; +{ + return __vfwprintf (stdout, format, arg); +} diff --git a/src/kernel/libroot/posix/glibc/libio/vwscanf.c b/src/kernel/libroot/posix/glibc/libio/vwscanf.c new file mode 100644 index 0000000000..cd7af9ce5b --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/vwscanf.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1993, 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include + +int +vwscanf (format, args) + const wchar_t *format; + _IO_va_list args; +{ + return _IO_vfwscanf (_IO_stdin, format, args, NULL); +} diff --git a/src/kernel/libroot/posix/glibc/libio/wfiledoalloc.c b/src/kernel/libroot/posix/glibc/libio/wfiledoalloc.c new file mode 100644 index 0000000000..2f8140b0ac --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/wfiledoalloc.c @@ -0,0 +1,119 @@ +/* Copyright (C) 1993, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +/* + Copyright (C) 1990 The Regents of the University of California. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 4. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE.*/ + +/* Modified for GNU iostream by Per Bothner 1991, 1992. */ + +#ifndef _POSIX_SOURCE +# define _POSIX_SOURCE +#endif +#include "libioP.h" +#include +#include +#ifdef __STDC__ +#include +#include +#endif + +#ifdef _LIBC +# undef isatty +# define isatty(Fd) __isatty (Fd) +#endif + +/* + * Allocate a file buffer, or switch to unbuffered I/O. + * Per the ANSI C standard, ALL tty devices default to line buffered. + * + * As a side effect, we set __SOPT or __SNPT (en/dis-able fseek + * optimisation) right after the _fstat() that finds the buffer size. + */ + +int +_IO_wfile_doallocate (fp) + _IO_FILE *fp; +{ + _IO_size_t size; + int couldbetty; + wchar_t *p; + struct _G_stat64 st; + + /* Allocate room for the external buffer. */ + if (fp->_IO_buf_base == NULL) + INTUSE(_IO_file_doallocate) (fp); + + if (fp->_fileno < 0 || _IO_SYSSTAT (fp, &st) < 0) + { + couldbetty = 0; + size = _IO_BUFSIZ; +#if 0 + /* do not try to optimise fseek() */ + fp->_flags |= __SNPT; +#endif + } + else + { + couldbetty = S_ISCHR (st.st_mode); +#if _IO_HAVE_ST_BLKSIZE + size = st.st_blksize <= 0 ? _IO_BUFSIZ : st.st_blksize; +#else + size = _IO_BUFSIZ; +#endif + } + ALLOC_WBUF (p, size * sizeof (wchar_t), EOF); + INTUSE(_IO_wsetb) (fp, p, p + size, 1); + if (couldbetty && isatty (fp->_fileno)) + fp->_flags |= _IO_LINE_BUF; + return 1; +} diff --git a/src/kernel/libroot/posix/glibc/libio/wfileops.c b/src/kernel/libroot/posix/glibc/libio/wfileops.c new file mode 100644 index 0000000000..38f6ab256e --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/wfileops.c @@ -0,0 +1,931 @@ +/* Copyright (C) 1993,95,97,98,99,2000,2001,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Ulrich Drepper . + Based on the single byte version by Per Bothner . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include +#include +#include +#include +#include +#include + + +#ifndef _LIBC +# define _IO_new_do_write _IO_do_write +# define _IO_new_file_attach _IO_file_attach +# define _IO_new_file_close_it _IO_file_close_it +# define _IO_new_file_finish _IO_file_finish +# define _IO_new_file_fopen _IO_file_fopen +# define _IO_new_file_init _IO_file_init +# define _IO_new_file_setbuf _IO_file_setbuf +# define _IO_new_file_sync _IO_file_sync +# define _IO_new_file_overflow _IO_file_overflow +# define _IO_new_file_seekoff _IO_file_seekoff +# define _IO_new_file_underflow _IO_file_underflow +# define _IO_new_file_write _IO_file_write +# define _IO_new_file_xsputn _IO_file_xsputn +#endif + + +/* Convert TO_DO wide character from DATA to FP. + Then mark FP as having empty buffers. */ +int +_IO_wdo_write (fp, data, to_do) + _IO_FILE *fp; + const wchar_t *data; + _IO_size_t to_do; +{ + struct _IO_codecvt *cc = fp->_codecvt; + + if (to_do > 0) + { + if (fp->_IO_write_end == fp->_IO_write_ptr + && fp->_IO_write_end != fp->_IO_write_base) + { + if (_IO_new_do_write (fp, fp->_IO_write_base, + fp->_IO_write_ptr - fp->_IO_write_base) == EOF) + return EOF; + } + + do + { + enum __codecvt_result result; + const wchar_t *new_data; + + /* Now convert from the internal format into the external buffer. */ + result = (*cc->__codecvt_do_out) (cc, &fp->_wide_data->_IO_state, + data, data + to_do, &new_data, + fp->_IO_write_ptr, + fp->_IO_buf_end, + &fp->_IO_write_ptr); + + /* Write out what we produced so far. */ + if (_IO_new_do_write (fp, fp->_IO_write_base, + fp->_IO_write_ptr - fp->_IO_write_base) == EOF) + /* Something went wrong. */ + return WEOF; + + to_do -= new_data - data; + + /* Next see whether we had problems during the conversion. If yes, + we cannot go on. */ + if (result != __codecvt_ok + && (result != __codecvt_partial || new_data - data == 0)) + break; + + data = new_data; + } + while (to_do > 0); + } + + _IO_wsetg (fp, fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base, + fp->_wide_data->_IO_buf_base); + fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_write_ptr + = fp->_wide_data->_IO_buf_base; + fp->_wide_data->_IO_write_end = ((fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED)) + ? fp->_wide_data->_IO_buf_base + : fp->_wide_data->_IO_buf_end); + + return to_do == 0 ? 0 : WEOF; +} +INTDEF(_IO_wdo_write) + + +wint_t +_IO_wfile_underflow (fp) + _IO_FILE *fp; +{ + struct _IO_codecvt *cd; + enum __codecvt_result status; + _IO_ssize_t count; + int tries; + const char *read_ptr_copy; + + if (__builtin_expect (fp->_flags & _IO_NO_READS, 0)) + { + fp->_flags |= _IO_ERR_SEEN; + __set_errno (EBADF); + return WEOF; + } + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + return *fp->_wide_data->_IO_read_ptr; + + cd = fp->_codecvt; + + /* Maybe there is something left in the external buffer. */ + if (fp->_IO_read_ptr < fp->_IO_read_end) + { + /* There is more in the external. Convert it. */ + const char *read_stop = (const char *) fp->_IO_read_ptr; + + fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state; + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr = + fp->_wide_data->_IO_buf_base; + status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state, + fp->_IO_read_ptr, fp->_IO_read_end, + &read_stop, + fp->_wide_data->_IO_read_ptr, + fp->_wide_data->_IO_buf_end, + &fp->_wide_data->_IO_read_end); + + fp->_IO_read_ptr = (char *) read_stop; + + /* If we managed to generate some text return the next character. */ + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + return *fp->_wide_data->_IO_read_ptr; + + if (status == __codecvt_error) + { + __set_errno (EILSEQ); + fp->_flags |= _IO_ERR_SEEN; + return WEOF; + } + + /* Move the remaining content of the read buffer to the beginning. */ + memmove (fp->_IO_buf_base, fp->_IO_read_ptr, + fp->_IO_read_end - fp->_IO_read_ptr); + fp->_IO_read_end = (fp->_IO_buf_base + + (fp->_IO_read_end - fp->_IO_read_ptr)); + fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base; + } + else + fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = + fp->_IO_buf_base; + + if (fp->_IO_buf_base == NULL) + { + /* Maybe we already have a push back pointer. */ + if (fp->_IO_save_base != NULL) + { + free (fp->_IO_save_base); + fp->_flags &= ~_IO_IN_BACKUP; + } + INTUSE(_IO_doallocbuf) (fp); + + fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = + fp->_IO_buf_base; + } + + fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = + fp->_IO_buf_base; + + if (fp->_wide_data->_IO_buf_base == NULL) + { + /* Maybe we already have a push back pointer. */ + if (fp->_wide_data->_IO_save_base != NULL) + { + free (fp->_wide_data->_IO_save_base); + fp->_flags &= ~_IO_IN_BACKUP; + } + INTUSE(_IO_wdoallocbuf) (fp); + } + + /* Flush all line buffered files before reading. */ + /* FIXME This can/should be moved to genops ?? */ + if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED)) + { +#if 0 + INTUSE(_IO_flush_all_linebuffered) (); +#else + /* We used to flush all line-buffered stream. This really isn't + required by any standard. My recollection is that + traditional Unix systems did this for stdout. stderr better + not be line buffered. So we do just that here + explicitly. --drepper */ + _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, + _IO_stdout); + _IO_flockfile (_IO_stdout); + + if ((_IO_stdout->_flags & (_IO_LINKED | _IO_NO_WRITES | _IO_LINE_BUF)) + == (_IO_LINKED | _IO_LINE_BUF)) + _IO_OVERFLOW (_IO_stdout, EOF); + + _IO_funlockfile (_IO_stdout); + _IO_cleanup_region_end (0); +#endif + } + + INTUSE(_IO_switch_to_get_mode) (fp); + + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr = + fp->_wide_data->_IO_buf_base; + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_buf_base; + fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_write_ptr = + fp->_wide_data->_IO_write_end = fp->_wide_data->_IO_buf_base; + + tries = 0; + again: + count = _IO_SYSREAD (fp, fp->_IO_read_end, + fp->_IO_buf_end - fp->_IO_read_end); + if (count <= 0) + { + if (count == 0 && tries == 0) + fp->_flags |= _IO_EOF_SEEN; + else + fp->_flags |= _IO_ERR_SEEN, count = 0; + } + fp->_IO_read_end += count; + if (count == 0) + { + if (tries != 0) + /* There are some bytes in the external buffer but they don't + convert to anything. */ + __set_errno (EILSEQ); + return WEOF; + } + if (fp->_offset != _IO_pos_BAD) + _IO_pos_adjust (fp->_offset, count); + + /* Now convert the read input. */ + fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state; + fp->_IO_read_base = fp->_IO_read_ptr; + status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state, + fp->_IO_read_ptr, fp->_IO_read_end, + &read_ptr_copy, + fp->_wide_data->_IO_read_end, + fp->_wide_data->_IO_buf_end, + &fp->_wide_data->_IO_read_end); + + fp->_IO_read_ptr = (char *) read_ptr_copy; + if (fp->_wide_data->_IO_read_end == fp->_wide_data->_IO_buf_base) + { + if (status == __codecvt_error || fp->_IO_read_end == fp->_IO_buf_end) + { + __set_errno (EILSEQ); + fp->_flags |= _IO_ERR_SEEN; + return WEOF; + } + + /* The read bytes make no complete character. Try reading again. */ + assert (status == __codecvt_partial); + ++tries; + goto again; + } + + return *fp->_wide_data->_IO_read_ptr; +} +INTDEF(_IO_wfile_underflow) + + +static wint_t +_IO_wfile_underflow_mmap (_IO_FILE *fp) +{ + struct _IO_codecvt *cd; + enum __codecvt_result status; + const char *read_stop; + + if (__builtin_expect (fp->_flags & _IO_NO_READS, 0)) + { + fp->_flags |= _IO_ERR_SEEN; + __set_errno (EBADF); + return WEOF; + } + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + return *fp->_wide_data->_IO_read_ptr; + + cd = fp->_codecvt; + + /* Maybe there is something left in the external buffer. */ + if (fp->_IO_read_ptr >= fp->_IO_read_end + /* No. But maybe the read buffer is not fully set up. */ + && _IO_file_underflow_mmap (fp) == EOF) + /* Nothing available. _IO_file_underflow_mmap has set the EOF or error + flags as appropriate. */ + return WEOF; + + /* There is more in the external. Convert it. */ + read_stop = (const char *) fp->_IO_read_ptr; + + if (fp->_wide_data->_IO_buf_base == NULL) + { + /* Maybe we already have a push back pointer. */ + if (fp->_wide_data->_IO_save_base != NULL) + { + free (fp->_wide_data->_IO_save_base); + fp->_flags &= ~_IO_IN_BACKUP; + } + INTUSE(_IO_wdoallocbuf) (fp); + } + + fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state; + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr = + fp->_wide_data->_IO_buf_base; + status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state, + fp->_IO_read_ptr, fp->_IO_read_end, + &read_stop, + fp->_wide_data->_IO_read_ptr, + fp->_wide_data->_IO_buf_end, + &fp->_wide_data->_IO_read_end); + + fp->_IO_read_ptr = (char *) read_stop; + + /* If we managed to generate some text return the next character. */ + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + return *fp->_wide_data->_IO_read_ptr; + + /* There is some garbage at the end of the file. */ + __set_errno (EILSEQ); + fp->_flags |= _IO_ERR_SEEN; + return WEOF; +} + +static wint_t +_IO_wfile_underflow_maybe_mmap (_IO_FILE *fp) +{ + /* This is the first read attempt. Doing the underflow will choose mmap + or vanilla operations and then punt to the chosen underflow routine. + Then we can punt to ours. */ + if (_IO_file_underflow_maybe_mmap (fp) == EOF) + return WEOF; + + return _IO_WUNDERFLOW (fp); +} + + +wint_t +_IO_wfile_overflow (f, wch) + _IO_FILE *f; + wint_t wch; +{ + if (f->_flags & _IO_NO_WRITES) /* SET ERROR */ + { + f->_flags |= _IO_ERR_SEEN; + __set_errno (EBADF); + return WEOF; + } + /* If currently reading or no buffer allocated. */ + if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0) + { + /* Allocate a buffer if needed. */ + if (f->_wide_data->_IO_write_base == 0) + { + INTUSE(_IO_wdoallocbuf) (f); + _IO_wsetg (f, f->_wide_data->_IO_buf_base, + f->_wide_data->_IO_buf_base, f->_wide_data->_IO_buf_base); + + if (f->_IO_write_base == NULL) + { + INTUSE(_IO_doallocbuf) (f); + _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base); + } + } + else + { + /* Otherwise must be currently reading. If _IO_read_ptr + (and hence also _IO_read_end) is at the buffer end, + logically slide the buffer forwards one block (by setting + the read pointers to all point at the beginning of the + block). This makes room for subsequent output. + Otherwise, set the read pointers to _IO_read_end (leaving + that alone, so it can continue to correspond to the + external position). */ + if (f->_wide_data->_IO_read_ptr == f->_wide_data->_IO_buf_end) + { + f->_IO_read_end = f->_IO_read_ptr = f->_IO_buf_base; + f->_wide_data->_IO_read_end = f->_wide_data->_IO_read_ptr = + f->_wide_data->_IO_buf_base; + } + } + f->_wide_data->_IO_write_ptr = f->_wide_data->_IO_read_ptr; + f->_wide_data->_IO_write_base = f->_wide_data->_IO_write_ptr; + f->_wide_data->_IO_write_end = f->_wide_data->_IO_buf_end; + f->_wide_data->_IO_read_base = f->_wide_data->_IO_read_ptr = + f->_wide_data->_IO_read_end; + + f->_IO_write_ptr = f->_IO_read_ptr; + f->_IO_write_base = f->_IO_write_ptr; + f->_IO_write_end = f->_IO_buf_end; + f->_IO_read_base = f->_IO_read_ptr = f->_IO_read_end; + + f->_flags |= _IO_CURRENTLY_PUTTING; + if (f->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED)) + f->_wide_data->_IO_write_end = f->_wide_data->_IO_write_ptr; + } + if (wch == WEOF) + return _IO_do_flush (f); + if (f->_wide_data->_IO_write_ptr == f->_wide_data->_IO_buf_end) + /* Buffer is really full */ + if (_IO_do_flush (f) == EOF) + return WEOF; + *f->_wide_data->_IO_write_ptr++ = wch; + if ((f->_flags & _IO_UNBUFFERED) + || ((f->_flags & _IO_LINE_BUF) && wch == L'\n')) + if (_IO_do_flush (f) == EOF) + return WEOF; + return wch; +} +INTDEF(_IO_wfile_overflow) + +wint_t +_IO_wfile_sync (fp) + _IO_FILE *fp; +{ + _IO_ssize_t delta; + wint_t retval = 0; + + /* char* ptr = cur_ptr(); */ + if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base) + if (_IO_do_flush (fp)) + return WEOF; + delta = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_end; + if (delta != 0) + { + /* We have to find out how many bytes we have to go back in the + external buffer. */ + struct _IO_codecvt *cv = fp->_codecvt; + _IO_off64_t new_pos; + + int clen = (*cv->__codecvt_do_encoding) (cv); + + if (clen > 0) + /* It is easy, a fixed number of input bytes are used for each + wide character. */ + delta *= clen; + else + { + /* We have to find out the hard way how much to back off. + To do this we determine how much input we needed to + generate the wide characters up to the current reading + position. */ + int nread; + + fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state; + nread = (*cv->__codecvt_do_length) (cv, &fp->_wide_data->_IO_state, + fp->_IO_read_base, + fp->_IO_read_end, delta); + fp->_IO_read_ptr = fp->_IO_read_base + nread; + delta = -(fp->_IO_read_end - fp->_IO_read_base - nread); + } + + new_pos = _IO_SYSSEEK (fp, delta, 1); + if (new_pos != (_IO_off64_t) EOF) + { + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_read_ptr; + fp->_IO_read_end = fp->_IO_read_ptr; + } +#ifdef ESPIPE + else if (errno == ESPIPE) + ; /* Ignore error from unseekable devices. */ +#endif + else + retval = WEOF; + } + if (retval != WEOF) + fp->_offset = _IO_pos_BAD; + /* FIXME: Cleanup - can this be shared? */ + /* setg(base(), ptr, ptr); */ + return retval; +} +INTDEF(_IO_wfile_sync) + +_IO_off64_t +_IO_wfile_seekoff (fp, offset, dir, mode) + _IO_FILE *fp; + _IO_off64_t offset; + int dir; + int mode; +{ + _IO_off64_t result; + _IO_off64_t delta, new_offset; + long int count; + /* POSIX.1 8.2.3.7 says that after a call the fflush() the file + offset of the underlying file must be exact. */ + int must_be_exact = ((fp->_wide_data->_IO_read_base + == fp->_wide_data->_IO_read_end) + && (fp->_wide_data->_IO_write_base + == fp->_wide_data->_IO_write_ptr)); + + if (mode == 0) + { + /* XXX For wide stream with backup store it is not very + reasonable to determine the offset. The pushed-back + character might require a state change and we need not be + able to compute the initial state by reverse transformation + since there is no guarantee of symmetry. So we don't even + try and return an error. */ + if (_IO_in_backup (fp)) + { + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + { + __set_errno (EINVAL); + return -1; + } + + /* There is no more data in the backup buffer. We can + switch back. */ + INTUSE(_IO_switch_to_main_wget_area) (fp); + } + + dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */ + } + + /* Flush unwritten characters. + (This may do an unneeded write if we seek within the buffer. + But to be able to switch to reading, we would need to set + egptr to ptr. That can't be done in the current design, + which assumes file_ptr() is eGptr. Anyway, since we probably + end up flushing when we close(), it doesn't make much difference.) + FIXME: simulate mem-mapped files. */ + + if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base + || _IO_in_put_mode (fp)) + if (INTUSE(_IO_switch_to_wget_mode) (fp)) + return WEOF; + + if (fp->_wide_data->_IO_buf_base == NULL) + { + /* It could be that we already have a pushback buffer. */ + if (fp->_wide_data->_IO_read_base != NULL) + { + free (fp->_wide_data->_IO_read_base); + fp->_flags &= ~_IO_IN_BACKUP; + } + INTUSE(_IO_doallocbuf) (fp); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); + _IO_wsetp (fp, fp->_wide_data->_IO_buf_base, + fp->_wide_data->_IO_buf_base); + _IO_wsetg (fp, fp->_wide_data->_IO_buf_base, + fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base); + } + + switch (dir) + { + struct _IO_codecvt *cv; + int clen; + + case _IO_seek_cur: + /* Adjust for read-ahead (bytes is buffer). To do this we must + find out which position in the external buffer corresponds to + the current position in the internal buffer. */ + cv = fp->_codecvt; + clen = (*cv->__codecvt_do_encoding) (cv); + + if (clen > 0) + offset -= (fp->_wide_data->_IO_read_end + - fp->_wide_data->_IO_read_ptr) * clen; + else + { + int nread; + + delta = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_base; + fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state; + nread = (*cv->__codecvt_do_length) (cv, &fp->_wide_data->_IO_state, + fp->_IO_read_base, + fp->_IO_read_end, delta); + fp->_IO_read_ptr = fp->_IO_read_base + nread; + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_read_ptr; + offset -= fp->_IO_read_end - fp->_IO_read_base - nread; + } + + if (fp->_offset == _IO_pos_BAD) + goto dumb; + /* Make offset absolute, assuming current pointer is file_ptr(). */ + offset += fp->_offset; + + dir = _IO_seek_set; + break; + case _IO_seek_set: + break; + case _IO_seek_end: + { + struct _G_stat64 st; + if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode)) + { + offset += st.st_size; + dir = _IO_seek_set; + } + else + goto dumb; + } + } + /* At this point, dir==_IO_seek_set. */ + + /* If we are only interested in the current position we've found it now. */ + if (mode == 0) + return offset; + + /* If destination is within current buffer, optimize: */ + if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL + && !_IO_in_backup (fp)) + { + /* Offset relative to start of main get area. */ + _IO_off64_t rel_offset = (offset - fp->_offset + + (fp->_IO_read_end - fp->_IO_read_base)); + if (rel_offset >= 0) + { +#if 0 + if (_IO_in_backup (fp)) + _IO_switch_to_main_get_area (fp); +#endif + if (rel_offset <= fp->_IO_read_end - fp->_IO_read_base) + { + enum __codecvt_result status; + struct _IO_codecvt *cd = fp->_codecvt; + const char *read_ptr_copy; + + fp->_IO_read_ptr = fp->_IO_read_base + rel_offset; + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + + /* Now set the pointer for the internal buffer. This + might be an iterative process. Though the read + pointer is somewhere in the current external buffer + this does not mean we can convert this whole buffer + at once fitting in the internal buffer. */ + fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state; + read_ptr_copy = fp->_IO_read_base; + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_base; + do + { + wchar_t buffer[1024]; + wchar_t *ignore; + status = (*cd->__codecvt_do_in) (cd, + &fp->_wide_data->_IO_state, + read_ptr_copy, + fp->_IO_read_ptr, + &read_ptr_copy, + buffer, + buffer + + (sizeof (buffer) + / sizeof (buffer[0])), + &ignore); + if (status != __codecvt_ok && status != __codecvt_partial) + { + fp->_flags |= _IO_ERR_SEEN; + goto dumb; + } + } + while (read_ptr_copy != fp->_IO_read_ptr); + + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_base; + + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + goto resync; + } +#ifdef TODO + /* If we have streammarkers, seek forward by reading ahead. */ + if (_IO_have_markers (fp)) + { + int to_skip = rel_offset + - (fp->_IO_read_ptr - fp->_IO_read_base); + if (ignore (to_skip) != to_skip) + goto dumb; + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + goto resync; + } +#endif + } +#ifdef TODO + if (rel_offset < 0 && rel_offset >= Bbase () - Bptr ()) + { + if (!_IO_in_backup (fp)) + _IO_switch_to_backup_area (fp); + gbump (fp->_IO_read_end + rel_offset - fp->_IO_read_ptr); + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + goto resync; + } +#endif + } + +#ifdef TODO + INTUSE(_IO_unsave_markers) (fp); +#endif + + if (fp->_flags & _IO_NO_READS) + goto dumb; + + /* Try to seek to a block boundary, to improve kernel page management. */ + new_offset = offset & ~(fp->_IO_buf_end - fp->_IO_buf_base - 1); + delta = offset - new_offset; + if (delta > fp->_IO_buf_end - fp->_IO_buf_base) + { + new_offset = offset; + delta = 0; + } + result = _IO_SYSSEEK (fp, new_offset, 0); + if (result < 0) + return EOF; + if (delta == 0) + count = 0; + else + { + count = _IO_SYSREAD (fp, fp->_IO_buf_base, + (must_be_exact + ? delta : fp->_IO_buf_end - fp->_IO_buf_base)); + if (count < delta) + { + /* We weren't allowed to read, but try to seek the remainder. */ + offset = count == EOF ? delta : delta-count; + dir = _IO_seek_cur; + goto dumb; + } + } + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + delta, + fp->_IO_buf_base + count); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + fp->_offset = result + count; + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + return offset; + dumb: + + INTUSE(_IO_unsave_markers) (fp); + result = _IO_SYSSEEK (fp, offset, dir); + if (result != EOF) + { + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + fp->_offset = result; + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + _IO_wsetg (fp, fp->_wide_data->_IO_buf_base, + fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base); + _IO_wsetp (fp, fp->_wide_data->_IO_buf_base, + fp->_wide_data->_IO_buf_base); + } + return result; + +resync: + /* We need to do it since it is possible that the file offset in + the kernel may be changed behind our back. It may happen when + we fopen a file and then do a fork. One process may access the + the file and the kernel file offset will be changed. */ + if (fp->_offset >= 0) + _IO_SYSSEEK (fp, fp->_offset, 0); + + return offset; +} +INTDEF(_IO_wfile_seekoff) + + +_IO_size_t +_IO_wfile_xsputn (f, data, n) + _IO_FILE *f; + const void *data; + _IO_size_t n; +{ + register const wchar_t *s = (const wchar_t *) data; + _IO_size_t to_do = n; + int must_flush = 0; + _IO_size_t count; + + if (n <= 0) + return 0; + /* This is an optimized implementation. + If the amount to be written straddles a block boundary + (or the filebuf is unbuffered), use sys_write directly. */ + + /* First figure out how much space is available in the buffer. */ + count = f->_wide_data->_IO_write_end - f->_wide_data->_IO_write_ptr; + if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING)) + { + count = f->_wide_data->_IO_buf_end - f->_wide_data->_IO_write_ptr; + if (count >= n) + { + register const wchar_t *p; + for (p = s + n; p > s; ) + { + if (*--p == L'\n') + { + count = p - s + 1; + must_flush = 1; + break; + } + } + } + } + /* Then fill the buffer. */ + if (count > 0) + { + if (count > to_do) + count = to_do; + if (count > 20) + { +#ifdef _LIBC + f->_wide_data->_IO_write_ptr = + __wmempcpy (f->_wide_data->_IO_write_ptr, s, count); +#else + wmemcpy (f->_wide_data->_IO_write_ptr, s, count); + f->_wide_data->_IO_write_ptr += count; +#endif + s += count; + } + else + { + register wchar_t *p = f->_wide_data->_IO_write_ptr; + register int i = (int) count; + while (--i >= 0) + *p++ = *s++; + f->_wide_data->_IO_write_ptr = p; + } + to_do -= count; + } + if (to_do > 0) + to_do -= INTUSE(_IO_wdefault_xsputn) (f, s, to_do); + if (must_flush + && f->_wide_data->_IO_write_ptr != f->_wide_data->_IO_write_base) + INTUSE(_IO_wdo_write) (f, f->_wide_data->_IO_write_base, + f->_wide_data->_IO_write_ptr + - f->_wide_data->_IO_write_base); + + return n - to_do; +} +INTDEF(_IO_wfile_xsputn) + + +struct _IO_jump_t _IO_wfile_jumps = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_new_file_finish), + JUMP_INIT(overflow, (_IO_overflow_t) INTUSE(_IO_wfile_overflow)), + JUMP_INIT(underflow, (_IO_underflow_t) INTUSE(_IO_wfile_underflow)), + JUMP_INIT(uflow, (_IO_underflow_t) INTUSE(_IO_wdefault_uflow)), + JUMP_INIT(pbackfail, (_IO_pbackfail_t) INTUSE(_IO_wdefault_pbackfail)), + JUMP_INIT(xsputn, INTUSE(_IO_wfile_xsputn)), + JUMP_INIT(xsgetn, INTUSE(_IO_file_xsgetn)), + JUMP_INIT(seekoff, INTUSE(_IO_wfile_seekoff)), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_new_file_setbuf), + JUMP_INIT(sync, (_IO_sync_t) INTUSE(_IO_wfile_sync)), + JUMP_INIT(doallocate, _IO_wfile_doallocate), + JUMP_INIT(read, INTUSE(_IO_file_read)), + JUMP_INIT(write, _IO_new_file_write), + JUMP_INIT(seek, INTUSE(_IO_file_seek)), + JUMP_INIT(close, INTUSE(_IO_file_close)), + JUMP_INIT(stat, INTUSE(_IO_file_stat)), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; +INTVARDEF(_IO_wfile_jumps) + + +struct _IO_jump_t _IO_wfile_jumps_mmap = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_new_file_finish), + JUMP_INIT(overflow, (_IO_overflow_t) INTUSE(_IO_wfile_overflow)), + JUMP_INIT(underflow, (_IO_underflow_t) _IO_wfile_underflow_mmap), + JUMP_INIT(uflow, (_IO_underflow_t) INTUSE(_IO_wdefault_uflow)), + JUMP_INIT(pbackfail, (_IO_pbackfail_t) INTUSE(_IO_wdefault_pbackfail)), + JUMP_INIT(xsputn, INTUSE(_IO_wfile_xsputn)), + JUMP_INIT(xsgetn, INTUSE(_IO_file_xsgetn)), + JUMP_INIT(seekoff, INTUSE(_IO_wfile_seekoff)), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_file_setbuf_mmap), + JUMP_INIT(sync, (_IO_sync_t) INTUSE(_IO_wfile_sync)), + JUMP_INIT(doallocate, _IO_wfile_doallocate), + JUMP_INIT(read, INTUSE(_IO_file_read)), + JUMP_INIT(write, _IO_new_file_write), + JUMP_INIT(seek, INTUSE(_IO_file_seek)), + JUMP_INIT(close, _IO_file_close_mmap), + JUMP_INIT(stat, INTUSE(_IO_file_stat)), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; + +struct _IO_jump_t _IO_wfile_jumps_maybe_mmap = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_new_file_finish), + JUMP_INIT(overflow, (_IO_overflow_t) INTUSE(_IO_wfile_overflow)), + JUMP_INIT(underflow, (_IO_underflow_t) _IO_wfile_underflow_maybe_mmap), + JUMP_INIT(uflow, (_IO_underflow_t) INTUSE(_IO_wdefault_uflow)), + JUMP_INIT(pbackfail, (_IO_pbackfail_t) INTUSE(_IO_wdefault_pbackfail)), + JUMP_INIT(xsputn, INTUSE(_IO_wfile_xsputn)), + JUMP_INIT(xsgetn, INTUSE(_IO_file_xsgetn)), + JUMP_INIT(seekoff, INTUSE(_IO_wfile_seekoff)), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_file_setbuf_mmap), + JUMP_INIT(sync, (_IO_sync_t) INTUSE(_IO_wfile_sync)), + JUMP_INIT(doallocate, _IO_wfile_doallocate), + JUMP_INIT(read, INTUSE(_IO_file_read)), + JUMP_INIT(write, _IO_new_file_write), + JUMP_INIT(seek, INTUSE(_IO_file_seek)), + JUMP_INIT(close, INTUSE(_IO_file_close)), + JUMP_INIT(stat, INTUSE(_IO_file_stat)), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; diff --git a/src/kernel/libroot/posix/glibc/libio/wgenops.c b/src/kernel/libroot/posix/glibc/libio/wgenops.c new file mode 100644 index 0000000000..1eb9fb26c9 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/wgenops.c @@ -0,0 +1,746 @@ +/* Copyright (C) 1993,1995,1997-2001,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Ulrich Drepper . + Based on the single byte version by Per Bothner . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +/* Generic or default I/O operations. */ + +#include "libioP.h" +#ifdef __STDC__ +#include +#endif +#include +#include + + +#ifndef _LIBC +# define __wmemcpy(dst, src, n) wmemcpy (dst, src, n) +#endif + + +static int save_for_wbackup __P ((_IO_FILE *fp, wchar_t *end_p)) +#ifdef _LIBC + internal_function +#endif + ; + +/* Return minimum _pos markers + Assumes the current get area is the main get area. */ +_IO_ssize_t _IO_least_wmarker __P ((_IO_FILE *fp, wchar_t *end_p)); + +_IO_ssize_t +_IO_least_wmarker (fp, end_p) + _IO_FILE *fp; + wchar_t *end_p; +{ + _IO_ssize_t least_so_far = end_p - fp->_wide_data->_IO_read_base; + struct _IO_marker *mark; + for (mark = fp->_markers; mark != NULL; mark = mark->_next) + if (mark->_pos < least_so_far) + least_so_far = mark->_pos; + return least_so_far; +} +INTDEF(_IO_least_wmarker) + +/* Switch current get area from backup buffer to (start of) main get area. */ +void +_IO_switch_to_main_wget_area (fp) + _IO_FILE *fp; +{ + wchar_t *tmp; + fp->_flags &= ~_IO_IN_BACKUP; + /* Swap _IO_read_end and _IO_save_end. */ + tmp = fp->_wide_data->_IO_read_end; + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_save_end; + fp->_wide_data->_IO_save_end= tmp; + /* Swap _IO_read_base and _IO_save_base. */ + tmp = fp->_wide_data->_IO_read_base; + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_save_base; + fp->_wide_data->_IO_save_base = tmp; + /* Set _IO_read_ptr. */ + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_base; +} +INTDEF(_IO_switch_to_main_wget_area) + + +/* Switch current get area from main get area to (end of) backup area. */ +void +_IO_switch_to_wbackup_area (fp) + _IO_FILE *fp; +{ + wchar_t *tmp; + fp->_flags |= _IO_IN_BACKUP; + /* Swap _IO_read_end and _IO_save_end. */ + tmp = fp->_wide_data->_IO_read_end; + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_save_end; + fp->_wide_data->_IO_save_end = tmp; + /* Swap _IO_read_base and _IO_save_base. */ + tmp = fp->_wide_data->_IO_read_base; + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_save_base; + fp->_wide_data->_IO_save_base = tmp; + /* Set _IO_read_ptr. */ + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end; +} +INTDEF(_IO_switch_to_wbackup_area) + + +void +_IO_wsetb (f, b, eb, a) + _IO_FILE *f; + wchar_t *b; + wchar_t *eb; + int a; +{ + if (f->_wide_data->_IO_buf_base && !(f->_flags & _IO_USER_BUF)) + FREE_BUF (f->_wide_data->_IO_buf_base, _IO_wblen (f)); + f->_wide_data->_IO_buf_base = b; + f->_wide_data->_IO_buf_end = eb; + if (a) + f->_flags &= ~_IO_USER_BUF; + else + f->_flags |= _IO_USER_BUF; +} +INTDEF(_IO_wsetb) + + +wint_t +_IO_wdefault_pbackfail (fp, c) + _IO_FILE *fp; + wint_t c; +{ + if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base + && !_IO_in_backup (fp) + && (wint_t) fp->_IO_read_ptr[-1] == c) + --fp->_IO_read_ptr; + else + { + /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/ + if (!_IO_in_backup (fp)) + { + /* We need to keep the invariant that the main get area + logically follows the backup area. */ + if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base + && _IO_have_wbackup (fp)) + { + if (save_for_wbackup (fp, fp->_wide_data->_IO_read_ptr)) + return WEOF; + } + else if (!_IO_have_wbackup (fp)) + { + /* No backup buffer: allocate one. */ + /* Use nshort buffer, if unused? (probably not) FIXME */ + int backup_size = 128; + wchar_t *bbuf = (wchar_t *) malloc (backup_size + * sizeof (wchar_t)); + if (bbuf == NULL) + return WEOF; + fp->_wide_data->_IO_save_base = bbuf; + fp->_wide_data->_IO_save_end = (fp->_wide_data->_IO_save_base + + backup_size); + fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_save_end; + } + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr; + INTUSE(_IO_switch_to_wbackup_area) (fp); + } + else if (fp->_wide_data->_IO_read_ptr <= fp->_wide_data->_IO_read_base) + { + /* Increase size of existing backup buffer. */ + _IO_size_t new_size; + _IO_size_t old_size = (fp->_wide_data->_IO_read_end + - fp->_wide_data->_IO_read_base); + wchar_t *new_buf; + new_size = 2 * old_size; + new_buf = (wchar_t *) malloc (new_size * sizeof (wchar_t)); + if (new_buf == NULL) + return WEOF; + __wmemcpy (new_buf + (new_size - old_size), + fp->_wide_data->_IO_read_base, old_size); + free (fp->_wide_data->_IO_read_base); + _IO_wsetg (fp, new_buf, new_buf + (new_size - old_size), + new_buf + new_size); + fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_read_ptr; + } + + *--fp->_wide_data->_IO_read_ptr = c; + } + return c; +} +INTDEF(_IO_wdefault_pbackfail) + + +void +_IO_wdefault_finish (fp, dummy) + _IO_FILE *fp; + int dummy; +{ + struct _IO_marker *mark; + if (fp->_wide_data->_IO_buf_base && !(fp->_flags & _IO_USER_BUF)) + { + FREE_BUF (fp->_wide_data->_IO_buf_base, + _IO_wblen (fp) * sizeof (wchar_t)); + fp->_wide_data->_IO_buf_base = fp->_wide_data->_IO_buf_end = NULL; + } + + for (mark = fp->_markers; mark != NULL; mark = mark->_next) + mark->_sbuf = NULL; + + if (fp->_IO_save_base) + { + free (fp->_wide_data->_IO_save_base); + fp->_IO_save_base = NULL; + } + +#ifdef _IO_MTSAFE_IO + if (fp->_lock != NULL) + _IO_lock_fini (*fp->_lock); +#endif + + INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp); +} +INTDEF(_IO_wdefault_finish) + + +wint_t +_IO_wdefault_uflow (fp) + _IO_FILE *fp; +{ + wint_t wch; + wch = _IO_UNDERFLOW (fp); + if (wch == WEOF) + return WEOF; + return *fp->_wide_data->_IO_read_ptr++; +} +INTDEF(_IO_wdefault_uflow) + + +wint_t +__woverflow (f, wch) + _IO_FILE *f; + wint_t wch; +{ + if (f->_mode == 0) + _IO_fwide (f, 1); + return _IO_OVERFLOW (f, wch); +} +libc_hidden_def (__woverflow) + + +wint_t +__wuflow (fp) + _IO_FILE *fp; +{ + if (fp->_mode < 0 || (fp->_mode == 0 && _IO_fwide (fp, 1) != 1)) + return WEOF; + + if (fp->_mode == 0) + _IO_fwide (fp, 1); + if (_IO_in_put_mode (fp)) + if (INTUSE(_IO_switch_to_wget_mode) (fp) == EOF) + return WEOF; + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + return *fp->_wide_data->_IO_read_ptr++; + if (_IO_in_backup (fp)) + { + INTUSE(_IO_switch_to_main_wget_area) (fp); + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + return *fp->_wide_data->_IO_read_ptr++; + } + if (_IO_have_markers (fp)) + { + if (save_for_wbackup (fp, fp->_wide_data->_IO_read_end)) + return WEOF; + } + else if (_IO_have_wbackup (fp)) + INTUSE(_IO_free_wbackup_area) (fp); + return _IO_UFLOW (fp); +} +libc_hidden_def (__wuflow) + +wint_t +__wunderflow (fp) + _IO_FILE *fp; +{ + if (fp->_mode < 0 || (fp->_mode == 0 && _IO_fwide (fp, 1) != 1)) + return WEOF; + + if (fp->_mode == 0) + _IO_fwide (fp, 1); + if (_IO_in_put_mode (fp)) + if (INTUSE(_IO_switch_to_wget_mode) (fp) == EOF) + return WEOF; + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + return *fp->_wide_data->_IO_read_ptr; + if (_IO_in_backup (fp)) + { + INTUSE(_IO_switch_to_main_wget_area) (fp); + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + return *fp->_wide_data->_IO_read_ptr; + } + if (_IO_have_markers (fp)) + { + if (save_for_wbackup (fp, fp->_wide_data->_IO_read_end)) + return WEOF; + } + else if (_IO_have_backup (fp)) + INTUSE(_IO_free_wbackup_area) (fp); + return _IO_UNDERFLOW (fp); +} +libc_hidden_def (__wunderflow) + + +_IO_size_t +_IO_wdefault_xsputn (f, data, n) + _IO_FILE *f; + const void *data; + _IO_size_t n; +{ + const wchar_t *s = (const wchar_t *) data; + _IO_size_t more = n; + if (more <= 0) + return 0; + for (;;) + { + /* Space available. */ + _IO_ssize_t count = (f->_wide_data->_IO_write_end + - f->_wide_data->_IO_write_ptr); + if (count > 0) + { + if ((_IO_size_t) count > more) + count = more; + if (count > 20) + { +#ifdef _LIBC + f->_wide_data->_IO_write_ptr = + __wmempcpy (f->_wide_data->_IO_write_ptr, s, count); +#else + memcpy (f->_wide_data->_IO_write_ptr, s, count); + f->_wide_data->_IO_write_ptr += count; +#endif + s += count; + } + else if (count <= 0) + count = 0; + else + { + wchar_t *p = f->_wide_data->_IO_write_ptr; + _IO_ssize_t i; + for (i = count; --i >= 0; ) + *p++ = *s++; + f->_wide_data->_IO_write_ptr = p; + } + more -= count; + } + if (more == 0 || __woverflow (f, *s++) == WEOF) + break; + more--; + } + return n - more; +} +INTDEF(_IO_wdefault_xsputn) + + +_IO_size_t +_IO_wdefault_xsgetn (fp, data, n) + _IO_FILE *fp; + void *data; + _IO_size_t n; +{ + _IO_size_t more = n; + wchar_t *s = (wchar_t*) data; + for (;;) + { + /* Data available. */ + _IO_ssize_t count = (fp->_wide_data->_IO_read_end + - fp->_wide_data->_IO_read_ptr); + if (count > 0) + { + if ((_IO_size_t) count > more) + count = more; + if (count > 20) + { +#ifdef _LIBC + s = __wmempcpy (s, fp->_wide_data->_IO_read_ptr, count); +#else + memcpy (s, fp->_wide_data->_IO_read_ptr, count); + s += count; +#endif + fp->_wide_data->_IO_read_ptr += count; + } + else if (count <= 0) + count = 0; + else + { + wchar_t *p = fp->_wide_data->_IO_read_ptr; + int i = (int) count; + while (--i >= 0) + *s++ = *p++; + fp->_wide_data->_IO_read_ptr = p; + } + more -= count; + } + if (more == 0 || __wunderflow (fp) == WEOF) + break; + } + return n - more; +} +INTDEF(_IO_wdefault_xsgetn) + + +void +_IO_wdoallocbuf (fp) + _IO_FILE *fp; +{ + if (fp->_wide_data->_IO_buf_base) + return; + if (!(fp->_flags & _IO_UNBUFFERED)) + if ((wint_t)_IO_WDOALLOCATE (fp) != WEOF) + return; + INTUSE(_IO_wsetb) (fp, fp->_wide_data->_shortbuf, + fp->_wide_data->_shortbuf + 1, 0); +} +INTDEF(_IO_wdoallocbuf) + + +int +_IO_wdefault_doallocate (fp) + _IO_FILE *fp; +{ + wchar_t *buf; + + ALLOC_WBUF (buf, _IO_BUFSIZ, EOF); + INTUSE(_IO_wsetb) (fp, buf, buf + _IO_BUFSIZ, 1); + return 1; +} +INTDEF(_IO_wdefault_doallocate) + + +int +_IO_switch_to_wget_mode (fp) + _IO_FILE *fp; +{ + if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base) + if ((wint_t)_IO_WOVERFLOW (fp, WEOF) == WEOF) + return EOF; + if (_IO_in_backup (fp)) + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_backup_base; + else + { + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_buf_base; + if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end) + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr; + } + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_write_ptr; + + fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_write_ptr + = fp->_wide_data->_IO_write_end = fp->_wide_data->_IO_read_ptr; + + fp->_flags &= ~_IO_CURRENTLY_PUTTING; + return 0; +} +INTDEF(_IO_switch_to_wget_mode) + +void +_IO_free_wbackup_area (fp) + _IO_FILE *fp; +{ + if (_IO_in_backup (fp)) + INTUSE(_IO_switch_to_main_wget_area) (fp); /* Just in case. */ + free (fp->_wide_data->_IO_save_base); + fp->_wide_data->_IO_save_base = NULL; + fp->_wide_data->_IO_save_end = NULL; + fp->_wide_data->_IO_backup_base = NULL; +} +INTDEF(_IO_free_wbackup_area) + +#if 0 +int +_IO_switch_to_wput_mode (fp) + _IO_FILE *fp; +{ + fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_read_ptr; + fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_read_ptr; + /* Following is wrong if line- or un-buffered? */ + fp->_wide_data->_IO_write_end = (fp->_flags & _IO_IN_BACKUP + ? fp->_wide_data->_IO_read_end + : fp->_wide_data->_IO_buf_end); + + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end; + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_end; + + fp->_flags |= _IO_CURRENTLY_PUTTING; + return 0; +} +#endif + + +static int +#ifdef _LIBC +internal_function +#endif +save_for_wbackup (fp, end_p) + _IO_FILE *fp; + wchar_t *end_p; +{ + /* Append [_IO_read_base..end_p] to backup area. */ + _IO_ssize_t least_mark = INTUSE(_IO_least_wmarker) (fp, end_p); + /* needed_size is how much space we need in the backup area. */ + _IO_size_t needed_size = ((end_p - fp->_wide_data->_IO_read_base) + - least_mark); + /* FIXME: Dubious arithmetic if pointers are NULL */ + _IO_size_t current_Bsize = (fp->_wide_data->_IO_save_end + - fp->_wide_data->_IO_save_base); + _IO_size_t avail; /* Extra space available for future expansion. */ + _IO_ssize_t delta; + struct _IO_marker *mark; + if (needed_size > current_Bsize) + { + wchar_t *new_buffer; + avail = 100; + new_buffer = (wchar_t *) malloc ((avail + needed_size) + * sizeof (wchar_t)); + if (new_buffer == NULL) + return EOF; /* FIXME */ + if (least_mark < 0) + { +#ifdef _LIBC + __wmempcpy (__wmempcpy (new_buffer + avail, + fp->_wide_data->_IO_save_end + least_mark, + -least_mark), + fp->_wide_data->_IO_read_base, + end_p - fp->_wide_data->_IO_read_base); +#else + memcpy (new_buffer + avail, + fp->_wide_data->_IO_save_end + least_mark, + -least_mark * sizeof (wchar_t)); + memcpy (new_buffer + avail - least_mark, + fp->_wide_data->_IO_read_base, + (end_p - fp->_wide_data->_IO_read_base) * sizeof (wchar_t)); +#endif + } + else + { +#ifdef _LIBC + __wmemcpy (new_buffer + avail, + fp->_wide_data->_IO_read_base + least_mark, + needed_size); +#else + memcpy (new_buffer + avail, + fp->_wide_data->_IO_read_base + least_mark, + needed_size * sizeof (wchar_t)); +#endif + } + if (fp->_wide_data->_IO_save_base) + free (fp->_wide_data->_IO_save_base); + fp->_wide_data->_IO_save_base = new_buffer; + fp->_wide_data->_IO_save_end = new_buffer + avail + needed_size; + } + else + { + avail = current_Bsize - needed_size; + if (least_mark < 0) + { +#ifdef _LIBC + __wmemmove (fp->_wide_data->_IO_save_base + avail, + fp->_wide_data->_IO_save_end + least_mark, + -least_mark); + __wmemcpy (fp->_wide_data->_IO_save_base + avail - least_mark, + fp->_wide_data->_IO_read_base, + end_p - fp->_wide_data->_IO_read_base); +#else + memmove (fp->_wide_data->_IO_save_base + avail, + fp->_wide_data->_IO_save_end + least_mark, + -least_mark * sizeof (wchar_t)); + memcpy (fp->_wide_data->_IO_save_base + avail - least_mark, + fp->_wide_data->_IO_read_base, + (end_p - fp->_wide_data->_IO_read_base) * sizeof (wchar_t)); +#endif + } + else if (needed_size > 0) +#ifdef _LIBC + __wmemcpy (fp->_wide_data->_IO_save_base + avail, + fp->_wide_data->_IO_read_base + least_mark, + needed_size); +#else + memcpy (fp->_wide_data->_IO_save_base + avail, + fp->_wide_data->_IO_read_base + least_mark, + needed_size * sizeof (wchar_t)); +#endif + } + fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_save_base + avail; + /* Adjust all the streammarkers. */ + delta = end_p - fp->_wide_data->_IO_read_base; + for (mark = fp->_markers; mark != NULL; mark = mark->_next) + mark->_pos -= delta; + return 0; +} + +wint_t +_IO_sputbackwc (fp, c) + _IO_FILE *fp; + wint_t c; +{ + wint_t result; + + if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base + && (wchar_t)fp->_wide_data->_IO_read_ptr[-1] == (wchar_t) c) + { + fp->_wide_data->_IO_read_ptr--; + result = c; + } + else + result = _IO_PBACKFAIL (fp, c); + + if (result != WEOF) + fp->_flags &= ~_IO_EOF_SEEN; + + return result; +} +INTDEF(_IO_sputbackwc) + +wint_t +_IO_sungetwc (fp) + _IO_FILE *fp; +{ + wint_t result; + + if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base) + { + fp->_wide_data->_IO_read_ptr--; + result = *fp->_wide_data->_IO_read_ptr; + } + else + result = _IO_PBACKFAIL (fp, EOF); + + if (result != WEOF) + fp->_flags &= ~_IO_EOF_SEEN; + + return result; +} + + +unsigned +_IO_adjust_wcolumn (start, line, count) + unsigned start; + const wchar_t *line; + int count; +{ + const wchar_t *ptr = line + count; + while (ptr > line) + if (*--ptr == L'\n') + return line + count - ptr - 1; + return start + count; +} + +void +_IO_init_wmarker (marker, fp) + struct _IO_marker *marker; + _IO_FILE *fp; +{ + marker->_sbuf = fp; + if (_IO_in_put_mode (fp)) + INTUSE(_IO_switch_to_wget_mode) (fp); + if (_IO_in_backup (fp)) + marker->_pos = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_end; + else + marker->_pos = (fp->_wide_data->_IO_read_ptr + - fp->_wide_data->_IO_read_base); + + /* Should perhaps sort the chain? */ + marker->_next = fp->_markers; + fp->_markers = marker; +} + +#define BAD_DELTA EOF + +/* Return difference between MARK and current position of MARK's stream. */ +int +_IO_wmarker_delta (mark) + struct _IO_marker *mark; +{ + int cur_pos; + if (mark->_sbuf == NULL) + return BAD_DELTA; + if (_IO_in_backup (mark->_sbuf)) + cur_pos = (mark->_sbuf->_wide_data->_IO_read_ptr + - mark->_sbuf->_wide_data->_IO_read_end); + else + cur_pos = (mark->_sbuf->_wide_data->_IO_read_ptr + - mark->_sbuf->_wide_data->_IO_read_base); + return mark->_pos - cur_pos; +} + +int +_IO_seekwmark (fp, mark, delta) + _IO_FILE *fp; + struct _IO_marker *mark; + int delta; +{ + if (mark->_sbuf != fp) + return EOF; + if (mark->_pos >= 0) + { + if (_IO_in_backup (fp)) + INTUSE(_IO_switch_to_main_wget_area) (fp); + fp->_wide_data->_IO_read_ptr = (fp->_wide_data->_IO_read_base + + mark->_pos); + } + else + { + if (!_IO_in_backup (fp)) + INTUSE(_IO_switch_to_wbackup_area) (fp); + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end + mark->_pos; + } + return 0; +} + +void +_IO_unsave_wmarkers (fp) + _IO_FILE *fp; +{ + struct _IO_marker *mark = fp->_markers; + if (mark) + { +#ifdef TODO + streampos offset = seekoff (0, ios::cur, ios::in); + if (offset != EOF) + { + offset += eGptr () - Gbase (); + for ( ; mark != NULL; mark = mark->_next) + mark->set_streampos (mark->_pos + offset); + } + else + { + for ( ; mark != NULL; mark = mark->_next) + mark->set_streampos (EOF); + } +#endif + fp->_markers = 0; + } + + if (_IO_have_backup (fp)) + INTUSE(_IO_free_wbackup_area) (fp); +} diff --git a/src/kernel/libroot/posix/glibc/libio/wprintf.c b/src/kernel/libroot/posix/glibc/libio/wprintf.c new file mode 100644 index 0000000000..f418cf515d --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/wprintf.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1991,1995,1996,1997,1999,2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include + +/* Write formatted output to stdout from the format string FORMAT. */ +/* VARARGS1 */ +int +wprintf (const wchar_t *format, ...) +{ + va_list arg; + int done; + + va_start (arg, format); + done = __vfwprintf (stdout, format, arg); + va_end (arg); + + return done; +} diff --git a/src/kernel/libroot/posix/glibc/libio/wscanf.c b/src/kernel/libroot/posix/glibc/libio/wscanf.c new file mode 100644 index 0000000000..f4b8cd1b83 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/wscanf.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991, 1995, 1996, 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include + + +/* Read formatted input from stdin according to the format string FORMAT. */ +/* VARARGS1 */ +int +wscanf (const wchar_t *format, ...) +{ + va_list arg; + int done; + + va_start (arg, format); + done = _IO_vfwscanf (stdin, format, arg, NULL); + va_end (arg); + + return done; +} diff --git a/src/kernel/libroot/posix/glibc/libio/wstrops.c b/src/kernel/libroot/posix/glibc/libio/wstrops.c new file mode 100644 index 0000000000..3c9c4971e8 --- /dev/null +++ b/src/kernel/libroot/posix/glibc/libio/wstrops.c @@ -0,0 +1,333 @@ +/* Copyright (C) 1993,1997,1998,1999,2001,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "strfile.h" +#include "libioP.h" +#include +#include +#include + +#if 0 +/* The following definitions are for exposition only. + They map the terminology used in the ANSI/ISO C++ draft standard + to the implementation. */ + +/* allocated: set when a dynamic array object has been allocated, and + hence should be freed by the destructor for the strstreambuf object. */ +#define ALLOCATED(FP) ((FP)->_f._IO_buf_base && DYNAMIC(FP)) + +/* constant: set when the array object has const elements, + so the output sequence cannot be written. */ +#define CONSTANT(FP) ((FP)->_f._IO_file_flags & _IO_NO_WRITES) + +/* alsize: the suggested minimum size for a dynamic array object. */ +#define ALSIZE(FP) ??? /* not stored */ + +/* palloc: points to the function to call to allocate a dynamic array object.*/ +#define PALLOC(FP) \ + ((FP)->_s._allocate_buffer == default_alloc ? 0 : (FP)->_s._allocate_buffer) + +/* pfree: points to the function to call to free a dynamic array object. */ +#define PFREE(FP) \ + ((FP)->_s._free_buffer == default_free ? 0 : (FP)->_s._free_buffer) + +#endif + +#ifdef TODO +/* An "unbounded buffer" is when a buffer is supplied, but with no + specified length. An example is the buffer argument to sprintf. + */ +#endif + +void +_IO_wstr_init_static (fp, ptr, size, pstart) + _IO_FILE *fp; + wchar_t *ptr; + int size; + wchar_t *pstart; +{ + if (size == 0) + size = __wcslen (ptr); + else if (size < 0) + { + /* If size is negative 'the characters are assumed to + continue indefinitely.' This is kind of messy ... */ + int s; + size = 512; + /* Try increasing powers of 2, as long as we don't wrap around. */ + for (; s = 2*size, s > 0 && ptr + s > ptr && s < 0x4000000L; ) + size = s; + /* Try increasing size as much as we can without wrapping around. */ + for (s = size >> 1; s > 0; s >>= 1) + { + if (ptr + size + s > ptr) + size += s; + } + } + INTUSE(_IO_wsetb) (fp, ptr, ptr + size, 0); + + fp->_wide_data->_IO_write_base = ptr; + fp->_wide_data->_IO_read_base = ptr; + fp->_wide_data->_IO_read_ptr = ptr; + if (pstart) + { + fp->_wide_data->_IO_write_ptr = pstart; + fp->_wide_data->_IO_write_end = ptr + size; + fp->_wide_data->_IO_read_end = pstart; + } + else + { + fp->_wide_data->_IO_write_ptr = ptr; + fp->_wide_data->_IO_write_end = ptr; + fp->_wide_data->_IO_read_end = ptr + size; + } + /* A null _allocate_buffer function flags the strfile as being static. */ + (((_IO_strfile *) fp)->_s._allocate_buffer) = (_IO_alloc_type)0; +} + +void +_IO_wstr_init_readonly (fp, ptr, size) + _IO_FILE *fp; + const char *ptr; + int size; +{ + _IO_wstr_init_static (fp, (wchar_t *) ptr, size, NULL); + fp->_IO_file_flags |= _IO_NO_WRITES; +} + +_IO_wint_t +_IO_wstr_overflow (fp, c) + _IO_FILE *fp; + _IO_wint_t c; +{ + int flush_only = c == WEOF; + _IO_size_t pos; + if (fp->_flags & _IO_NO_WRITES) + return flush_only ? 0 : WEOF; + if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING)) + { + fp->_flags |= _IO_CURRENTLY_PUTTING; + fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_read_ptr; + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end; + } + pos = fp->_wide_data->_IO_write_ptr - fp->_wide_data->_IO_write_base; + if (pos >= (_IO_size_t) (_IO_wblen (fp) + flush_only)) + { + if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */ + return WEOF; + else + { + wchar_t *new_buf; + wchar_t *old_buf = fp->_wide_data->_IO_buf_base; + _IO_size_t new_size = 2 * _IO_wblen (fp) + 100; + new_buf + = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size + * sizeof (wchar_t)); + if (new_buf == NULL) + { + /* __ferror(fp) = 1; */ + return WEOF; + } + if (old_buf) + { + __wmemcpy (new_buf, old_buf, _IO_wblen (fp)); + (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf); + /* Make sure _IO_setb won't try to delete _IO_buf_base. */ + fp->_wide_data->_IO_buf_base = NULL; + } + INTUSE(_IO_wsetb) (fp, new_buf, new_buf + new_size, 1); + fp->_wide_data->_IO_read_base = + new_buf + (fp->_wide_data->_IO_read_base - old_buf); + fp->_wide_data->_IO_read_ptr = + new_buf + (fp->_wide_data->_IO_read_ptr - old_buf); + fp->_wide_data->_IO_read_end = + new_buf + (fp->_wide_data->_IO_read_end - old_buf); + fp->_wide_data->_IO_write_ptr = + new_buf + (fp->_wide_data->_IO_write_ptr - old_buf); + + fp->_wide_data->_IO_write_base = new_buf; + fp->_wide_data->_IO_write_end = fp->_wide_data->_IO_buf_end; + } + } + + if (!flush_only) + *fp->_wide_data->_IO_write_ptr++ = c; + if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end) + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr; + return c; +} + +_IO_wint_t +_IO_wstr_underflow (fp) + _IO_FILE *fp; +{ + if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end) + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr; + if ((fp->_flags & _IO_TIED_PUT_GET) && (fp->_flags & _IO_CURRENTLY_PUTTING)) + { + fp->_flags &= ~_IO_CURRENTLY_PUTTING; + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_write_ptr; + fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_write_end; + } + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + return *fp->_wide_data->_IO_read_ptr; + else + return WEOF; +} + +/* The size of the valid part of the buffer. */ + +_IO_ssize_t +_IO_wstr_count (fp) + _IO_FILE *fp; +{ + return ((fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end + ? fp->_wide_data->_IO_write_ptr : fp->_wide_data->_IO_read_end) + - fp->_wide_data->_IO_read_base); +} + +_IO_off64_t +_IO_wstr_seekoff (fp, offset, dir, mode) + _IO_FILE *fp; + _IO_off64_t offset; + int dir; + int mode; +{ + _IO_off64_t new_pos; + + if (mode == 0 && (fp->_flags & _IO_TIED_PUT_GET)) + mode = (fp->_flags & _IO_CURRENTLY_PUTTING ? _IOS_OUTPUT : _IOS_INPUT); + + if (mode == 0) + { + /* Don't move any pointers. But there is no clear indication what + mode FP is in. Let's guess. */ + if (fp->_IO_file_flags & _IO_NO_WRITES) + new_pos = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_base; + else + new_pos = (fp->_wide_data->_IO_write_ptr + - fp->_wide_data->_IO_write_base); + } + else + { + _IO_ssize_t cur_size = _IO_wstr_count (fp); + new_pos = EOF; + + /* Move the get pointer, if requested. */ + if (mode & _IOS_INPUT) + { + switch (dir) + { + case _IO_seek_end: + offset += cur_size; + break; + case _IO_seek_cur: + offset += (fp->_wide_data->_IO_read_ptr + - fp->_wide_data->_IO_read_base); + break; + default: /* case _IO_seek_set: */ + break; + } + if (offset < 0 || (_IO_ssize_t) offset > cur_size) + return EOF; + fp->_wide_data->_IO_read_ptr = (fp->_wide_data->_IO_read_base + + offset); + fp->_wide_data->_IO_read_end = (fp->_wide_data->_IO_read_base + + cur_size); + new_pos = offset; + } + + /* Move the put pointer, if requested. */ + if (mode & _IOS_OUTPUT) + { + switch (dir) + { + case _IO_seek_end: + offset += cur_size; + break; + case _IO_seek_cur: + offset += (fp->_wide_data->_IO_write_ptr + - fp->_wide_data->_IO_write_base); + break; + default: /* case _IO_seek_set: */ + break; + } + if (offset < 0 || (_IO_ssize_t) offset > cur_size) + return EOF; + fp->_wide_data->_IO_write_ptr = (fp->_wide_data->_IO_write_base + + offset); + new_pos = offset; + } + } + return new_pos; +} + +_IO_wint_t +_IO_wstr_pbackfail (fp, c) + _IO_FILE *fp; + _IO_wint_t c; +{ + if ((fp->_flags & _IO_NO_WRITES) && c != WEOF) + return WEOF; + return INTUSE(_IO_wdefault_pbackfail) (fp, c); +} + +void +_IO_wstr_finish (fp, dummy) + _IO_FILE *fp; + int dummy; +{ + if (fp->_wide_data->_IO_buf_base && !(fp->_flags & _IO_USER_BUF)) + (((_IO_strfile *) fp)->_s._free_buffer) (fp->_wide_data->_IO_buf_base); + fp->_wide_data->_IO_buf_base = NULL; + + INTUSE(_IO_wdefault_finish) (fp, 0); +} + +struct _IO_jump_t _IO_wstr_jumps = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_wstr_finish), + JUMP_INIT(overflow, (_IO_overflow_t) _IO_wstr_overflow), + JUMP_INIT(underflow, (_IO_underflow_t) _IO_wstr_underflow), + JUMP_INIT(uflow, (_IO_underflow_t) INTUSE(_IO_wdefault_uflow)), + JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail), + JUMP_INIT(xsputn, INTUSE(_IO_wdefault_xsputn)), + JUMP_INIT(xsgetn, INTUSE(_IO_wdefault_xsgetn)), + JUMP_INIT(seekoff, _IO_wstr_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_default_setbuf), + JUMP_INIT(sync, _IO_default_sync), + JUMP_INIT(doallocate, INTUSE(_IO_wdefault_doallocate)), + JUMP_INIT(read, _IO_default_read), + JUMP_INIT(write, _IO_default_write), + JUMP_INIT(seek, _IO_default_seek), + JUMP_INIT(close, _IO_default_close), + JUMP_INIT(stat, _IO_default_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +};