X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Flibc.so_src%2FfileIO.c;h=af8f00727a7893a042e21261b4d7c2e4cb1e4cd4;hb=0eb50bc9e604f654bdb0409bb66da03b733f906c;hp=b588f2461e760c11cce74a2c511025e000690ad2;hpb=cd0a4d84497fe89a8680ac0b881007ab6e97f44d;p=tpg%2Facess2.git diff --git a/Usermode/Libraries/libc.so_src/fileIO.c b/Usermode/Libraries/libc.so_src/fileIO.c index b588f246..af8f0072 100644 --- a/Usermode/Libraries/libc.so_src/fileIO.c +++ b/Usermode/Libraries/libc.so_src/fileIO.c @@ -10,6 +10,8 @@ #include "lib.h" #include "stdio_int.h" +#define WRITE_STR(_fd, _str) write(_fd, _str, sizeof(_str)) + #define DEBUG_BUILD 0 // === CONSTANTS === @@ -17,7 +19,7 @@ #define _stdout 1 // === PROTOTYPES === -EXPORT void itoa(char *buf, uint64_t num, uint base, int minLength, char pad, int bSigned); +EXPORT void itoa(char *buf, uint64_t num, size_t base, int minLength, char pad, int bSigned); struct sFILE *get_file_struct(); // === GLOBALS === @@ -28,59 +30,83 @@ struct sFILE *stderr; // Standard Error ///\note Initialised in SoMain // === CODE === +int _fopen_modetoflags(const char *mode) +{ + int flags = 0; + + // Get main mode + switch(*mode) + { + case 'r': flags = FILE_FLAG_MODE_READ; break; + case 'w': flags = FILE_FLAG_MODE_WRITE; break; + case 'a': flags = FILE_FLAG_MODE_APPEND; break; + case 'x': flags = FILE_FLAG_MODE_EXEC; break; // Acess addon + default: + return -1; + } + mode ++; + + // Get Modifiers + for( ; *mode; mode ++ ) + { + switch(*mode) + { + case 'b': flags |= FILE_FLAG_M_BINARY; break; + case '+': flags |= FILE_FLAG_M_EXT; break; + default: + return -1; + } + } + + return flags; +} + /** * \fn FILE *freopen(char *file, char *mode, FILE *fp) */ EXPORT FILE *freopen(const char *file, const char *mode, FILE *fp) { int openFlags = 0; - int i; // Sanity Check Arguments if(!fp || !file || !mode) return NULL; - if(fp->Flags) { + if(fp->FD != -1) { fflush(fp); - } else - fp->FD = -1; - - // Get main mode - switch(mode[0]) - { - case 'r': fp->Flags = FILE_FLAG_MODE_READ; break; - case 'w': fp->Flags = FILE_FLAG_MODE_WRITE; break; - case 'a': fp->Flags = FILE_FLAG_MODE_APPEND; break; - case 'x': fp->Flags = FILE_FLAG_MODE_EXEC; break; - default: - return NULL; - } - // Get Modifiers - for(i=1;mode[i];i++) - { - switch(mode[i]) - { - case '+': fp->Flags |= FILE_FLAG_M_EXT; - } } + + // Get stdio flags + fp->Flags = _fopen_modetoflags(mode); + if(fp->Flags == -1) + return NULL; // Get Open Flags - switch(mode[0]) + switch(fp->Flags & FILE_FLAG_MODE_MASK) { // Read - case 'r': openFlags = OPENFLAG_READ; + case FILE_FLAG_MODE_READ: + openFlags = OPENFLAG_READ; if(fp->Flags & FILE_FLAG_M_EXT) openFlags |= OPENFLAG_WRITE; break; // Write - case 'w': openFlags = OPENFLAG_WRITE; + case FILE_FLAG_MODE_WRITE: + openFlags = OPENFLAG_WRITE; + if(fp->Flags & FILE_FLAG_M_EXT) + openFlags |= OPENFLAG_READ; + break; + // Execute + case FILE_FLAG_MODE_APPEND: + openFlags = OPENFLAG_APPEND; if(fp->Flags & FILE_FLAG_M_EXT) openFlags |= OPENFLAG_READ; break; // Execute - case 'x': openFlags = OPENFLAG_EXEC; + case FILE_FLAG_MODE_EXEC: + openFlags = OPENFLAG_EXEC; break; } - + //Open File if(fp->FD != -1) fp->FD = reopen(fp->FD, file, openFlags); @@ -91,7 +117,7 @@ EXPORT FILE *freopen(const char *file, const char *mode, FILE *fp) return NULL; } - if(mode[0] == 'a') { + if( (fp->Flags & FILE_FLAG_MODE_MASK) == FILE_FLAG_MODE_APPEND ) { seek(fp->FD, 0, SEEK_END); //SEEK_END } @@ -116,29 +142,116 @@ EXPORT FILE *fopen(const char *file, const char *mode) return freopen(file, mode, retFile); } -EXPORT void fclose(FILE *fp) +EXPORT FILE *fmemopen(void *buffer, size_t length, const char *mode) +{ + FILE *ret; + + if( !buffer || !mode ) return NULL; + + ret = get_file_struct(); + + ret->FD = -2; + ret->Flags = _fopen_modetoflags(mode); + if(ret->Flags == -1) { + ret->Flags = 0; + return NULL; + } + + ret->Buffer = buffer; + ret->BufferStart = 0; + ret->BufferSize = length; + + return ret; +} + +EXPORT int fclose(FILE *fp) { - close(fp->FD); - free(fp); + fflush(fp); + if( fp->FD != -1 ) { + close(fp->FD); + } + fp->Flags = 0; + fp->FD = -1; + return 0; } EXPORT void fflush(FILE *fp) { - ///\todo Implement + if( !fp || fp->FD == -1 ) + return ; + + if( !(fp->Flags & FILE_FLAG_DIRTY) ) + return ; + + // Nothing to do for memory files + if( fp->FD == -2 ) + return ; } -EXPORT long int ftell(FILE *fp) +EXPORT void clearerr(FILE *fp) { - if(!fp || !fp->FD) return -1; + if( !fp || fp->FD == -1 ) + return ; - return tell(fp->FD); + // TODO: Impliment clearerr() +} + +EXPORT int feof(FILE *fp) +{ + if( !fp || fp->FD == -1 ) + return 0; + return !!(fp->Flags & FILE_FLAG_EOF); +} + +EXPORT int ferror(FILE *fp) +{ + if( !fp || fp->FD == -1 ) + return 0; + return 0; +} +EXPORT int fileno(FILE *stream) +{ + return stream->FD; +} + +EXPORT off_t ftell(FILE *fp) +{ + if(!fp || fp->FD == -1) return -1; + + if( fp->FD == -2 ) + return fp->Pos; + else + 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); + if(!fp || fp->FD == -1) return -1; + + if( fp->FD == -2 ) { + switch(whence) + { + case SEEK_CUR: + fp->Pos += amt; + break; + case SEEK_SET: + fp->Pos = amt; + break; + case SEEK_END: + if( fp->BufferSize < (size_t)amt ) + fp->Pos = 0; + else + fp->Pos = fp->BufferSize - amt; + break; + } + if(fp->Pos > (off_t)fp->BufferSize) { + fp->Pos = fp->BufferSize; + fp->Flags |= FILE_FLAG_EOF; + } + return 0; + } + else + return seek(fp->FD, amt, whence); } @@ -150,35 +263,17 @@ EXPORT int vfprintf(FILE *fp, const char *format, va_list args) { va_list tmpList; int size; - char sbuf[1024]; - char *buf = sbuf; - - if(!fp || !format) return -1; va_copy(tmpList, args); - size = vsnprintf(sbuf, 1024, (char*)format, tmpList); - - if( size >= 1024 ) - { - buf = (char*)malloc(size+1); - if(!buf) { - write(_stdout, 31, "vfprintf ERROR: malloc() failed"); - return 0; - } - buf[size] = '\0'; - - // Print - vsnprintf(buf, size+1, (char*)format, args); - } + size = vsnprintf(NULL, 0, (char*)format, tmpList); + char buf[size+1]; + vsnprintf(buf, size+1, (char*)format, args); // Write to stream - write(fp->FD, size, buf); - - // Free buffer - free(buf); + fwrite(buf, size, 1, fp); // Return written byte count return size; @@ -207,10 +302,25 @@ EXPORT int fprintf(FILE *fp, const char *format, ...) */ EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp) { - int ret; - if(!fp || !fp->FD) return -1; - - ret = write(fp->FD, size*num, ptr); + size_t ret; + + if(!fp || fp->FD == -1) + return -1; + + if( fp->FD == -2 ) { + size_t avail = (fp->BufferSize - fp->Pos) / size; + if( avail == 0 ) + fp->Flags |= FILE_FLAG_EOF; + if( num > avail ) num = avail; + size_t bytes = num * size; + memcpy((char*)fp->Buffer + fp->Pos, ptr, bytes); + fp->Pos += bytes; + ret = num; + } + else { + ret = write(fp->FD, ptr, size*num); + ret /= size; + } return ret; } @@ -221,11 +331,26 @@ EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp) */ 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); - + size_t ret; + + if(!fp || fp->FD == -1) + return -1; + + if( fp->FD == -2 ) { + size_t avail = (fp->BufferSize - fp->Pos) / size; + if( avail == 0 ) + fp->Flags |= FILE_FLAG_EOF; + if( num > avail ) num = avail; + size_t bytes = num * size; + memcpy(ptr, (char*)fp->Buffer + fp->Pos, bytes); + fp->Pos += bytes; + ret = num; + } + else { + ret = read(fp->FD, ptr, size*num); + ret /= size; + } + return ret; } @@ -235,8 +360,13 @@ EXPORT size_t fread(void *ptr, size_t size, size_t num, FILE *fp) */ EXPORT int fputc(int c, FILE *fp) { - if(!fp || !fp->FD) return -1; - return write(fp->FD, 1, &c); + return fwrite(&c, 1, 1, fp); +} + +EXPORT int putchar(int c) +{ + c &= 0xFF; + return write(_stdout, &c, 1); } /** @@ -246,8 +376,15 @@ EXPORT int fputc(int c, FILE *fp) EXPORT int fgetc(FILE *fp) { char ret = 0; - if(!fp) return -1; - if(read(fp->FD, 1, &ret) == -1) return -1; + if( fread(&ret, 1, 1, fp) == (size_t)-1 ) + return -1; + return ret; +} + +EXPORT int getchar(void) +{ + char ret = 0; + if(read(_stdin, &ret, 1) != 1) return -1; return ret; } @@ -261,25 +398,25 @@ FILE *get_file_struct() int i; for(i=0;i= 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); - vsnprintf(buf, size+1, (char*)format, args); - va_end(args); - } // Send to stdout - write(_stdout, size+1, buf); + write(_stdout, buf, size+1); // Free buffer free(buf); // Return return size; - - #else - - int ret; - va_list args; - va_start(args, format); - ret = fprintfv(stdout, (char*)format, args); - va_end(args); - return ret; - #endif } /**