- if( fp->FD == -2 ) {\r
- size_t avail = (fp->BufferSize - fp->Pos) / size;\r
- if( avail == 0 )\r
- fp->Flags |= FILE_FLAG_EOF;\r
- if( num > avail ) num = avail;\r
- size_t bytes = num * size;\r
- memcpy((char*)fp->Buffer + fp->Pos, ptr, bytes);\r
- fp->Pos += bytes;\r
- ret = num;\r
- }\r
- else { \r
- ret = _SysWrite(fp->FD, ptr, size*num);\r
- ret /= size;\r
+ switch( _GetFileMode(fp) )\r
+ {\r
+ case FILE_FLAG_MODE_READ:\r
+ case FILE_FLAG_MODE_EXEC:\r
+ errno = EBADF;\r
+ return 0;\r
+ case FILE_FLAG_MODE_APPEND:\r
+ fseek(fp, 0, SEEK_END);\r
+ case FILE_FLAG_MODE_WRITE:\r
+ // Handle memory files first\r
+ if( fp->FD == FD_MEMFILE ) {\r
+ return _fwrite_memfile(ptr, size, num, fp);\r
+ }\r
+ else if( fp->FD == FD_MEMSTREAM ) {\r
+ return _fwrite_memstream(ptr, size, num, fp);\r
+ }\r
+ else if( fp->BufferSpace )\r
+ {\r
+ // Buffering enabled\r
+ if( fp->BufferSpace - fp->BufferPos < size*num )\r
+ {\r
+ // If there's not enough space, flush and write-through\r
+ _fflush_int(fp); // TODO: check ret\r
+ ret = _fwrite_unbuffered(fp, size, num, ptr);\r
+ }\r
+ else if( (fp->Flags & FILE_FLAG_LINEBUFFERED) && memchr(ptr,'\n',size*num) )\r
+ {\r
+ // Newline present? Flush though\r
+ _fflush_int(fp); // TODO: check ret\r
+ ret = _fwrite_unbuffered(fp, size, num, ptr);\r
+ }\r
+ else\r
+ {\r
+ // Copy to buffer\r
+ memcpy( fp->Buffer + fp->BufferPos, ptr, size*num );\r
+ fp->BufferPos += size*num;\r
+ ret = num;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ // Bufering disabled, write-though\r
+ ret = _fwrite_unbuffered(fp, size, num, ptr);\r
+ }\r
+ // errno should be set earlier\r
+ break;\r