X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Flibc.so_src%2FfileIO.c;h=d69a4becfc7f13907bedcdf8b4f72e369212a2a6;hb=7681237dd0061c95dd4b22ca1b5c8c3c8b8fae2e;hp=23a760d61e559df9ac2039d332c38bd0bd06b723;hpb=a2210987109ab5a6337c72b45f7e52cfc9092f8f;p=tpg%2Facess2.git diff --git a/Usermode/Libraries/libc.so_src/fileIO.c b/Usermode/Libraries/libc.so_src/fileIO.c index 23a760d6..d69a4bec 100644 --- a/Usermode/Libraries/libc.so_src/fileIO.c +++ b/Usermode/Libraries/libc.so_src/fileIO.c @@ -17,7 +17,7 @@ #define _stdout 1 // === PROTOTYPES === -EXPORT void itoa(char *buf, uint64_t num, int base, int minLength, char pad, int bSigned); +EXPORT void itoa(char *buf, uint64_t num, uint base, int minLength, char pad, int bSigned); struct sFILE *get_file_struct(); // === GLOBALS === @@ -29,9 +29,9 @@ struct sFILE *stderr; // Standard Error // === CODE === /** - * \fn FILE *freopen(FILE *fp, char *file, char *mode) + * \fn FILE *freopen(char *file, char *mode, FILE *fp) */ -EXPORT FILE *freopen(FILE *fp, char *file, char *mode) +EXPORT FILE *freopen(const char *file, const char *mode, FILE *fp) { int openFlags = 0; int i; @@ -41,8 +41,8 @@ EXPORT FILE *freopen(FILE *fp, char *file, char *mode) if(fp->Flags) { fflush(fp); - close(fp->FD); - } + } else + fp->FD = -1; // Get main mode switch(mode[0]) @@ -82,7 +82,10 @@ EXPORT FILE *freopen(FILE *fp, char *file, char *mode) } //Open File - fp->FD = reopen(fp->FD, file, openFlags); + if(fp->FD != -1) + fp->FD = reopen(fp->FD, file, openFlags); + else + fp->FD = open(file, openFlags); if(fp->FD == -1) { fp->Flags = 0; return NULL; @@ -95,12 +98,12 @@ EXPORT FILE *freopen(FILE *fp, char *file, char *mode) return fp; } /** - \fn FILE *fopen(char *file, char *mode) + \fn FILE *fopen(const char *file, const char *mode) \brief Opens a file and returns the pointer \param file String - Filename to open \param mode Mode to open in */ -EXPORT FILE *fopen(char *file, char *mode) +EXPORT FILE *fopen(const char *file, const char *mode) { FILE *retFile; @@ -110,7 +113,7 @@ EXPORT FILE *fopen(char *file, char *mode) // Create Return Structure retFile = get_file_struct(); - return freopen(retFile, file, mode); + return freopen(file, mode, retFile); } EXPORT void fclose(FILE *fp) @@ -124,28 +127,55 @@ EXPORT void fflush(FILE *fp) ///\todo Implement } +EXPORT long int ftell(FILE *fp) +{ + if(!fp || !fp->FD) return -1; + + return tell(fp->FD); +} + +EXPORT int fseek(FILE *fp, long int amt, int whence) +{ + if(!fp || !fp->FD) return -1; + + return seek(fp->FD, amt, whence); +} + + /** * \fn EXPORT int vfprintf(FILE *fp, const char *format, va_list args) * \brief Print to a file from a variable argument list */ EXPORT int vfprintf(FILE *fp, const char *format, va_list args) { - va_list tmpList = args; + va_list tmpList; int size; - char *buf; - + char sbuf[1024]; + char *buf = sbuf; + + + if(!fp || !format) return -1; + + va_copy(tmpList, args); - size = vsprintf(NULL, (char*)format, tmpList); + size = vsnprintf(sbuf, 1024, (char*)format, tmpList); - buf = (char*)malloc(size+1); - buf[size] = '\0'; + if( size >= 1024 ) + { + buf = (char*)malloc(size+1); + if(!buf) { + write(_stdout, 31, "vfprintf ERROR: malloc() failed"); + return 0; + } + buf[size] = '\0'; - // Print - vsprintf(buf, (char*)format, args); + // Print + vsnprintf(buf, size+1, (char*)format, args); + } // Write to stream - write(fp->FD, size+1, buf); + write(fp->FD, size, buf); // Free buffer free(buf); @@ -172,6 +202,8 @@ EXPORT int fprintf(FILE *fp, const char *format, ...) } /** + * \fn EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp) + * \brief Write to a stream */ EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp) { @@ -183,6 +215,20 @@ EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp) return ret; } +/** + * \fn EXPORT size_t fread(void *ptr, size_t size, size_t num, FILE *fp) + * \brief Read from a stream + */ +EXPORT size_t fread(void *ptr, size_t size, size_t num, FILE *fp) +{ + int ret; + if(!fp || !fp->FD) return -1; + + ret = read(fp->FD, size*num, ptr); + + return ret; +} + /** * \fn EXPORT int fputc(int c, FILE *fp) * \brief Write a single character to the stream @@ -237,17 +283,22 @@ EXPORT int puts(const char *str) return len; } +EXPORT int vsprintf(char * __s, const char *__format, va_list __args) +{ + return vsnprintf(__s, 0x7FFFFFFF, __format, __args); +} + //sprintfv /** - \fn EXPORT void vsprintf(char *buf, const char *format, va_list args) - \brief Prints a formatted string to a buffer - \param buf Pointer - Destination Buffer - \param format String - Format String - \param args VarArgs List - Arguments -*/ -EXPORT int vsprintf(char *buf, const char *format, va_list args) + * \fn EXPORT void vsnprintf(char *buf, const char *format, va_list args) + * \brief Prints a formatted string to a buffer + * \param buf Pointer - Destination Buffer + * \param format String - Format String + * \param args VarArgs List - Arguments + */ +EXPORT int vsnprintf(char *buf, size_t __maxlen, const char *format, va_list args) { - char tmp[33]; + char tmp[65]; int c, minSize; int pos = 0; char *p; @@ -261,7 +312,7 @@ EXPORT int vsprintf(char *buf, const char *format, va_list args) { // Non-control character if (c != '%') { - if(buf) buf[pos] = c; + if(buf && pos < __maxlen) buf[pos] = c; pos ++; continue; } @@ -269,7 +320,7 @@ EXPORT int vsprintf(char *buf, const char *format, va_list args) // Control Character c = *format++; if(c == '%') { // Literal % - if(buf) buf[pos] = '%'; + if(buf && pos < __maxlen) buf[pos] = '%'; pos ++; continue; } @@ -324,12 +375,15 @@ EXPORT int vsprintf(char *buf, const char *format, va_list args) // Pointer case 'p': - if(buf) { + if(buf && pos+2 < __maxlen) { buf[pos] = '*'; buf[pos+1] = '0'; buf[pos+2] = 'x'; } pos += 3; + arg = va_arg(args, uint32_t); + itoa(tmp, arg, 16, minSize, pad, 0); + goto sprintf_puts; // Fall through to hex // Unsigned Hexadecimal case 'x': @@ -358,9 +412,11 @@ EXPORT int vsprintf(char *buf, const char *format, va_list args) p = (void*)(intptr_t)arg; sprintf_puts: if(!p) p = "(null)"; + //_SysDebug("vsnprintf: p = '%s'", p); if(buf) { while(*p) { - buf[pos++] = *p++; + if(pos < __maxlen) buf[pos] = *p; + pos ++; p ++; } } else { @@ -373,12 +429,14 @@ EXPORT int vsprintf(char *buf, const char *format, va_list args) // Unknown, just treat it as a character default: arg = va_arg(args, uint32_t); - if(buf) buf[pos] = arg; + if(buf && pos < __maxlen) buf[pos] = arg; pos ++; break; } } - if(buf) buf[pos] = '\0'; + if(buf && pos < __maxlen) buf[pos] = '\0'; + + //_SysDebug("vsnprintf: buf = '%s'", buf); return pos; } @@ -387,14 +445,20 @@ const char cUCDIGITS[] = "0123456789ABCDEF"; /** * \fn static void itoa(char *buf, uint64_t num, int base, int minLength, char pad, int bSigned) * \brief Convert an integer into a character string + * \param buf Destination Buffer + * \param num Number to convert + * \param base Base-n number output + * \param minLength Minimum length of output + * \param pad Padding used to ensure minLength + * \param bSigned Signed number output? */ -EXPORT void itoa(char *buf, uint64_t num, int base, int minLength, char pad, int bSigned) +EXPORT void itoa(char *buf, uint64_t num, size_t base, int minLength, char pad, int bSigned) { - char tmpBuf[32]; + char tmpBuf[64]; int pos=0, i; if(!buf) return; - if(base > 16) { + if(base > 16 || base < 2) { buf[0] = 0; return; } @@ -406,14 +470,15 @@ EXPORT void itoa(char *buf, uint64_t num, int base, int minLength, char pad, int } else bSigned = 0; + // Encode into reversed string while(num > base-1) { - tmpBuf[pos] = cUCDIGITS[ num % base ]; - num = (long) num / base; // Shift {number} right 1 digit - pos++; + tmpBuf[pos++] = cUCDIGITS[ num % base ]; + num = (uint64_t) num / (uint64_t)base; // Shift {number} right 1 digit } tmpBuf[pos++] = cUCDIGITS[ num % base ]; // Last digit of {number} if(bSigned) tmpBuf[pos++] = '-'; // Append sign symbol if needed + i = 0; minLength -= pos; while(minLength-- > 0) buf[i++] = pad; @@ -429,22 +494,29 @@ EXPORT int printf(const char *format, ...) { #if 1 int size; - char *buf; + char sbuf[1024]; + char *buf = sbuf; va_list args; // Get final size va_start(args, format); - size = vsprintf(NULL, (char*)format, args); + size = vsnprintf(sbuf, 1024, (char*)format, args); va_end(args); - // Allocate buffer - buf = (char*)malloc(size+1); - buf[size] = '\0'; + if( size >= 1024 ) { + // Allocate buffer + buf = (char*)malloc(size+1); + if(buf) { + write(_stdout, 29, "PRINTF ERROR: malloc() failed"); + return 0; + } + buf[size] = '\0'; - // Fill Buffer - va_start(args, format); - vsprintf(buf, (char*)format, args); - va_end(args); + // Fill Buffer + va_start(args, format); + vsnprintf(buf, size+1, (char*)format, args); + va_end(args); + } // Send to stdout write(_stdout, size+1, buf); @@ -478,3 +550,17 @@ EXPORT int sprintf(char *buf, const char *format, ...) va_end(args); return ret; } + +/** + * \fn EXPORT int snprintf(const char *buf, size_t maxlen, char *format, ...) + * \brief Print a formatted string to a buffer + */ +EXPORT int snprintf(char *buf, size_t maxlen, const char *format, ...) +{ + int ret; + va_list args; + va_start(args, format); + ret = vsnprintf((char*)buf, maxlen, (char*)format, args); + va_end(args); + return ret; +}