📄 file.c
字号:
} return 0;}int ftruncate(int fd, off_t size){ int rc, sector; struct filedesc* file = &openfiles[fd]; sector = size / SECTOR_SIZE; if (size % SECTOR_SIZE) sector++; rc = fat_seek(&(file->fatfile), sector); if (rc < 0) { errno = EIO; return rc * 10 - 1; } rc = fat_truncate(&(file->fatfile)); if (rc < 0) { errno = EIO; return rc * 10 - 2; } file->size = size; return 0;}static int flush_cache(int fd){ int rc; struct filedesc* file = &openfiles[fd]; int sector = file->fileoffset / SECTOR_SIZE; DEBUGF("Flushing dirty sector cache\n"); /* make sure we are on correct sector */ rc = fat_seek(&(file->fatfile), sector); if ( rc < 0 ) return rc * 10 - 3; rc = fat_readwrite(&(file->fatfile), 1, file->cache, true ); if ( rc < 0 ) { if(file->fatfile.eof) errno = ENOSPC; return rc * 10 - 2; } file->dirty = false; return 0;}static int readwrite(int fd, void* buf, int count, bool write){ int sectors; int nread=0; struct filedesc* file = &openfiles[fd]; int rc; if ( !file->busy ) { errno = EBADF; return -1; } LDEBUGF( "readwrite(%d,%x,%d,%s)\n", fd,buf,count,write?"write":"read"); /* attempt to read past EOF? */ if (!write && count > file->size - file->fileoffset) count = file->size - file->fileoffset; /* any head bytes? */ if ( file->cacheoffset != -1 ) { int headbytes; int offs = file->cacheoffset; if ( count <= SECTOR_SIZE - file->cacheoffset ) { headbytes = count; file->cacheoffset += count; if ( file->cacheoffset >= SECTOR_SIZE ) file->cacheoffset = -1; } else { headbytes = SECTOR_SIZE - file->cacheoffset; file->cacheoffset = -1; } if (write) { memcpy( file->cache + offs, buf, headbytes ); if (offs+headbytes == SECTOR_SIZE) { int rc = flush_cache(fd); if ( rc < 0 ) { errno = EIO; return rc * 10 - 2; } file->cacheoffset = -1; } else file->dirty = true; } else { memcpy( buf, file->cache + offs, headbytes ); } nread = headbytes; count -= headbytes; } /* if buffer has been modified, write it back to disk */ if (nread && file->dirty) { rc = flush_cache(fd); if (rc < 0) return rc * 10 - 3; } /* read/write whole sectors right into/from the supplied buffer */ sectors = count / SECTOR_SIZE; if ( sectors ) { int rc = fat_readwrite(&(file->fatfile), sectors, buf+nread, write ); if ( rc < 0 ) { DEBUGF("Failed read/writing %d sectors\n",sectors); errno = EIO; if(write && file->fatfile.eof) { DEBUGF("No space left on device\n"); errno = ENOSPC; } else { file->fileoffset += nread; } file->cacheoffset = -1; return nread ? nread : rc * 10 - 4; } else { if ( rc > 0 ) { nread += rc * SECTOR_SIZE; count -= sectors * SECTOR_SIZE; /* if eof, skip tail bytes */ if ( rc < sectors ) count = 0; } else { /* eof */ count=0; } file->cacheoffset = -1; } } /* any tail bytes? */ if ( count ) { if (write) { if ( file->fileoffset + nread < file->size ) { /* sector is only partially filled. copy-back from disk */ int rc; LDEBUGF("Copy-back tail cache\n"); rc = fat_readwrite(&(file->fatfile), 1, file->cache, false ); if ( rc < 0 ) { DEBUGF("Failed writing\n"); errno = EIO; file->fileoffset += nread; file->cacheoffset = -1; return nread ? nread : rc * 10 - 5; } /* seek back one sector to put file position right */ rc = fat_seek(&(file->fatfile), (file->fileoffset + nread) / SECTOR_SIZE); if ( rc < 0 ) { DEBUGF("fat_seek() failed\n"); errno = EIO; file->fileoffset += nread; file->cacheoffset = -1; return nread ? nread : rc * 10 - 6; } } memcpy( file->cache, buf + nread, count ); file->dirty = true; } else { rc = fat_readwrite(&(file->fatfile), 1, &(file->cache),false); if (rc < 1 ) { DEBUGF("Failed caching sector\n"); errno = EIO; file->fileoffset += nread; file->cacheoffset = -1; return nread ? nread : rc * 10 - 7; } memcpy( buf + nread, file->cache, count ); } nread += count; file->cacheoffset = count; } file->fileoffset += nread; LDEBUGF("fileoffset: %d\n", file->fileoffset); /* adjust file size to length written */ if ( write && file->fileoffset > file->size ) file->size = file->fileoffset; return nread;}ssize_t write(int fd, const void* buf, size_t count){ if (!openfiles[fd].write) { errno = EACCES; return -1; } return readwrite(fd, (void *)buf, count, true);}ssize_t read(int fd, void* buf, size_t count){ return readwrite(fd, buf, count, false);}off_t lseek(int fd, off_t offset, int whence){ int pos; int newsector; int oldsector; int sectoroffset; int rc; struct filedesc* file = &openfiles[fd]; LDEBUGF("lseek(%d,%d,%d)\n",fd,offset,whence); if ( !file->busy ) { errno = EBADF; return -1; } switch ( whence ) { case SEEK_SET: pos = offset; break; case SEEK_CUR: pos = file->fileoffset + offset; break; case SEEK_END: pos = file->size + offset; break; default: errno = EINVAL; return -2; } if ((pos < 0) || (pos > file->size)) { errno = EINVAL; return -3; } /* new sector? */ newsector = pos / SECTOR_SIZE; oldsector = file->fileoffset / SECTOR_SIZE; sectoroffset = pos % SECTOR_SIZE; if ( (newsector != oldsector) || ((file->cacheoffset==-1) && sectoroffset) ) { if ( newsector != oldsector ) { if (file->dirty) { rc = flush_cache(fd); if (rc < 0) return rc * 10 - 5; } rc = fat_seek(&(file->fatfile), newsector); if ( rc < 0 ) { errno = EIO; return rc * 10 - 4; } } if ( sectoroffset ) { rc = fat_readwrite(&(file->fatfile), 1, &(file->cache),false); if ( rc < 0 ) { errno = EIO; return rc * 10 - 6; } file->cacheoffset = sectoroffset; } else file->cacheoffset = -1; } else if ( file->cacheoffset != -1 ) file->cacheoffset = sectoroffset; file->fileoffset = pos; return pos;}int filesize(int fd){ struct filedesc* file = &openfiles[fd]; if ( !file->busy ) { errno = EBADF; return -1; } return file->size;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -