⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mfs_filesys.c

📁 实用的程序代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (new_dir_block != first_dir_block)      mfs_file_system[first_dir_block].u.dir_data.num_entries += 1;    mfs_file_system[new_dir_block].u.dir_data.dir_ent[new_dir_index].index = new_entry_index;    set_filename(mfs_file_system[new_dir_block].u.dir_data.dir_ent[new_dir_index].name, get_basename(filename));    mfs_file_system[new_dir_block].u.dir_data.dir_ent[new_dir_index].deleted = 'n';    return new_entry_index;  }}/** * move a list of blocks starting and start_index and chained * through next_block pointers and ending at end_index * to the free list * the blocks are all already marked as MFS_BLOCK_TYPE_EMPTY * the prev_block of start_index is 0, and the next_block of end_index = 0 */static int move_to_free_list(int start_index, int end_index) {  if (mfs_free_block_list != 0) { /* free list exists and is non empty */    /* prepend this list to the existing free list */    mfs_file_system[mfs_free_block_list].prev_block = end_index;    mfs_file_system[end_index].next_block = mfs_free_block_list;  }  else { /* free list is empty - no need to prepend */  }  mfs_free_block_list = start_index;  return 1; /* always succeeds */}/** * mark all the data blocks associated with a file as free and add them * to the free list * return 1 for success and 0 for failure * delete dir blocks only if the directory is empty */static int delete_data_in_file(int file_index) {  int next_block;  int current_block;  if (mfs_file_system[file_index].block_type == MFS_BLOCK_TYPE_FILE) {    /* OK to delete */  }  else if (mfs_file_system[file_index].block_type == MFS_BLOCK_TYPE_DIR) {    /* first verify whether dir is actually empty */    if (mfs_file_system[file_index].u.dir_data.num_entries - mfs_file_system[file_index].u.dir_data.num_deleted != 2) {      /* dir is not empty so cannot delete */      return 0;    }  }  else { /* don't know what this is; cannot delete */    return 0;  }  /* at this point we know that it is OK to delete */  current_block = file_index;  while((next_block = mfs_file_system[current_block].next_block) != 0) {    mfs_file_system[current_block].block_type = MFS_BLOCK_TYPE_EMPTY;    current_block = next_block;  }  mfs_file_system[current_block].block_type = MFS_BLOCK_TYPE_EMPTY;  move_to_free_list(file_index, current_block);  return 1;}/** * delete the data blocks corresponding to the file and then delete the * file entry from its directory * return 1 on success, 0 on failure * delete will not work on a directory unless the directory is empty */int mfs_delete_file (char *filename) {  int dir_block;  int dir_index;  int entry_index;  int new_block;  int first_dir_block;  if (!get_dir_ent(filename, &dir_block, &dir_index)) {     /* file does not exist */    return 0 ; /* cannot delete file if it does not exist */  }  entry_index = mfs_file_system[dir_block].u.dir_data.dir_ent[dir_index].index;  if (delete_data_in_file(entry_index)) {    /* now delete the file entry from the directory */    mfs_file_system[dir_block].u.dir_data.dir_ent[dir_index].deleted = 'y';    mfs_file_system[dir_block].u.dir_data.num_deleted += 1;    first_dir_block = get_first_dir_block(dir_block);    if (dir_block != first_dir_block)      mfs_file_system[first_dir_block].u.dir_data.num_deleted += 1;  }  return 1;}/** * create a new empty directory inside the current directory * return index of new directory in file system if success, 0 if failure  */int mfs_create_dir(char *newdir) {  return create_file(newdir, MFS_BLOCK_TYPE_DIR);}/** * delete the directory named newdir if it exists, and is empty * return 1 on success, 0 on failure * cannot delete . or .. */int mfs_delete_dir (char *newdir) {  if (!strcmp(newdir,"..") || !strcmp(newdir,"."))    return 0;  return mfs_delete_file(newdir);}/** * rename from_file to to_file * works for dirs as well as files * cannot rename to something that already exists * return 1 on success, 0 on failure */int mfs_rename_file(char *from_file, char *to_file) {  int from_dir_block;  int to_dir_block;  int from_dir_index;  int to_dir_index;  if (get_dir_ent(from_file, &from_dir_block, &from_dir_index) &&      !get_dir_ent(to_file, &to_dir_block, &to_dir_index)) {    set_filename(mfs_file_system[from_dir_block].u.dir_data.dir_ent[from_dir_index].name, get_basename(to_file));    return 1;  }  return 0;}/** * return 0 if filename is not a file in the current directory * return 1 if filename is a file in the current directory * return 2 if filename is a directory in the current directory */int mfs_exists_file(char *filename) {  int dir_block;  int dir_index;  int file_block;  if (get_dir_ent(filename, &dir_block, &dir_index)) {    file_block = mfs_file_system[dir_block].u.dir_data.dir_ent[dir_index].index;    if (mfs_file_system[file_block].block_type == MFS_BLOCK_TYPE_DIR)      return 2;    else if (mfs_file_system[file_block].block_type == MFS_BLOCK_TYPE_FILE)      return 1;    else return 0;  }  return 0;}/** * return the name of the current directory  * in dirname =  pre_allocated buffer of at least 16 chars * return 1 if success, 0 if failure */int mfs_get_current_dir_name(char *dirname){  int dir_block;  int dir_index;  int file_block;  file_block = mfs_current_dir;  if (file_block == 0) {     strcpy(dirname, "/");     return 1;  }  if(!get_dir_ent_by_index(file_block, &dir_block, &dir_index)) {     return 0; /* cannot find current dir in its parent */  }  strcpy(dirname, mfs_file_system[dir_block].u.dir_data.dir_ent[dir_index].name);  return 1;}/** * get the number of used blocks and the number of free blocks in the file system through pointers * the return value is  1 (for success) and 0 for failure to obtain the numbers */int mfs_get_usage(int *num_blocks_used, int *num_blocks_free) {  int i;  *num_blocks_used = 0;  *num_blocks_free = 0;  for ( i = 0; i < MFS_MAX_FILE_BLOCKS; i++) {    if (mfs_file_system[i].block_type == MFS_BLOCK_TYPE_EMPTY)      *num_blocks_free += 1;    else      *num_blocks_used += 1;  }  return 1;}/** * returns the index of the first free entry in the mfs_open_files array * if there is no free entry, returns -1 */static int get_first_free_ftab_index() {  int i;  for (i=0; i < MFS_MAX_OPEN_FILES; i++) {    if (mfs_open_files[i].mode == MFS_MODE_FREE)      return i;  }  return -1;}/** * mode can be MFS_MODE_READ/MFS_MODE_WRITE/MFS_MODE_CREATE * this function should be used for FILEs and not DIRs * no error checking (is this FILE and not DIR?) is done for MFS_MODE_READ * MFS_MODE_CREATE automatically creates a FILE and not a DIR * MFS_MODE_WRITE fails if the specified file is a DIR * return index of file in array mfs_open_files or -1  */int mfs_file_open(const char *filename, int mode) {  int dir_block;  int dir_index;  int current_index;  if (mfs_num_open_files >= MFS_MAX_OPEN_FILES) {/* cannot open any more files */    return -1;  }  if (mode == MFS_MODE_READ || mode == MFS_MODE_WRITE) { /* look for existing file */    if (get_dir_ent(filename, &dir_block, &dir_index)) { /* found it */      if (mode == MFS_MODE_WRITE && mfs_file_system[mfs_file_system[dir_block].u.dir_data.dir_ent[dir_index].index].block_type != MFS_BLOCK_TYPE_FILE) {	/* cannot open anything other than FILE for write */	return -1;      }      mfs_num_open_files++;      current_index = get_first_free_ftab_index();      mfs_open_files[current_index].first_block = mfs_file_system[dir_block].u.dir_data.dir_ent[dir_index].index;      mfs_open_files[current_index].current_block = mfs_open_files[current_index].first_block;      mfs_open_files[current_index].mode = mode;      mfs_open_files[current_index].offset = 0;      return current_index;    }    else {       //file/dir not found, open it in create mode       if (mode == MFS_MODE_WRITE)          mode = MFS_MODE_CREATE;    }  }  if (mode == MFS_MODE_CREATE) { /* create a new file */     dir_block = create_file(filename, MFS_BLOCK_TYPE_FILE);    if (dir_block == 0) { /* failed to create the file */      return -1;    }    mfs_num_open_files++;    current_index = get_first_free_ftab_index();    mfs_open_files[current_index].first_block = dir_block;    mfs_open_files[current_index].current_block = dir_block;    mfs_open_files[current_index].mode = MFS_MODE_WRITE;    mfs_open_files[current_index].offset = 0;    return current_index;  }  return -1;}/** * fd should be a valid index in mfs_open_files array * Works only if fd points to a file and not a dir * buf should be a pointer to a pre-allocated buffer of size buflen or more * buflen chars are read and placed in buf * if fewer than buflen chars are available then only that many chars are read * return num bytes read or 0 for error=no bytes read*/int mfs_file_read(int fd, char *buf, int buflen) {  int num_read = 0;  char *from_ptr = &(mfs_file_system[mfs_open_files[fd].current_block].u.block_data[mfs_open_files[fd].offset]);  int num_left ;  num_left =  mfs_file_system[mfs_open_files[fd].current_block].block_size ;  if (num_left > MFS_BLOCK_DATA_SIZE)    num_left = MFS_BLOCK_DATA_SIZE;  num_left -=  mfs_open_files[fd].offset ;  while (buflen > 0) {    if (num_left == 0) { /* see if there is a next_block */      int next_block = mfs_file_system[mfs_open_files[fd].current_block].next_block;      if (next_block == 0) { /* nothing more to read */	break;      }      if (mfs_file_system[next_block].block_size == 0) { /* nothing more to read */	break;      }      from_ptr = &(mfs_file_system[next_block].u.block_data[0]);      num_left = mfs_file_system[next_block].block_size;      mfs_open_files[fd].current_block = next_block;      mfs_open_files[fd].offset = 0;    }       *buf = *from_ptr;    *buf++;    *from_ptr++;    mfs_open_files[fd].offset += 1;    num_read++;    num_left--;    buflen--;  }  return num_read;}/** * fd should be a valid index in mfs_open_files array * buf should be a pointer to a pre-allocated buffer of size buflen or more * buflen chars are read from buf and written to 1 or more blocks of the file * return 1 for success or 0 for error=unable to write to file*/ int mfs_file_write (int fd, const char *buf, int buflen) {  char *to_ptr = &(mfs_file_system[mfs_open_files[fd].current_block].u.block_data[mfs_open_files[fd].offset]);  int num_left = MFS_BLOCK_DATA_SIZE - mfs_open_files[fd].offset;  while (buflen > 0) {    *to_ptr = *buf;    *buf++;    *to_ptr++;    mfs_open_files[fd].offset += 1;    num_left--;    mfs_file_system[mfs_open_files[fd].current_block].block_size +=1;    if (mfs_open_files[fd].current_block != mfs_open_files[fd].first_block)      mfs_file_system[mfs_open_files[fd].first_block].block_size += 1;    buflen--;    if (num_left == 0 && buflen > 0) { /* create next_block */      int new_block;      /* create a new file block linked from this one */      if (get_next_free_block(&new_block)) { /* found a free block */	mfs_file_system[new_block].prev_block = mfs_open_files[fd].current_block;	mfs_file_system[new_block].next_block = 0;	mfs_file_system[new_block].block_type = MFS_BLOCK_TYPE_FILE;	mfs_file_system[new_block].block_size = 0;	mfs_file_system[mfs_open_files[fd].current_block].next_block = new_block;	mfs_open_files[fd].current_block = new_block;	mfs_open_files[fd].offset = 0;      }      else { /* no space for new block  - return failure */	return 0;      }           to_ptr = &(mfs_file_system[new_block].u.block_data[0]);      num_left = MFS_BLOCK_DATA_SIZE;    }  }  return 1;}/** * recover the file table entry in mfs_open_files corresponding to the fd * if the fd is not valid, return 0 * fd is not valid if the index in mfs_open_files is out of range, or * if the corresponding entry is not an open file * return 1 on success */int mfs_file_close(int fd) {  if (fd <0 || fd >= MFS_MAX_OPEN_FILES)    return 0;  if (mfs_open_files[fd].mode != MFS_MODE_FREE) {    mfs_open_files[fd].mode = MFS_MODE_FREE;    mfs_num_open_files--;    return 1;  }  return 0;}/** * seek to a given offset within the file * if MFS_SEEK_END is specified, the offset can be either 0 or negative * otherwise offset should be positive or 0 * return 0 on failure, 1 on success * it is an error to seek before beginning of file or after the end of file */long mfs_file_lseek(int fd, long offset, int whence) {  if (fd <0 || fd >= MFS_MAX_OPEN_FILES || mfs_open_files[fd].mode == MFS_MODE_FREE)    return 0;  if (whence == MFS_SEEK_SET || whence == MFS_SEEK_CUR) {    if (whence == MFS_SEEK_CUR)      offset += mfs_open_files[fd].offset;    else      mfs_open_files[fd].current_block = mfs_open_files[fd].first_block;    if (offset > mfs_file_system[mfs_open_files[fd].first_block].block_size) { /* attempting to seek beyond end of file */      return 0;    }  }  else { /* whence == MFS_SEEK_END */    if (offset > 0) { /* cannot seek beyond end of file */      return 0;    }    else {      offset += mfs_file_system[mfs_open_files[fd].first_block].block_size;      mfs_open_files[fd].current_block = mfs_open_files[fd].first_block;    }  }  /* at this point offset is a positive value, guaranteed to be within the file    * mfs_open_files[fd].current_block is set to first_block for MFS_SEEK_SET and MFS_SEEK_END   * and is assumed to be set correctly for MFS_SEEK_CUR   */  while(offset > MFS_BLOCK_DATA_SIZE) {    mfs_open_files[fd].current_block = mfs_file_system[mfs_open_files[fd].current_block].next_block;    offset -= MFS_BLOCK_DATA_SIZE;  }  mfs_open_files[fd].offset = offset;  return 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -