// Write 'n' bytes from 'buf' to 'fd' at the current seek position. static ssize_t file_write(struct Fd *fd, const void *buf, size_t n, off_t offset) { int r; size_t tot; // don't write past the maximum file size tot = offset + n; if (tot > MAXFILESIZE) return -E_NO_DISK; // increase the file's size if necessary if (tot > fd->fd_file.file.f_size) { if ((r = file_trunc(fd, tot)) < 0) return r; } // write the data memcpy(fd2data(fd) + offset, buf, n); return n; }
static void* file_open(void* obj, char* path, s64 flag, s64 mode) { assert(IS_PTR(obj)); fatfile_t* file = (fatfile_t*)obj; down(&file->sem); if(*path == NULL) // last name in path { file->ref ++; if((!file->attr.directory) && (flag & O_TRUNC)) file_trunc(file); up_one(&file->sem); return file; } if(!file->attr.directory) // 路径中的名称必须是目录 { up_one(&file->sem); return (void*)-1; } char filename[32]; char* end = strchr(path, '/'); strncpy(filename, path, end -path); UpperStr(filename); if(*end == '/') // skip '/' end ++; // find in child list fatfile_t* child = findChild(file, filename); if(child == NULL) { child = (fatfile_t*)kmalloc(sizeof(fatfile_t)); memset(child, 0, sizeof(fatfile_t)); child->ops = &file_ops; sem_init(&child->sem, 1, "file sem"); child->fatfs = file->fatfs; child->name = strdup(filename); struct FAT_ENTRY entry; int index = findEntryByName(file, filename, &entry); if(index >= 0) { child->index = index; child->cluster = (entry.start_clusterHI << 16) | entry.start_clusterLO; child->size = entry.file_size; child->attr = entry.attribute; getEntryCreateDate(child, &entry); getEntryWriteDate(child, &entry); } else { if((flag &O_CREAT) && (*end == NULL)) { rtcdate rtc; cmostime(&rtc); child->cdatetime = rtc; child->wdatetime = rtc; child->dirty = TRUE; // update entry } else { kmfree(child->name); kmfree(child); up_one(&file->sem); return (void*)-2; } } insertChild(file, child); } up_one(&file->sem); return file_open(child, end, flag, mode); }