From 9f95b317f237261427ca09a1e430079d05557212 Mon Sep 17 00:00:00 2001 From: Boudewijn Dekker Date: Tue, 27 Apr 1999 06:15:27 +0000 Subject: [PATCH] Fixed bug in modfl and in fread and fwrite and added some permission checks in stdio. svn path=/trunk/; revision=413 --- reactos/lib/crtdll/io/chsize.c | 3 +- reactos/lib/crtdll/io/commit.c | 1 + reactos/lib/crtdll/io/dup.c | 6 +- reactos/lib/crtdll/io/open.c | 13 + reactos/lib/crtdll/makefile | 2 +- reactos/lib/crtdll/malloc/expand.c | 16 ++ reactos/lib/crtdll/math/modf.c | 44 ++-- reactos/lib/crtdll/mbstring/hanzen.c | 87 ++++++- reactos/lib/crtdll/mbstring/ismblead.c | 43 +++- reactos/lib/crtdll/mbstring/ismbtrail.c | 12 +- reactos/lib/crtdll/process/execl.c | 16 +- reactos/lib/crtdll/process/execle.c | 40 ++- reactos/lib/crtdll/process/execlp.c | 16 +- reactos/lib/crtdll/process/execlpe.c | 36 ++- reactos/lib/crtdll/process/spawnl.c | 14 +- reactos/lib/crtdll/process/spawnle.c | 36 ++- reactos/lib/crtdll/process/spawnlp.c | 13 +- reactos/lib/crtdll/process/spawnlpe.c | 37 ++- reactos/lib/crtdll/process/spawnv.c | 2 +- reactos/lib/crtdll/stdio/FILE.DOC | 16 +- reactos/lib/crtdll/stdio/allocfil.c | 10 + reactos/lib/crtdll/stdio/clearerr.c | 3 +- reactos/lib/crtdll/stdio/fclose.c | 2 +- reactos/lib/crtdll/stdio/fdopen.c | 6 +- reactos/lib/crtdll/stdio/fflush.c | 41 +++- reactos/lib/crtdll/stdio/filbuf.c | 33 ++- reactos/lib/crtdll/stdio/flsbuf.c | 14 +- reactos/lib/crtdll/stdio/fopen.c | 4 +- reactos/lib/crtdll/stdio/fread.c | 25 +- reactos/lib/crtdll/stdio/freopen.c | 2 +- reactos/lib/crtdll/stdio/fscanf.c | 2 +- reactos/lib/crtdll/stdio/fseek.c | 8 +- reactos/lib/crtdll/stdio/ftell.c | 4 +- reactos/lib/crtdll/stdio/fwrite.c | 25 +- reactos/lib/crtdll/stdio/getc.c | 14 +- reactos/lib/crtdll/stdio/getw.c | 39 ++- reactos/lib/crtdll/stdio/putc.c | 25 +- reactos/lib/crtdll/stdio/rename.c | 4 +- reactos/lib/crtdll/stdio/setvbuf.c | 25 +- reactos/lib/crtdll/stdio/stdhnd.c | 2 +- reactos/lib/crtdll/stdio/tmpfile.c | 2 +- reactos/lib/crtdll/stdio/ungetc.c | 36 ++- reactos/lib/crtdll/stdio/vfprintf.c | 309 +++++++++++++++++++++--- reactos/lib/crtdll/stdio/vfscanf.c | 2 +- reactos/lib/crtdll/stdio/vsscanf.c | 2 +- reactos/lib/crtdll/sys_stat/futime.c | 5 +- 46 files changed, 842 insertions(+), 255 deletions(-) diff --git a/reactos/lib/crtdll/io/chsize.c b/reactos/lib/crtdll/io/chsize.c index f69ad442590..9fd2ce22608 100644 --- a/reactos/lib/crtdll/io/chsize.c +++ b/reactos/lib/crtdll/io/chsize.c @@ -1,8 +1,7 @@ /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ #include -int -chsize(int _fd, long size) +int _chsize(int _fd, long size) { if (lseek(_fd, size, 0) == -1) return -1; diff --git a/reactos/lib/crtdll/io/commit.c b/reactos/lib/crtdll/io/commit.c index 8c9d787a146..5a16ad6f599 100644 --- a/reactos/lib/crtdll/io/commit.c +++ b/reactos/lib/crtdll/io/commit.c @@ -3,6 +3,7 @@ #include #include +//fixme change this constant to _OCOMMIT int _commode_dll = _IOCOMMIT; int _commit(int _fd) diff --git a/reactos/lib/crtdll/io/dup.c b/reactos/lib/crtdll/io/dup.c index 7ddf8436315..f2a22ce3507 100644 --- a/reactos/lib/crtdll/io/dup.c +++ b/reactos/lib/crtdll/io/dup.c @@ -1,8 +1,12 @@ #include #include +// fixme change type of mode argument to mode_t + +int __fileno_alloc(HANDLE hFile, int mode); +int __fileno_getmode(int _fd); int _dup( int handle ) { - return _open_osfhandle(_get_osfhandle(handle), 0666); + return __fileno_alloc(_get_osfhandle(handle), __fileno_getmode(handle)); } diff --git a/reactos/lib/crtdll/io/open.c b/reactos/lib/crtdll/io/open.c index 9fbb2ca2051..c7fdcd7d96e 100644 --- a/reactos/lib/crtdll/io/open.c +++ b/reactos/lib/crtdll/io/open.c @@ -231,6 +231,19 @@ int __fileno_setmode(int _fd, int _newmode) return m; } +int __fileno_getmode(int _fd) +{ + if ( _fd < minfno ) + return -1; + + if ( _fd >= maxfno ) + return -1; + + return fileno_modes[_fd].mode; + +} + + int __fileno_close(int _fd) { if ( _fd < 0 ) diff --git a/reactos/lib/crtdll/makefile b/reactos/lib/crtdll/makefile index afd7656a552..f01f0d0a274 100644 --- a/reactos/lib/crtdll/makefile +++ b/reactos/lib/crtdll/makefile @@ -52,7 +52,7 @@ STDIO_OBJECTS = stdio/getenv.o stdio/filbuf.o \ stdio/fopen.o stdio/fprintf.o stdio/fputc.o stdio/fputs.o stdio/setvbuf.o\ stdio/fread.o stdio/freopen.o stdio/fscanf.o stdio/fseek.o \ stdio/fsetpos.o stdio/ftell.o stdio/fwalk.o stdio/fwrite.o stdio/getc.o \ - stdio/getchar.o stdio/gets.o stdio/getw.o stdio/perror.o \ + stdio/getchar.o stdio/gets.o stdio/getw.o stdio/perror.o stdio/clearerr.o \ stdio/putc.o stdio/putchar.o stdio/puts.o stdio/putw.o \ stdio/remove.o stdio/rename.o stdio/rewind.o stdio/allocfil.o\ stdio/setbuf.o stdio/setbuffe.o stdlib/obsol.o stdio/setlineb.o\ diff --git a/reactos/lib/crtdll/malloc/expand.c b/reactos/lib/crtdll/malloc/expand.c index dec9d9376a7..7a323ae945a 100644 --- a/reactos/lib/crtdll/malloc/expand.c +++ b/reactos/lib/crtdll/malloc/expand.c @@ -26,3 +26,19 @@ void *_expand( void *pold, size_t size ) return NULL; } + +size_t _msize (void* pBlock) +{ + PHEAP_BUCKET pbucket; + PHEAP_SUBALLOC psub; + PHEAP_FRAGMENT pfrag=(PHEAP_FRAGMENT)((LPVOID)pBlock-HEAP_FRAG_ADMIN_SIZE); + + /* sanity checks */ + if(pfrag->Magic!=HEAP_FRAG_MAGIC) + return 0; + + /* get bucket size */ + psub=pfrag->Sub; + pbucket=psub->Bucket; + return pbucket->Size; +} \ No newline at end of file diff --git a/reactos/lib/crtdll/math/modf.c b/reactos/lib/crtdll/math/modf.c index 37ba9873fbd..6864e52e044 100644 --- a/reactos/lib/crtdll/math/modf.c +++ b/reactos/lib/crtdll/math/modf.c @@ -33,6 +33,12 @@ double modf(double __x, double *__i) iptr->sign = x->sign; return __x; } else { + + if ( x->mantissah == 0 && x->mantissal == 0 ) { + *__i = __x; + return 0.0; + } + i = (0x000fffff)>>j0; iptr->sign = x->sign; iptr->exponent = x->exponent; @@ -42,8 +48,7 @@ double modf(double __x, double *__i) __x = 0.0; x->sign = iptr->sign; return __x; - } - + } return __x - *__i; } } else if (j0>51) { /* no fraction part */ @@ -72,6 +77,7 @@ double modf(double __x, double *__i) } } + long double modfl(long double __x, long double *__i) { @@ -86,21 +92,23 @@ long double modfl(long double __x, long double *__i) if(j0<32) { /* integer part in high x */ if(j0<0) { /* |x|<1 */ - *__i = 0.0; + *__i = 0.0L; iptr->sign = x->sign; return __x; } else { - i = ((unsigned int)(0xffffffff))>>(j0); + i = ((unsigned int)(0xffffffff))>>(j0+1); + if ( x->mantissal == 0 && (x->mantissal & i) == 0 ) { + *__i = __x; + __x = 0.0L; + x->sign = iptr->sign; + return __x; + } iptr->sign = x->sign; iptr->exponent = x->exponent; iptr->mantissah = x->mantissah&((~i)); iptr->mantissal = 0; - if ( __x == *__i ) { - __x = 0.0; - x->sign = iptr->sign; - return __x; - } + return __x - *__i; } @@ -109,25 +117,25 @@ long double modfl(long double __x, long double *__i) if ( _isnanl(__x) || _isinfl(__x) ) return __x; - __x = 0.0; + __x = 0.0L; x->sign = iptr->sign; return __x; } else { /* fraction part in low x */ - - i = ((unsigned int)(0xffffffff))>>(j0-32); + i = ((unsigned int)(0xffffffff))>>(j0-32); + if ( x->mantissal == 0 ) { + *__i = __x; + __x = 0.0L; + x->sign = iptr->sign; + return __x; + } iptr->sign = x->sign; iptr->exponent = x->exponent; iptr->mantissah = x->mantissah; iptr->mantissal = x->mantissal&(~i); - if ( __x == *__i ) { - __x = 0.0; - x->sign = iptr->sign; - return __x; - } + return __x - *__i; } } - diff --git a/reactos/lib/crtdll/mbstring/hanzen.c b/reactos/lib/crtdll/mbstring/hanzen.c index f9c6fbccd9c..0ab798f4b03 100644 --- a/reactos/lib/crtdll/mbstring/hanzen.c +++ b/reactos/lib/crtdll/mbstring/hanzen.c @@ -1,12 +1,91 @@ -unsigned int _mbcjistojms( unsigned int c ) + +static unsigned short han_to_zen_ascii_table[0x5f] = { + 0x8140, 0x8149, 0x8168, 0x8194, 0x8190, 0x8193, 0x8195, 0x8166, + 0x8169, 0x816a, 0x8196, 0x817b, 0x8143, 0x817c, 0x8144, 0x815e, + 0x824f, 0x8250, 0x8251, 0x8252, 0x8253, 0x8254, 0x8255, 0x8256, + 0x8257, 0x8258, 0x8146, 0x8147, 0x8183, 0x8181, 0x8184, 0x8148, + 0x8197, 0x8260, 0x8261, 0x8262, 0x8263, 0x8264, 0x8265, 0x8266, + 0x8267, 0x8268, 0x8269, 0x826a, 0x826b, 0x826c, 0x826d, 0x826e, + 0x826f, 0x8270, 0x8271, 0x8272, 0x8273, 0x8274, 0x8275, 0x8276, + 0x8277, 0x8278, 0x8279, 0x816d, 0x818f, 0x816e, 0x814f, 0x8151, + 0x8165, 0x8281, 0x8282, 0x8283, 0x8284, 0x8285, 0x8286, 0x8287, + 0x8288, 0x8289, 0x828a, 0x828b, 0x828c, 0x828d, 0x828e, 0x828f, + 0x8290, 0x8291, 0x8292, 0x8293, 0x8294, 0x8295, 0x8296, 0x8297, + 0x8298, 0x8299, 0x829a, 0x816f, 0x8162, 0x8170, 0x8150 +}; +static unsigned short han_to_zen_kana_table[0x40] = { + 0x8140, 0x8142, 0x8175, 0x8176, 0x8141, 0x8145, 0x8392, 0x8340, + 0x8342, 0x8344, 0x8346, 0x8348, 0x8383, 0x8385, 0x8387, 0x8362, + 0x815b, 0x8341, 0x8343, 0x8345, 0x8347, 0x8349, 0x834a, 0x834c, + 0x834e, 0x8350, 0x8352, 0x8354, 0x8356, 0x8358, 0x835a, 0x835c, + 0x835e, 0x8360, 0x8363, 0x8365, 0x8367, 0x8369, 0x836a, 0x836b, + 0x836c, 0x836d, 0x836e, 0x8371, 0x8374, 0x8377, 0x837a, 0x837d, + 0x837e, 0x8380, 0x8381, 0x8382, 0x8384, 0x8386, 0x8388, 0x8389, + 0x838a, 0x838b, 0x838c, 0x838d, 0x838f, 0x8393, 0x814a, 0x814b +}; +static unsigned char zen_to_han_kana_table[0x8396-0x8340+1] = { + 0xa7, 0xb1, 0xa8, 0xb2, 0xa9, 0xb3, 0xaa, 0xb4, + 0xab, 0xb5, 0xb6, 0xb6, 0xb7, 0xb7, 0xb8, 0xb8, + 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb, 0xbc, 0xbc, + 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xbf, 0xc0, 0xc0, + 0xc1, 0xc1, 0xaf, 0xc2, 0xc2, 0xc3, 0xc3, 0xc4, + 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xca, + 0xca, 0xcb, 0xcb, 0xcb, 0xcc, 0xcc, 0xcc, 0xcd, + 0xcd, 0xcd, 0xce, 0xce, 0xce, 0xcf, 0xd0, 0, + 0xd1, 0xd2, 0xd3, 0xac, 0xd4, 0xad, 0xd5, 0xae, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdc, + 0xb2, 0xb4, 0xa6, 0xdd, 0xb3, 0xb6, 0xb9 +}; +#define ZTOH_SYMBOLS 9 +static unsigned short zen_to_han_symbol_table_1[ZTOH_SYMBOLS] = { + 0x8142, 0x8175, 0x8176, 0x8141, 0x8145, 0x815b, 0x814a, 0x814b +}; +static unsigned char zen_to_han_symbol_table_2[ZTOH_SYMBOLS] = { + 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xb0, 0xde, 0xdf +}; +#define ISKANA(c) ((c) >= 0xa1 && (c) <= 0xdf) +#define JISHIRA(c) ((c) >= 0x829f && (c) <= 0x82f1) +#define JISKANA(c) ((c) >= 0x8340 && (c) <= 0x8396 && (c) != 0x837f) +#define JTOKANA(c) ((c) <= 0x82dd ? (c) + 0xa1 : (c) + 0xa2) + + +static unsigned short _mbbtombc(unsigned short c) { - return c; + if (c >= 0x20 && c <= 0x7e) { + return han_to_zen_ascii_table[c - 0x20]; + } else if (ISKANA(c)) { + return han_to_zen_kana_table[c - 0xa0]; + } + return c; } -unsigned int _mbcjmstojis( unsigned int c ) + +static unsigned short _mbctombb(unsigned short c) { - return c; + int i; + unsigned short *p; + + if (JISKANA(c)) { + return zen_to_han_kana_table[c - 0x8340]; + } else if (JISHIRA(c)) { + c = JTOKANA(c); + return zen_to_han_kana_table[c - 0x8340]; + } else if (c <= 0x8396) { + for (i = 0x20, p = han_to_zen_ascii_table; i <= 0x7e; i++, p++) { + if (*p == c) { + return i; + } + } + for (i = 0; i < ZTOH_SYMBOLS; i++) { + if (zen_to_han_symbol_table_1[i] == c) { + return zen_to_han_symbol_table_2[i]; + } + } + } + return c; } +#endif + unsigned int _mbctohira( unsigned int c ) { diff --git a/reactos/lib/crtdll/mbstring/ismblead.c b/reactos/lib/crtdll/mbstring/ismblead.c index 9a7bf8563c4..b1c89aeec5c 100644 --- a/reactos/lib/crtdll/mbstring/ismblead.c +++ b/reactos/lib/crtdll/mbstring/ismblead.c @@ -10,11 +10,48 @@ #include -int _ismbblead(unsigned int byte) -{ - return (int)IsDBCSLeadByte(byte) +#define ___ 0 +#define _1_ _KNJ_1 /* Legal 1st byte of double byte code */ +#define __2 _KNJ_2 /* Legal 2nd byte of double byte code */ +#define _M_ _KNJ_M /* Non-puntuation in Kana-set */ +#define _P_ _KNJ_P /* Punctuation of Kana-set */ +#define _12 (_1_|__2) +#define _M2 (_M_|__2) +#define _P2 (_P_|__2) + +static char _jctype[257] = { +/*-1*/ ___, +/*0x*/ ___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___, +/*1x*/ ___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___, +/*2x*/ ___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___, +/*3x*/ ___,___,___,___,___,___,___,___,___,___,___,___,___,___,___,___, +/*4x*/ __2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2, +/*5x*/ __2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2, +/*6x*/ __2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2, +/*7x*/ __2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,__2,___, +/*8x*/ __2,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12, +/*9x*/ _12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12, +/*Ax*/ __2,_P2,_P2,_P2,_P2,_P2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2, +/*Bx*/ _M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2, +/*Cx*/ _M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2, +/*Dx*/ _M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2,_M2, +/*Ex*/ _12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12, +/*Fx*/ _12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,_12,___,___,___ +}; + + iskanji() : シフト JIS コードの1バイト目(0x81 <= c <= 0x9F る + いは0xE0 <= c <= 0xFC) かどうか + +int _ismbblead(char c) +{ + return ((_jctype+1)[(unsigned char)(c)] & _KNJ_1); } +//int _ismbblead(unsigned int byte) +//{ +// +// return (int)IsDBCSLeadByte(byte) +//} int _ismbslead( const unsigned char *str, const unsigned char *t) { diff --git a/reactos/lib/crtdll/mbstring/ismbtrail.c b/reactos/lib/crtdll/mbstring/ismbtrail.c index 4b26a6ee088..2fb54c8edeb 100644 --- a/reactos/lib/crtdll/mbstring/ismbtrail.c +++ b/reactos/lib/crtdll/mbstring/ismbtrail.c @@ -10,11 +10,19 @@ #include -int _ismbbtrail( unsigned int b) + iskanji2() : シフト JIS コードの2バイト目(0x40 <= c <= 0x7E る + いは0x80 <= c <= 0xFC) かどうか + +int _ismbbtrail(unsigned int c) { - return ((b >= 0x40 && b <= 0x7e ) || (b >= 0x80 && b <= 0xfc ) ); + return ((_jctype+1)[(unsigned char)(c)] & _KNJ_2); } +//int _ismbbtrail( unsigned int b) +//{ +// return ((b >= 0x40 && b <= 0x7e ) || (b >= 0x80 && b <= 0xfc ) ); +//} + int _ismbstrail( const unsigned char *str, const unsigned char *t) { diff --git a/reactos/lib/crtdll/process/execl.c b/reactos/lib/crtdll/process/execl.c index 1769cd2009f..1d054760361 100644 --- a/reactos/lib/crtdll/process/execl.c +++ b/reactos/lib/crtdll/process/execl.c @@ -4,9 +4,17 @@ #include #include -int _execl(const char* szPath, const char* szArgv0, ...) +int _execl(const char* szPath, const char* szArgv0, ...) { - va_list a = 0; - va_start(a,szArgv0); - return _spawnve(P_OVERLAY, szPath, (char *const*)a, _environ); + char *szArg[100]; + const char *a; + int i = 0; + va_list l = 0; + va_start(l,szArgv0); + do { + a = va_arg(l,const char *); + szArg[i++] = (char *)a; + } while ( a != NULL && i < 100 ); + + return _spawnve(P_OVERLAY, szPath, szArg, _environ); } diff --git a/reactos/lib/crtdll/process/execle.c b/reactos/lib/crtdll/process/execle.c index 0f5d5adca4b..f907798aa5b 100644 --- a/reactos/lib/crtdll/process/execle.c +++ b/reactos/lib/crtdll/process/execle.c @@ -1,17 +1,33 @@ -/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ - - #include +#include +#include -#define scan_ptr() \ - const char **ptr; \ - union { const char **ccpp; const char *ccp; } u; \ - for (ptr = &argv0; *ptr; ptr++); \ - u.ccp = *++ptr; \ - ptr = u.ccpp; -int _execle(const char *path, const char *argv0, ... /*, const char **envp */) +// fixme rewrite to pass the array variants to va_list variant + +int _execle(const char *path, const char *szArgv0, ... /*, const char **envp */) { - scan_ptr(); - return _spawnve(P_OVERLAY, path, (char *const *)&argv0, (char *const *)ptr); + char *szArg[100]; + const char *a; + char *ptr; + int i = 0; + va_list l = 0; + va_start(l,szArgv0); + do { + a = (const char *)va_arg(l,const char *); + szArg[i++] = (char *)a; + } while ( a != NULL && i < 100 ); + + +// szArg0 is passed and not environment if there is only one parameter; + + if ( i >=2 ) { + ptr = szArg[i-2]; + szArg[i-2] = NULL; + } + else + ptr = NULL; + + + return _spawnve(P_OVERLAY, path, (char * const *)szArg, (char * const *)ptr); } diff --git a/reactos/lib/crtdll/process/execlp.c b/reactos/lib/crtdll/process/execlp.c index bb79013b971..1b975896821 100644 --- a/reactos/lib/crtdll/process/execlp.c +++ b/reactos/lib/crtdll/process/execlp.c @@ -1,9 +1,17 @@ -/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ - #include #include +#include -int _execlp(const char *path, const char *argv0, ...) +int _execlp(const char *szPath, const char *szArgv0, ...) { - return _spawnvpe(P_OVERLAY, path, (char * const *)&argv0, _environ); + char *szArg[100]; + const char *a; + int i = 0; + va_list l = 0; + va_start(l,szArgv0); + do { + a = (const char *)va_arg(l,const char *); + szArg[i++] = (char *)a; + } while ( a != NULL && i < 100 ); + return _spawnvpe(P_OVERLAY, szPath,szArg, _environ); } diff --git a/reactos/lib/crtdll/process/execlpe.c b/reactos/lib/crtdll/process/execlpe.c index b4d514eae2b..785dff08f56 100644 --- a/reactos/lib/crtdll/process/execlpe.c +++ b/reactos/lib/crtdll/process/execlpe.c @@ -1,17 +1,29 @@ -/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ - #include +#include +#include -#define scan_ptr() \ - const char **ptr; \ - union { const char **ccpp; const char *ccp; } u; \ - for (ptr = &argv0; *ptr; ptr++); \ - u.ccp = *++ptr; \ - ptr = u.ccpp; - -int execlpe(const char *path, const char *argv0, ... /*, const char **envp */) +int execlpe(const char *path, const char *szArgv0, ... /*, const char **envp */) { - scan_ptr(); - return spawnvpe(P_OVERLAY, path, (char * const *)&argv0, (char * const *)ptr); + char *szArg[100]; + const char *a; + char *ptr; + int i = 0; + va_list l = 0; + va_start(l,szArgv0); + do { + a = (const char *)va_arg(l,const char *); + szArg[i++] = (char *)a; + } while ( a != NULL && i < 100 ); + + +// szArg0 is passed and not environment if there is only one parameter; + + if ( i >=2 ) { + ptr = szArg[i-2]; + szArg[i-2] = NULL; + } + else + ptr = NULL; + return spawnvpe(P_OVERLAY, path, (char * const *)szArg, (char * const *)ptr); } diff --git a/reactos/lib/crtdll/process/spawnl.c b/reactos/lib/crtdll/process/spawnl.c index 499509ee22a..11be2f2edd4 100644 --- a/reactos/lib/crtdll/process/spawnl.c +++ b/reactos/lib/crtdll/process/spawnl.c @@ -6,7 +6,15 @@ int _spawnl(int nMode, const char* szPath, const char* szArgv0,...) { - va_list a = 0; - va_start(a,szArgv0); - return _spawnve(nMode, szPath, (char * const *)a, _environ); + char *szArg[100]; + const char *a; + int i = 0; + va_list l = 0; + va_start(l,szArgv0); + do { + a = va_arg(l,const char *); + szArg[i++] = (char *)a; + } while ( a != NULL && i < 100 ); + + return _spawnve(nMode, szPath, szArg, _environ); } diff --git a/reactos/lib/crtdll/process/spawnle.c b/reactos/lib/crtdll/process/spawnle.c index 0f1573f8d5e..3ea86bba19d 100644 --- a/reactos/lib/crtdll/process/spawnle.c +++ b/reactos/lib/crtdll/process/spawnle.c @@ -1,16 +1,30 @@ -/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ - #include +#include +#include -#define scan_ptr() \ - const char **ptr; \ - union { const char **ccpp; const char *ccp; } u; \ - for (ptr = &argv0; *ptr; ptr++); \ - u.ccp = *++ptr; \ - ptr = u.ccpp; -int _spawnle(int mode, const char *path, const char *argv0, ... /*, const char **envp */) +int _spawnle(int mode, const char *path, const char *szArgv0, ... /*, const char **envp */) { - scan_ptr(); - return _spawnve(mode, path, (char * const *)&argv0, (char * const *)ptr); + char *szArg[100]; + char *a; + char *ptr; + int i = 0; + va_list l = 0; + va_start(l,szArgv0); + do { + a = (const char *)va_arg(l,const char *); + szArg[i++] = (char *)a; + } while ( a != NULL && i < 100 ); + + +// szArg0 is passed and not environment if there is only one parameter; + + if ( i >=2 ) { + ptr = szArg[i-2]; + szArg[i-2] = NULL; + } + else + ptr = NULL; + + return _spawnve(mode, path, (char * const *)szArg, (char * const *)ptr); } diff --git a/reactos/lib/crtdll/process/spawnlp.c b/reactos/lib/crtdll/process/spawnlp.c index 3e5c55b3e3a..58ed2ede494 100644 --- a/reactos/lib/crtdll/process/spawnlp.c +++ b/reactos/lib/crtdll/process/spawnlp.c @@ -6,7 +6,14 @@ int _spawnlp(int nMode, const char* szPath, const char* szArgv0, ...) { - va_list a = 0; - va_start(a,szArgv0); - return _spawnvpe(nMode, szPath, (char * const *)a, _environ); + char *szArg[100]; + const char *a; + int i = 0; + va_list l = 0; + va_start(l,szArgv0); + do { + a = (const char *)va_arg(l,const char *); + szArg[i++] = (char *)a; + } while ( a != NULL && i < 100 ); + return _spawnvpe(nMode, szPath,szArg, _environ); } diff --git a/reactos/lib/crtdll/process/spawnlpe.c b/reactos/lib/crtdll/process/spawnlpe.c index 4ca400ac128..cfd73f90186 100644 --- a/reactos/lib/crtdll/process/spawnlpe.c +++ b/reactos/lib/crtdll/process/spawnlpe.c @@ -1,15 +1,30 @@ -/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ - #include -#define scan_ptr() \ - const char **ptr; \ - union { const char **ccpp; const char *ccp; } u; \ - for (ptr = &argv0; *ptr; ptr++); \ - u.ccp = *++ptr; \ - ptr = u.ccpp; +#include +#include -int _spawnlpe(int mode, const char *path, const char *argv0, ... /*, const char **envp */) + +int _spawnlpe(int mode, const char *path, const char *szArgv0, ... /*, const char **envp */) { - scan_ptr(); - return _spawnvpe(mode, path, (char * const *)&argv0, (char * const *)ptr); + char *szArg[100]; + const char *a; + char *ptr; + int i = 0; + va_list l = 0; + va_start(l,szArgv0); + do { + a = (const char *)va_arg(l,const char *); + szArg[i++] = (char *)a; + } while ( a != NULL && i < 100 ); + + +// szArg0 is passed and not environment if there is only one parameter; + + if ( i >=2 ) { + ptr = szArg[i-2]; + szArg[i-2] = NULL; + } + else + ptr = NULL; + + return _spawnvpe(mode, path, (char * const *)szArg, (char * const *)ptr); } diff --git a/reactos/lib/crtdll/process/spawnv.c b/reactos/lib/crtdll/process/spawnv.c index 1ebb2cc0ba0..cf252741afa 100644 --- a/reactos/lib/crtdll/process/spawnv.c +++ b/reactos/lib/crtdll/process/spawnv.c @@ -3,7 +3,7 @@ #include #include -int _spawnv (int nMode, const char* szPath, char* const* szaArgv) +int _spawnv(int nMode, const char* szPath, char* const* szaArgv) { return _spawnve(nMode, szPath, (char * const *)szaArgv, _environ); } diff --git a/reactos/lib/crtdll/stdio/FILE.DOC b/reactos/lib/crtdll/stdio/FILE.DOC index e3c7ae90091..a4367326563 100644 --- a/reactos/lib/crtdll/stdio/FILE.DOC +++ b/reactos/lib/crtdll/stdio/FILE.DOC @@ -22,15 +22,15 @@ size of the buffer int _flag; _IORW file is used for both read and write -_IOWRT file was last used for write -_IOREAD file was last used for read +_IOWRT file is opened for write +_IOREAD file is opened for read _IOMYBUF buffer needs to be freed -_IOEOF file is at EOF -_IOERR error occurred -_IOSTRG sprintf +_IOEOF file is at EOF +_IOERR error occurred +_IOSTRG sprintf _IOAPPEND append mode _IORMONCL remove file on close -_IOUNGETC buffer contents does not correspond to file +_IOUNGETC buffer contents does not correspond to file int _file; @@ -40,8 +40,4 @@ char *_name_to_remove; If nonzero, the named file is removed when the file is fclosed. -int _fillsize; -The number of bytes to read this time. Used to slow-start the read, -in case the program seeks a lot we won't waste time reading large -blocks, but if you read a lot, we use bigger transfers. diff --git a/reactos/lib/crtdll/stdio/allocfil.c b/reactos/lib/crtdll/stdio/allocfil.c index 9f0041afdbb..b0f9e6446e9 100644 --- a/reactos/lib/crtdll/stdio/allocfil.c +++ b/reactos/lib/crtdll/stdio/allocfil.c @@ -7,6 +7,16 @@ FILE * __alloc_file(void); +char __validfp (FILE *f) +{ + if ( (unsigned int)f < 256) + return FALSE; + + if( f == NULL || (int)f== -1 ) + return FALSE; + + return TRUE; +} /* A FILE* is considered "free" if its flag is zero. */ diff --git a/reactos/lib/crtdll/stdio/clearerr.c b/reactos/lib/crtdll/stdio/clearerr.c index e05529ca3bd..0543ed0abcd 100644 --- a/reactos/lib/crtdll/stdio/clearerr.c +++ b/reactos/lib/crtdll/stdio/clearerr.c @@ -1,5 +1,6 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ #include +#include #include #ifdef clearerr @@ -10,7 +11,7 @@ void clearerr(FILE *stream); void clearerr(FILE *f) { - if (!f) { + if (!__validfp (f)) { __set_errno (EINVAL); return; } diff --git a/reactos/lib/crtdll/stdio/fclose.c b/reactos/lib/crtdll/stdio/fclose.c index 0fe0a8a2ea2..1b141c5ca5a 100644 --- a/reactos/lib/crtdll/stdio/fclose.c +++ b/reactos/lib/crtdll/stdio/fclose.c @@ -25,7 +25,7 @@ fclose(FILE *f) // flush only if stream was opened for writing if ( !(f->_flag&_IOSTRG) ) { - if ( WRITE_STREAM(f) ) + if ( OPEN4WRITING(f) ) r = fflush(f); if (_close(fileno(f)) < 0) diff --git a/reactos/lib/crtdll/stdio/fdopen.c b/reactos/lib/crtdll/stdio/fdopen.c index dc815528e34..2427466e828 100644 --- a/reactos/lib/crtdll/stdio/fdopen.c +++ b/reactos/lib/crtdll/stdio/fdopen.c @@ -36,8 +36,12 @@ FILE *_fdopen(int handle, char *mode) file->_cnt = 0; file->_file = handle; file->_bufsiz = 0; + +// The mode of the stream must be compatible with the mode of the file descriptor. +// this should be checked. + if (rw) - file->_flag = _IORW; + file->_flag = _IOREAD | _IOWRT; else if (*mode == 'r') file->_flag = _IOREAD; else diff --git a/reactos/lib/crtdll/stdio/fflush.c b/reactos/lib/crtdll/stdio/fflush.c index 46002de9a8c..47d8aad7be5 100644 --- a/reactos/lib/crtdll/stdio/fflush.c +++ b/reactos/lib/crtdll/stdio/fflush.c @@ -33,30 +33,46 @@ int fflush(FILE *f) // nothing to do if stream can not be written to - //if ( !WRITE_STREAM(f) ) - // return 0; + if ( !OPEN4WRITING(f) ) { + __set_errno (EINVAL); + return 0; + } +// discard any unget characters f->_flag &= ~_IOUNGETC; -// if ((f->_flag&(_IONBF|_IOWRT))==_IOWRT -// && (base = f->_base) != NULL -// && (rn = n = f->_ptr - base) > 0) - if ((f->_flag&(_IODIRTY|_IONBF))==_IODIRTY - && (base = f->_base) != NULL - && (rn = n = f->_ptr - base) > 0) + + +// check for buffered dirty block + + if ( (f->_flag&(_IODIRTY|_IONBF)) ==_IODIRTY && f->_base != NULL) { + + base = f->_base; + + +// if the buffer is read ahead and dirty we will flush it entirely +// else the buffer is appended to the file to the extend it has valid bytes + + if ( (f->_flag & _IOAHEAD) == _IOAHEAD ) + rn = n = f->_ptr - base + f->_cnt; + else + rn = n = f->_ptr - base; + f->_ptr = base; if ((f->_flag & _IOFBF) == _IOFBF) { if ( (f->_flag & _IOAHEAD) == _IOAHEAD ) - _lseek(fileno(f),-(rn+f->_cnt), SEEK_CUR); + _lseek(fileno(f),-rn, SEEK_CUR); } f->_flag &= ~_IOAHEAD; f->_cnt = (f->_flag&(_IOLBF|_IONBF)) ? 0 : f->_bufsiz; - f->_flag &= ~_IODIRTY; + +// how can write return less than rn without being on error ??? + do { n = _write(fileno(f), base, rn); if (n <= 0) { @@ -66,11 +82,12 @@ int fflush(FILE *f) rn -= n; base += n; } while (rn > 0); + f->_flag &= ~_IODIRTY; + } - if (f->_flag & _IORW) + if (OPEN4READING(f) && OPEN4WRITING(f) ) { f->_cnt = 0; - //f->_flag &= ~(_IOWRT|_IOREAD); f->_ptr = f->_base; } return 0; diff --git a/reactos/lib/crtdll/stdio/filbuf.c b/reactos/lib/crtdll/stdio/filbuf.c index 7c6d7a16e3f..1ff790888e6 100644 --- a/reactos/lib/crtdll/stdio/filbuf.c +++ b/reactos/lib/crtdll/stdio/filbuf.c @@ -9,6 +9,7 @@ #include #include #include +#include int _readcnv(int fn, void *buf, size_t siz ); @@ -19,8 +20,10 @@ _filbuf(FILE *f) char c; -// if ( !READ_STREAM(f)) -// return EOF; + if ( !OPEN4READING(f)) { + __set_errno (EINVAL); + return EOF; + } if (f->_flag&(_IOSTRG|_IOEOF)) @@ -31,6 +34,7 @@ _filbuf(FILE *f) size = 4096; if ((f->_base = malloc(size+1)) == NULL) { + // error ENOMEM f->_flag |= _IONBF; f->_flag &= ~(_IOFBF|_IOLBF); } @@ -41,9 +45,12 @@ _filbuf(FILE *f) } } + if (f->_flag&_IONBF) f->_base = &c; + +// fush stdout before reading from stdin if (f == stdin) { if (stdout->_flag&_IOLBF) fflush(stdout); @@ -51,15 +58,14 @@ _filbuf(FILE *f) fflush(stderr); } -// if(__is_text_file(f)) -// f->_cnt = _readcnv(fileno(f), f->_base, -// f->_flag & _IONBF ? 1 : f->_bufsiz ); -// else +// if we have a dirty stream we flush it + if ( f->_flag &_IODIRTY == _IODIRTY ) + fflush(f); - f->_cnt = _read(fileno(f), f->_base, - f->_flag & _IONBF ? 1 : f->_bufsiz ); - f->_flag |= _IOAHEAD; + + f->_cnt = _read(fileno(f), f->_base, f->_flag & _IONBF ? 1 : f->_bufsiz ); + f->_flag |= _IOAHEAD; if(__is_text_file(f) && f->_cnt>0) { @@ -72,18 +78,23 @@ _filbuf(FILE *f) f->_cnt = newcnt; } } + f->_ptr = f->_base; + if (f->_flag & _IONBF) f->_base = NULL; // statically allocated buffer for sprintf + +//check for error if (--f->_cnt < 0) { if (f->_cnt == -1) { f->_flag |= _IOEOF; - //if (f->_flag & _IORW) - //f->_flag &= ~_IOREAD; } else f->_flag |= _IOERR; f->_cnt = 0; + +// should set errno + return EOF; } diff --git a/reactos/lib/crtdll/stdio/flsbuf.c b/reactos/lib/crtdll/stdio/flsbuf.c index fc9dc5a4f14..5f3268144b7 100644 --- a/reactos/lib/crtdll/stdio/flsbuf.c +++ b/reactos/lib/crtdll/stdio/flsbuf.c @@ -7,6 +7,7 @@ #include #include #include +#include int cntcr(char *bufp, int bufsiz); int convert(char *endp, int bufsiz,int n); @@ -15,15 +16,17 @@ int _writecnv(int fn, void *buf, size_t bufsiz); int _flsbuf(int c, FILE *f) { - char *base; + char *base; int n, rn; char c1; int size; -// if (!WRITE_STREAM(f)) -// return EOF; + if (!OPEN4WRITING(f)) { + __set_errno (EINVAL); + return EOF; + } /* if the buffer is not yet allocated, allocate it */ if ((base = f->_base) == NULL && (f->_flag & _IONBF) == 0) @@ -87,10 +90,7 @@ _flsbuf(int c, FILE *f) f->_flag &= ~_IODIRTY; while (rn > 0) { -// if(__is_text_file(f) ) -// n = _writecnv(fileno(f), base, rn); -// else - n = _write(fileno(f), base, rn); + n = _write(fileno(f), base, rn); if (n <= 0) { f->_flag |= _IOERR; diff --git a/reactos/lib/crtdll/stdio/fopen.c b/reactos/lib/crtdll/stdio/fopen.c index 0b1965adbcb..b145c5938fc 100644 --- a/reactos/lib/crtdll/stdio/fopen.c +++ b/reactos/lib/crtdll/stdio/fopen.c @@ -56,6 +56,8 @@ FILE* fopen(const char *file, const char *mode) if (fd < 0) return NULL; +// ms crtdll ensures that writes will end up at the end of file in append mode +// we just move the file pointer to the end of file initially if (*mode == 'a') lseek(fd, 0, SEEK_END); @@ -63,7 +65,7 @@ FILE* fopen(const char *file, const char *mode) f->_file = fd; f->_bufsiz = 0; if (rw) - f->_flag = _IORW; + f->_flag = _IOREAD | _IOWRT; else if (*mode == 'r') f->_flag = _IOREAD; else diff --git a/reactos/lib/crtdll/stdio/fread.c b/reactos/lib/crtdll/stdio/fread.c index ff679179944..c9f72385c98 100644 --- a/reactos/lib/crtdll/stdio/fread.c +++ b/reactos/lib/crtdll/stdio/fread.c @@ -39,13 +39,13 @@ size_t fread(void *vptr, size_t size, size_t count, FILE *iop) to_read = size * count; - //if (!READ_STREAM(iop)) - //{ - // __set_errno (EINVAL); - // return 0; - //} + if (!OPEN4READING(iop)) + { + __set_errno (EINVAL); + return 0; + } - if (iop == NULL ) + if (!__validfp (iop) ) { __set_errno (EINVAL); return 0; @@ -57,18 +57,27 @@ size_t fread(void *vptr, size_t size, size_t count, FILE *iop) return 0; - while(iop->_cnt > 0) { + while(iop->_cnt > 0 && to_read > 0 ) { to_read--; *ptr++ = getc(iop); } + + // if the buffer is dirty it will have to be written now + // otherwise the file pointer won't match anymore. + fflush(iop); + // check to see if this will work with in combination with ungetc n_read = _read(fileno(iop), ptr, to_read); if ( n_read != -1 ) to_read -= n_read; + + // the file buffer is empty and there is no read ahead information anymore. + + iop->_flag &= ~_IOAHEAD; - return count- (to_read/size); + return count- (to_read/size); } #endif diff --git a/reactos/lib/crtdll/stdio/freopen.c b/reactos/lib/crtdll/stdio/freopen.c index 681b429c5c4..13a60f10b62 100644 --- a/reactos/lib/crtdll/stdio/freopen.c +++ b/reactos/lib/crtdll/stdio/freopen.c @@ -56,7 +56,7 @@ freopen(const char *file, const char *mode, FILE *f) f->_file = fd; f->_bufsiz = 0; if (rw) - f->_flag = _IORW; + f->_flag = _IOREAD | _IOWRT; else if (*mode == 'r') f->_flag = _IOREAD; else diff --git a/reactos/lib/crtdll/stdio/fscanf.c b/reactos/lib/crtdll/stdio/fscanf.c index 666589df470..4e7c893d30d 100644 --- a/reactos/lib/crtdll/stdio/fscanf.c +++ b/reactos/lib/crtdll/stdio/fscanf.c @@ -22,7 +22,7 @@ Cambridge, MA 02139, USA. */ #include #include -#if 1 +#if 0 int fscanf(FILE *stream,const char *format, ...) { diff --git a/reactos/lib/crtdll/stdio/fseek.c b/reactos/lib/crtdll/stdio/fseek.c index ed9bced78e3..73929460460 100644 --- a/reactos/lib/crtdll/stdio/fseek.c +++ b/reactos/lib/crtdll/stdio/fseek.c @@ -18,7 +18,7 @@ int fseek(FILE *f, long offset, int ptrname) } f->_flag &= ~_IOEOF; - if (!WRITE_STREAM(f)) + if (!OPEN4WRITING(f)) { if (f->_base && !(f->_flag & _IONBF)) { @@ -30,7 +30,7 @@ int fseek(FILE *f, long offset, int ptrname) } /* check if the target position is in the buffer and optimize seek by moving inside the buffer */ - if (ptrname == SEEK_SET && (f->_flag & (_IOUNGETC|_IORW)) == 0 + if (ptrname == SEEK_SET && (f->_flag & (_IOUNGETC|_IOREAD|_IOWRT )) == 0 && p-offset <= f->_ptr-f->_base && offset-p <= f->_cnt) { f->_ptr+=offset-p; @@ -39,9 +39,7 @@ int fseek(FILE *f, long offset, int ptrname) } } - // if (f->_flag & _IORW) - // f->_flag &= ~_IOREAD; - + p = lseek(fileno(f), offset, ptrname); f->_cnt = 0; f->_ptr = f->_base; diff --git a/reactos/lib/crtdll/stdio/ftell.c b/reactos/lib/crtdll/stdio/ftell.c index cc0f511f332..c93e2a631da 100644 --- a/reactos/lib/crtdll/stdio/ftell.c +++ b/reactos/lib/crtdll/stdio/ftell.c @@ -21,9 +21,9 @@ ftell(FILE *f) { adjust = - f->_cnt; } - else if (f->_flag&(_IOWRT|_IORW)) + else if (f->_flag&(_IOWRT)) { - if (f->_flag&_IOWRT && f->_base && (f->_flag&_IONBF)==0) + if (f->_base && (f->_flag&_IONBF)==0) adjust = f->_ptr - f->_base; } diff --git a/reactos/lib/crtdll/stdio/fwrite.c b/reactos/lib/crtdll/stdio/fwrite.c index b9f3a8d1c50..4dcc8d7e5ce 100644 --- a/reactos/lib/crtdll/stdio/fwrite.c +++ b/reactos/lib/crtdll/stdio/fwrite.c @@ -37,11 +37,11 @@ size_t fwrite(const void *vptr, size_t size, size_t count, FILE *iop) char *ptr = (char *)vptr; to_write = size*count; - //if (!WRITE_STREAM(iop) ) - //{ - // __set_errno (EINVAL); - // return 0; - //} + if (!OPEN4WRITING(iop) ) + { + __set_errno (EINVAL); + return 0; + } if (iop == NULL ) @@ -56,19 +56,28 @@ size_t fwrite(const void *vptr, size_t size, size_t count, FILE *iop) return 0; - while(iop->_cnt > 0 ) { + while(iop->_cnt > 0 && to_write > 0 ) { to_write--; putc(*ptr++,iop); } - + + // if the buffer is dirty it will have to be written now + // otherwise the file pointer won't match anymore. + + fflush(iop); n_written = _write(fileno(iop), ptr,to_write); if ( n_written != -1 ) to_write -= n_written; // check to see if this will work with in combination with ungetc + + + // the file buffer is empty and there is no read ahead information anymore. + + iop->_flag &= ~_IOAHEAD; - return count - (to_write/size); + return count - (to_write/size); } diff --git a/reactos/lib/crtdll/stdio/getc.c b/reactos/lib/crtdll/stdio/getc.c index c36c49a150d..d3087a60359 100644 --- a/reactos/lib/crtdll/stdio/getc.c +++ b/reactos/lib/crtdll/stdio/getc.c @@ -4,22 +4,24 @@ #include #include +//getc can be a macro +#undef getc int getc(FILE *fp) { // check for invalid stream - if ( (int)fp == NULL ) { + if ( !__validfp (fp) ) { __set_errno(EINVAL); - return -1; + return EOF; } // check for read access on stream - //if ( !READ_STREAM(fp) ) { - // __set_errno(EINVAL); - // return -1; - //} + if ( !OPEN4READING(fp) ) { + __set_errno(EINVAL); + return -1; + } if(fp->_cnt > 0) { fp->_cnt--; diff --git a/reactos/lib/crtdll/stdio/getw.c b/reactos/lib/crtdll/stdio/getw.c index c47e11fa465..659061d9924 100644 --- a/reactos/lib/crtdll/stdio/getw.c +++ b/reactos/lib/crtdll/stdio/getw.c @@ -1,18 +1,33 @@ -/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ +/* Copyright (C) 1991 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + #include -#include + +/* Read a word (int) from STREAM. */ int -getw(FILE *f) +getw(FILE *stream) { - int i; - char *p; - int w; + int w; - p = (char *)&w; - for (i=sizeof(int); --i>=0;) - *p++ = getc(f); - if (feof(f)) - return EOF; - return w; + /* Is there a better way? */ + if (fread( &w, sizeof(w), 1, stream) != 1) + return(EOF); + return(w); } + diff --git a/reactos/lib/crtdll/stdio/putc.c b/reactos/lib/crtdll/stdio/putc.c index 7e341ba7d7e..0764d07f98e 100644 --- a/reactos/lib/crtdll/stdio/putc.c +++ b/reactos/lib/crtdll/stdio/putc.c @@ -5,36 +5,35 @@ #include #include +// putc can be a macro +#undef putc + int putc(int c, FILE *fp) { - if ( c == 0 ) - c = ' '; // valid stream macro should check that fp // is dword aligned - if ( fp == NULL ) { + if (!__validfp (fp)) { __set_errno(EINVAL); return -1; } // check for write access on fp - //if ( !WRITE_STREAM(fp) ) { - // __set_errno(EINVAL); - // return -1; - //} + if ( !OPEN4WRITING(fp) ) { + __set_errno(EINVAL); + return -1; + } fp->_flag |= _IODIRTY; if (fp->_cnt > 0 ) { fp->_cnt--; - *(fp)->_ptr++ = (char)c; - return (int)c; + *(fp)->_ptr++ = (unsigned char)c; + return (int)(unsigned char)c; } else { - return _flsbuf(c,fp); + return _flsbuf((unsigned char)c,fp); } - - - return -1; + return EOF; } wint_t putwc(wchar_t c, FILE *fp) diff --git a/reactos/lib/crtdll/stdio/rename.c b/reactos/lib/crtdll/stdio/rename.c index 3d5f0d28f4b..14eb4011092 100644 --- a/reactos/lib/crtdll/stdio/rename.c +++ b/reactos/lib/crtdll/stdio/rename.c @@ -5,7 +5,9 @@ int rename(const char *old_, const char *new_) { - if ( !MoveFile(old_,new_) ) + if ( old_ == NULL || new_ == NULL ) + return -1; + if ( !MoveFileA(old_,new_) ) return -1; return 0; diff --git a/reactos/lib/crtdll/stdio/setvbuf.c b/reactos/lib/crtdll/stdio/setvbuf.c index e291daa304c..2f095e3d05d 100644 --- a/reactos/lib/crtdll/stdio/setvbuf.c +++ b/reactos/lib/crtdll/stdio/setvbuf.c @@ -4,26 +4,34 @@ #include #include #include +#include #include int setvbuf(FILE *f, char *buf, int type, size_t len) { int mine=0; - if (!f) - return -1; - fflush(f); + if (!__validfp (f) ) { + __set_errno (EINVAL); + return 0; + } + if ( f->_base != NULL ) + fflush(f); switch (type) { case _IOFBF: case _IOLBF: - if (len <= 0) - return -1; + if (len <= 0) { + __set_errno (EINVAL); + return EOF; + } if (buf == 0) { - buf = (char *)malloc(len); - if (buf == 0) + buf = (char *)malloc(len+1); + if (buf == NULL) { + __set_errno (ENOMEM); return -1; + } mine = 1; } /* FALLTHROUGH */ @@ -48,6 +56,7 @@ int setvbuf(FILE *f, char *buf, int type, size_t len) } return 0; default: - return -1; + __set_errno (EINVAL); + return EOF; } } diff --git a/reactos/lib/crtdll/stdio/stdhnd.c b/reactos/lib/crtdll/stdio/stdhnd.c index 7f139e646e4..6e8e6ad42d8 100644 --- a/reactos/lib/crtdll/stdio/stdhnd.c +++ b/reactos/lib/crtdll/stdio/stdhnd.c @@ -28,7 +28,7 @@ FILE _crtdll_iob[5] = // stdaux { NULL, 0, NULL, - _IORW | _IONBF, + _IOREAD | _IOWRT | _IONBF, 3,0,0, NULL }, // stdprn diff --git a/reactos/lib/crtdll/stdio/tmpfile.c b/reactos/lib/crtdll/stdio/tmpfile.c index 236f4d8af44..22e36962af2 100644 --- a/reactos/lib/crtdll/stdio/tmpfile.c +++ b/reactos/lib/crtdll/stdio/tmpfile.c @@ -57,7 +57,7 @@ tmpfile(void) f->_file = temp_fd; f->_cnt = 0; f->_bufsiz = 0; - f->_flag = _IORMONCL | _IORW; + f->_flag = _IORMONCL | _IOREAD | _IOWRT; f->_name_to_remove = n_t_r; strcpy(f->_name_to_remove, temp_name); f->_base = f->_ptr = NULL; diff --git a/reactos/lib/crtdll/stdio/ungetc.c b/reactos/lib/crtdll/stdio/ungetc.c index 8227b58f642..e39ff4712a0 100644 --- a/reactos/lib/crtdll/stdio/ungetc.c +++ b/reactos/lib/crtdll/stdio/ungetc.c @@ -3,15 +3,24 @@ #include #include #include +#include int ungetc(int c, FILE *f) { - if (c == EOF - || (f->_flag & (_IOREAD|_IORW)) == 0 - || f->_ptr == NULL - || f->_base == NULL) - return EOF; + + if (!__validfp (f) || !OPEN4READING(f)) { + __set_errno (EINVAL); + return EOF; + } + + if (c == EOF ) + return EOF; + + + + if ( f->_ptr == NULL || f->_base == NULL) + return EOF; if (f->_ptr == f->_base) { @@ -36,11 +45,18 @@ ungetc(int c, FILE *f) wint_t ungetwc(wchar_t c, FILE *f) { - if ((char)c == EOF - || (f->_flag & (_IOREAD|_IORW)) == 0 - || f->_ptr == NULL - || f->_base == NULL) - return EOF; + if (!__validfp (f) || !OPEN4READING(f)) { + __set_errno (EINVAL); + return EOF; + } + + if (c == (wchar_t)EOF ) + return EOF; + + + + if ( f->_ptr == NULL || f->_base == NULL) + return EOF; if (f->_ptr == f->_base) { diff --git a/reactos/lib/crtdll/stdio/vfprintf.c b/reactos/lib/crtdll/stdio/vfprintf.c index 1ef7c233940..9b6e76854cc 100644 --- a/reactos/lib/crtdll/stdio/vfprintf.c +++ b/reactos/lib/crtdll/stdio/vfprintf.c @@ -1,11 +1,13 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ #include -#include +#include #include #include int _isnanl(double x); int _isinfl(double x); +int _isnan(double x); +int _isinf(double x); @@ -168,7 +170,202 @@ static char * number(FILE * f, long num, int base, int size, int precision -void numberf(FILE * f, long double __n, char exp_sign, int size, int precision, int type) +void numberf(FILE * f, double __n, char exp_sign, int size, int precision, int type) +{ + + double exponent = 0.0; + double e; + long ie; + + //int x; + char *buf, *tmp; + int i = 0; + int j = 0; + //int k = 0; + + double frac, intr; + double p; + char sign; + char c; + char ro = 0; + + double_t *n = (double_t *)&__n; + + + if ( exp_sign == 'g' || exp_sign == 'G' || exp_sign == 'e' || exp_sign == 'E' ) { + ie = ((unsigned int)n->exponent - (unsigned int)0x3ff); + exponent = ie/3.321928; + } + + if ( exp_sign == 'g' || exp_sign == 'G' ) { + type |= ZEROTRUNC; + if ( exponent < -4 || fabs(exponent) >= precision ) + exp_sign -= 2; // g -> e and G -> E + + } + + if ( exp_sign == 'e' || exp_sign == 'E' ) { + frac = modf(exponent,&e); + if ( frac > 0.5 ) + e++; + else if ( frac < -0.5 ) + e--; + + + + numberf(f,__n/pow(10.0L,e),'f',size-4, precision, type); + putc( exp_sign,f); + size--; + ie = (long)e; + type = LEFT | PLUS; + if ( ie < 0 ) + type |= SIGN; + + number(f,ie, 10,2, 2,type ); + return; + } + + + if ( exp_sign == 'f' ) { + + buf = alloca(4096); + if (type & LEFT) { + type &= ~ZEROPAD; + } + + c = (type & ZEROPAD) ? '0' : ' '; + sign = 0; + if (type & SIGN) { + if (__n < 0) { + sign = '-'; + __n = fabs(__n); + size--; + } else if (type & PLUS) { + sign = '+'; + size--; + } else if (type & SPACE) { + sign = ' '; + size--; + } + } + + + + + frac = modf(__n,&intr); + + + + // # flags forces a . and prevents trucation of trailing zero's + + if ( precision > 0 ) { + + + //frac = modfl(__n,&intr); + + i = precision-1; + while ( i >= 0 ) { + frac*=10.0L; + frac = modf(frac, &p); + buf[i] = (int)p + '0'; + i--; + } + i = precision; + size -= precision; + + ro = 0; + if ( frac > 0.5 ) { + ro = 1; + } + + if ( precision >= 1 || type & SPECIAL) { + buf[i++] = '.'; + size--; + } + } + + + + if ( intr == 0.0 ) { + buf[i++] = '0'; + size--; + } + else { + + + while ( intr > 0.0 ) { + + intr/=10.0L; + p = modf(intr, &intr); + + p *=10; + + buf[i++] = (int)p + '0'; + size--; + } + + } + + + j = 0; + while ( j < i && ro == 1) { + if ( buf[j] >= '0' && buf[j] <= '8' ) { + buf[j]++; + ro = 0; + } + else if ( buf[j] == '9' ) { + buf[j] = '0'; + } + j++; + } + if ( ro == 1 ) + buf[i++] = '1'; + + buf[i] = 0; + + size -= precision; + if (!(type&(ZEROPAD+LEFT))) + while(size-->0) + putc( ' ',f); + if (sign) + putc( sign,f); + + if (!(type&(ZEROPAD+LEFT))) + while(size-->0) + putc( ' ',f); + if (type & SPECIAL) { + } + + if (!(type & LEFT)) + while (size-- > 0) + putc( c,f); + + tmp = buf; + if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) { + j = 0; + while ( j < i && ( *tmp == '0' || *tmp == '.' )) { + tmp++; + i--; + } + + } + // else + // while (i < precision--) + // putc( '0', f); + while (i-- > 0) + putc( tmp[i],f); + while (size-- > 0) + putc( ' ', f); + + + + + + } + +} + +void numberfl(FILE * f, long double __n, char exp_sign, int size, int precision, int type) { long double exponent = 0.0; @@ -185,7 +382,7 @@ void numberf(FILE * f, long double __n, char exp_sign, int size, int precision, long double p; char sign; char c; - char ro; + char ro = 0; long_double_t *n = (long_double_t *)&__n; @@ -259,7 +456,7 @@ void numberf(FILE * f, long double __n, char exp_sign, int size, int precision, if ( precision > 0 ) { - frac = modfl(__n,&intr); + //frac = modfl(__n,&intr); i = precision-1; while ( i >= 0 ) { @@ -370,6 +567,7 @@ __vfprintf(FILE *f, const char *fmt, va_list args) unsigned long num; int i, base; long double _ldouble; + double _double; const char *s; const short int* sw; @@ -378,7 +576,7 @@ __vfprintf(FILE *f, const char *fmt, va_list args) int field_width; /* width of output field */ int precision; /* min. # of digits for integers; max number of chars for from string */ - int qualifier; /* 'h', 'l', or 'L' for integer fields */ + int qualifier = 0; /* 'h', 'l', or 'L' for integer fields */ for (; *fmt ; ++fmt) { if (*fmt != '%') { @@ -498,42 +696,77 @@ __vfprintf(FILE *f, const char *fmt, va_list args) case 'g': case 'G': - if (qualifier == 'l' || qualifier == 'L' ) + if (qualifier == 'l' || qualifier == 'L' ) { _ldouble = va_arg(args, long double); - else - _ldouble = (long double)va_arg(args, double); - - if ( _isnanl(_ldouble) ) { - s = "Nan"; - len = 3; - while ( len > 0 ) { - putc(*s++,f); - len --; - } - } - else if ( _isinfl(_ldouble) < 0 ) { - s = "-Inf"; - len = 4; - while ( len > 0 ) { - putc(*s++,f); - len --; - } - } - else if ( _isinfl(_ldouble) > 0 ) { - s = "+Inf"; - len = 4; - while ( len > 0 ) { - putc(*s++,f); - len --; - } - } - else { - if ( precision == -1 ) - precision = 6; - numberf(f,_ldouble,*fmt,field_width,precision,flags); + if ( _isnanl(_ldouble) ) { + s = "Nan"; + len = 3; + while ( len > 0 ) { + putc(*s++,f); + len --; + } + + } + else if ( _isinfl(_ldouble) < 0 ) { + s = "-Inf"; + len = 4; + while ( len > 0 ) { + putc(*s++,f); + len --; + } + } + else if ( _isinfl(_ldouble) > 0 ) { + s = "+Inf"; + len = 4; + while ( len > 0 ) { + putc(*s++,f); + len --; + } + } + else { + if ( precision == -1 ) + precision = 6; + numberfl(f,_ldouble,*fmt,field_width,precision,flags); - } + } + } + else { + _double = (double)va_arg(args, double); + + if ( _isnan(_double) ) { + s = "Nan"; + len = 3; + while ( len > 0 ) { + putc(*s++,f); + len --; + } + + } + else if ( _isinf(_double) < 0 ) { + s = "-Inf"; + len = 4; + while ( len > 0 ) { + putc(*s++,f); + len --; + } + } + else if ( _isinf(_double) > 0 ) { + s = "+Inf"; + len = 4; + while ( len > 0 ) { + putc(*s++,f); + len --; + } + } + else { + if ( precision == -1 ) + precision = 6; + numberf(f,_double,*fmt,field_width,precision,flags); + + } + } + continue; case 's': s = va_arg(args, char *); diff --git a/reactos/lib/crtdll/stdio/vfscanf.c b/reactos/lib/crtdll/stdio/vfscanf.c index b4b7fac6e77..6b200e9361b 100644 --- a/reactos/lib/crtdll/stdio/vfscanf.c +++ b/reactos/lib/crtdll/stdio/vfscanf.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/reactos/lib/crtdll/stdio/vsscanf.c b/reactos/lib/crtdll/stdio/vsscanf.c index 5f0ba7c2bcc..9420a0ca783 100644 --- a/reactos/lib/crtdll/stdio/vsscanf.c +++ b/reactos/lib/crtdll/stdio/vsscanf.c @@ -17,7 +17,7 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include -#include +#include #include #include #include diff --git a/reactos/lib/crtdll/sys_stat/futime.c b/reactos/lib/crtdll/sys_stat/futime.c index 85711e1cfd3..a17d34bab5c 100644 --- a/reactos/lib/crtdll/sys_stat/futime.c +++ b/reactos/lib/crtdll/sys_stat/futime.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -18,8 +19,8 @@ int _futime (int nHandle, struct _utimbuf *pTimes) if ( pTimes == NULL ) { pTimes = alloca(sizeof(struct _utimbuf)); - time(pTimes->actime); - time(pTimes->modtime); + time(&pTimes->actime); + time(&pTimes->modtime); } if ( pTimes->actime < pTimes->modtime ) {