int sys_gettime(void) { struct rtcdate *d; if (argptr(0, (char **)&d, sizeof(struct rtcdate)) < 0) return -1; cmostime(d); return 0; }
int sys_date(void) { struct rtcdate *r; if(argptr(0, (void*)&r, sizeof(r)) < 0) return -1; cmostime(r); return 0; }
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); }
static int fat_rw(fatfile_t* file, u8 * buffer, s64 size, s64 pos, int mode) { assert(file); assert(buffer); assert(size > 0); assert(pos >= 0); down(&file->sem); int bytes_to_rw = 0, bytes_rw = 0, cluster_offset = 0; int cluster, i; u64 file_size = file->size; if(pos > file_size) { up_one(&file->sem); return -1; } cluster = file->cluster; // get the correct cluster to begin reading/writing from i = pos / file->fatfs->cluster_size; // we traverse the cluster chain i times while (i--) { // get the next cluster in the file cluster = fat_getFATCluster(file->fatfs, cluster); // fail if we have gone beyond the files cluster chain if (cluster == FAT_FREECLUSTER || cluster == -1) { up_one(&file->sem); return -1; } } //iobuf_t* dir_iobuf = lock_iobuf(file->fatfs, file->dir_cluster); //struct FAT_ENTRY* entry = &((struct FAT_ENTRY*)dir_iobuf->cluster_buf)[file->dir_index]; // reduce size if we are trying to read past the end of the file if (pos + size > file_size) { // but if we are writing we will need to expand the file size if (mode == FAT_WRITE) { int new_clusters = ((pos + size - file_size) / file->fatfs->cluster_size) + 1; int prev_cluster = cluster, next_cluster; // alloc more clusters while (new_clusters--) { // get a free cluster next_cluster = fat_getFreeCluster(file->fatfs); if (next_cluster < 0) { up_one(&file->sem); return -1; } if(prev_cluster == 0) { file->cluster = cluster = next_cluster; file->dirty = TRUE; // update entry } else fat_setFATCluster(file->fatfs, prev_cluster, next_cluster, FALSE);// add it on to the cluster chain // update our previous cluster number prev_cluster = next_cluster; } fat_setFATCluster(file->fatfs, prev_cluster, FAT_ENDOFCLUSTER, FALSE); } else size = file_size - pos; } while (TRUE) { cluster_offset = pos % file->fatfs->cluster_size; bytes_to_rw = file->fatfs->cluster_size - cluster_offset; if(bytes_to_rw > size) bytes_to_rw = size; iobuf_t* iobuf = lock_iobuf(file->fatfs, cluster); assert(iobuf); if (mode == FAT_WRITE) { memcpy((iobuf->cluster_buf + cluster_offset), buffer, bytes_to_rw); unlock_iobuf(file->fatfs, iobuf, TRUE, FALSE); } else { memcpy(buffer, (iobuf->cluster_buf + cluster_offset), bytes_to_rw); unlock_iobuf(file->fatfs, iobuf, FALSE, FALSE); } buffer += bytes_to_rw; pos += bytes_to_rw; bytes_rw += bytes_to_rw; size -= bytes_to_rw; if (size <= 0) break; cluster = fat_getFATCluster(file->fatfs, cluster); assert(cluster > 1 && cluster != FAT_FREECLUSTER); } if (mode == FAT_WRITE) { if(bytes_rw > 0) { cmostime(&file->wdatetime); file->dirty = TRUE; // update entry if(file->size < pos + size) file->size = pos + size; } } up_one(&file->sem); return bytes_rw; }