/* Opens the file with the given NAME. Returns the new file if successful or a null pointer otherwise. Fails if no file named NAME exists, or if an internal memory allocation fails. */ struct inode * filesys_open (const char *name) { struct dir *search_dir = get_cwd(name); if (search_dir == NULL) { return NULL; } struct inode *inode = NULL; if (name[0] == '/') { inode = dir_get_inode(search_dir); } char *part = malloc(NAME_MAX + 1); if (part == NULL) { return false; } memset(part, 0, NAME_MAX + 1); int retrieved_next_part; for (retrieved_next_part = get_next_part(part, &name); retrieved_next_part > 0; retrieved_next_part = get_next_part(part, &name)) { if (dir_lookup (search_dir, part, &inode)) { if (!inode_is_dir(inode)) { break; } else { dir_close(search_dir); search_dir = dir_open(inode); if (search_dir == NULL) { free(part); return false; } } } else { inode = NULL; break; } } if (inode != NULL && inode_is_dir(inode) && get_next_part(part, &name) == 0) { inode = inode_reopen(inode); } dir_close(search_dir); if (inode != NULL && get_next_part(part, &name) != 0) { inode_close(inode); inode = NULL; } free(part); return inode; }
gfarm_error_t process_set_dir_key(struct process *process, struct peer *peer, int fd, char *key, int keylen) { struct file_opening *fo; gfarm_error_t e = process_get_file_opening(process, fd, &fo); char *s; if (e != GFARM_ERR_NO_ERROR) return (e); if (!inode_is_dir(fo->inode)) return (GFARM_ERR_NOT_A_DIRECTORY); if (fo->opener != peer) return (GFARM_ERR_OPERATION_NOT_PERMITTED); s = malloc(keylen + 1); if (s == NULL) return (GFARM_ERR_NO_MEMORY); memcpy(s, key, keylen); s[keylen] = '\0'; if (fo->u.d.key != NULL) free(fo->u.d.key); fo->u.d.key = s; return (GFARM_ERR_NO_ERROR); }
/* write file */ int write(int fd, void *buffer, unsigned size) { int write_size = 0; struct file *current_file; struct inode *inode; lock_acquire(&file_lock); if(fd == 1) /* stdout */ { putbuf((const char *)buffer,size); write_size = size; } else { current_file = process_get_file(fd); inode = file_get_inode(current_file); /* if file is directory, return -1 */ if( inode_is_dir(inode) == true){ lock_release(&file_lock); return -1; } if(current_file != NULL) write_size = file_write(current_file,(const void *)buffer,size); } lock_release(&file_lock); return write_size; }
/* read directory */ bool sys_readdir(int fd, char *name) { bool result = false; struct file *pfile = process_get_file(fd); struct inode *inode = file_get_inode(pfile); struct dir *dir; int offset = 0; char entry[100]; if(pfile != NULL) { /* if file is not directory, return false */ if(inode_is_dir(inode) == false ) return result; dir = dir_open(inode); /* read directory and store to name */ while(dir_readdir(dir, entry) == true) { /* read directory except . and .. */ if( strcmp(entry,".") == 0 || strcmp(entry,"..") == 0 ) continue; /* copy entry to name */ strlcpy(&name[offset], entry, strlen(entry)+1); offset = strlen(entry) + 1; } result = true; } return true; }
/* Deletes the file named NAME. Returns true if successful, false on failure. Fails if no file named NAME exists, or if an internal memory allocation fails. */ bool filesys_remove (const char *name) { char leaf_name[NAME_MAX + 1]; if (!dir_get_leaf_name (name, leaf_name)) return false; struct dir *parent_dir = dir_get_parent_dir (name); if (parent_dir == NULL) return false; struct inode *inode; if (!dir_lookup (parent_dir, leaf_name, &inode)) { dir_close (parent_dir); return false; } bool success; if (!inode_is_dir(inode)) // if is file success = dir_remove (parent_dir, leaf_name); else { if (dir_is_empty (inode)) { success = dir_remove (parent_dir, leaf_name); } else success = false; } dir_close (parent_dir); return success; }
bool filesys_isdir (int fd) { struct file *file = file_find (fd); if (file == NULL) return false; struct inode *inode = file_get_inode (file); return inode_is_dir (inode); }
struct dir *get_directory(const char *path, bool flag){ if(strlen(path)==0) return NULL; struct dir *curr; char *word, *brkt, *buffer = malloc(strlen(path)+1), *save, *last; struct inode *inode; memcpy(buffer, path, strlen(path)+1); save = buffer; if(buffer[0]=='/'){ curr = dir_open_root(); last = strtok_r(buffer+1, "/", &brkt); } else{ if(thread_current()->dir) curr = dir_reopen(thread_current()->dir); else curr = dir_open_root(); last = strtok_r(buffer, "/", &brkt); } while(1){ word = last; if(word == NULL) break; last = strtok_r(NULL, "/", &brkt); if(last == NULL && flag) break; if(strcmp(word,"")==0); else if(strcmp(word,".")==0); else if(strcmp(word,"..")==0){ inode = inode_open(inode_parent_number(dir_get_inode(curr))); dir_close(curr); curr = dir_open(inode); } else{ inode = NULL; if(dir_lookup(curr, word, &inode)){ dir_close(curr); if(inode_is_dir(inode)) curr = dir_open(inode); else{ inode_close(inode); free(save); return NULL; } } else{ dir_close(curr); free(save); return NULL; } } } free(save); if(inode_removed(curr->inode)) return NULL; return curr; }
struct dir* get_containing_dir (const char* path) { char s[strlen(path)+1]; memcpy(s, path, strlen(path)+1); char *save_ptr, *next_token = NULL, *token = strtok_r(s, "/", &save_ptr); struct dir* dir; if (s[0] == 47 || !thread_current ()->cwd) { dir = dir_open_root (); } else { dir = dir_reopen (thread_current()->cwd); } if (token) { next_token = strtok_r (NULL, "/", &save_ptr); } while (next_token != NULL) { if (strcmp(token, ".") != 0) { struct inode *inode; if (strcmp(token, "..") == 0) { if (!dir_get_parent (dir, &inode)) { return NULL; } } else { if (!dir_lookup (dir, token, &inode)) { return NULL; } } if (inode_is_dir (inode)) { dir_close (dir); dir = dir_open (inode); } else { inode_close (inode); } } token = next_token; next_token = strtok_r (NULL, "/", &save_ptr); } return dir; }
/* Removes any entry for NAME in DIR. Returns true if successful, false on failure, which occurs only if there is no file with the given NAME. */ bool dir_remove (struct dir *dir, const char *name) { struct dir_entry e; struct inode *inode = NULL; bool success = false; off_t ofs; ASSERT (dir != NULL); ASSERT (name != NULL); inode_lock (dir_get_inode(dir)); /* Find directory entry. */ if (!lookup (dir, name, &e, &ofs)) goto done; /* Open inode. */ inode = inode_open (e.inode_sector); if (inode == NULL) goto done; if (inode_is_dir(inode) && inode_get_open_cnt(inode) > 1 ) goto done; if (inode_is_dir(inode) && !dir_is_empty(inode)) goto done; /* Erase directory entry. */ e.in_use = false; if (inode_write_at (dir->inode, &e, sizeof e, ofs) != sizeof e) goto done; /* Remove inode. */ inode_remove (inode); success = true; done: inode_close (inode); inode_unlock (dir_get_inode(dir)); return success; }
/* if file is directory, return true */ bool sys_isdir(int fd) { bool result = false; struct file *pfile; /* get file */ pfile = process_get_file(fd); if(pfile != NULL) { result = inode_is_dir(file_get_inode(pfile)); } return result; }
bool filesys_readdir (int fd, char *name) { struct file *file = file_find (fd); if (file == NULL) return false; struct inode *inode = file_get_inode (file); if (!inode_is_dir (inode)) return false; struct dir *dir = dir_open (inode); dir_set_pos (dir, file_tell (file)); bool success = dir_readdir (dir, name); file_seek (file, dir_get_pos (dir)); dir_close (dir); return success; }
/* Opens the file with the given NAME. Returns the new file if successful or a null pointer otherwise. Fails if no file named NAME exists, or if an internal memory allocation fails. */ struct file * filesys_open (const char *name) { if (strlen(name) == 0) { return NULL; } struct dir *dir = get_containing_dir (name); char* file_name = get_filename (name); struct inode *inode = NULL; if (dir != NULL) { if (strcmp(file_name, "..") == 0) { if (!dir_get_parent(dir, &inode)) { free (file_name); return NULL; } } else if ((dir_is_root(dir) && strlen(file_name) == 0) || strcmp(file_name, ".") == 0) { free (file_name); return (struct file*)dir; } else { dir_lookup(dir, file_name, &inode); } } dir_close (dir); free(file_name); if (!inode) { return NULL; } if (inode_is_dir(inode)) { return (struct file *)dir_open(inode); } return file_open (inode); }
struct dir * dir_from_path (char *path) { char *save_ptr, *token, *next = NULL; int length = strlen(path) + 1; char dir_path [length]; struct dir *directory; struct thread *cur = thread_current (); struct inode *dir_node; bool success = false; memcpy (dir_path, path, length); token = strtok_r (dir_path, "/", &save_ptr); if (dir_path[0] == SLASH_SYM || cur->dir == NULL) directory = dir_open_root (); else directory = dir_reopen (cur->dir); if (token != NULL) next = strtok_r (NULL, "/", &save_ptr); while (next != NULL) { if (strcmp (token, ".") != 0) { if (strcmp (token, "..") != 0) success = dir_lookup (directory, token, &dir_node); else success = dir_lookup (directory, token, &dir_node); if (success) { if (inode_is_dir(dir_node)) { dir_close (directory); directory = dir_open (dir_node); } } else return NULL; } token = next; next = strtok_r (NULL, "/", &save_ptr); } return directory; }
gfarm_error_t process_set_dir_offset(struct process *process, struct peer *peer, int fd, gfarm_off_t offset) { struct file_opening *fo; gfarm_error_t e = process_get_file_opening(process, fd, &fo); if (e != GFARM_ERR_NO_ERROR) return (e); if (!inode_is_dir(fo->inode)) return (GFARM_ERR_NOT_A_DIRECTORY); if (fo->opener != peer) return (GFARM_ERR_OPERATION_NOT_PERMITTED); fo->u.d.offset = offset; return (GFARM_ERR_NO_ERROR); }
gfarm_error_t process_clear_dir_key(struct process *process, struct peer *peer, int fd) { struct file_opening *fo; gfarm_error_t e = process_get_file_opening(process, fd, &fo); if (e != GFARM_ERR_NO_ERROR) return (e); if (!inode_is_dir(fo->inode)) return (GFARM_ERR_NOT_A_DIRECTORY); if (fo->opener != peer) return (GFARM_ERR_OPERATION_NOT_PERMITTED); if (fo->u.d.key != NULL) free(fo->u.d.key); fo->u.d.key = NULL; return (GFARM_ERR_NO_ERROR); }
bool filesys_chdir (const char *full_path) { char leaf_name[NAME_MAX + 1]; if (!dir_get_leaf_name (full_path, leaf_name)) return false; struct dir *parent_dir = dir_get_parent_dir (full_path); if (parent_dir == NULL) return false; struct inode *tmp; if (!dir_lookup (parent_dir, leaf_name, &tmp)) return false; if (!inode_is_dir (tmp)) return false; struct dir *actual_dir = dir_open (tmp); thread_current()->cwd_sector = inode_get_inumber(dir_get_inode (actual_dir)); dir_close (actual_dir); return true; }
/* parsing the path, and return working directory */ struct dir* parse_path(char *path_name, char *file_name) { struct dir *dir; char *token, *next_token, *save_ptr; struct inode *inode; if(path_name == NULL || file_name == NULL) return NULL; if(strlen(path_name) == 0) return NULL; /* if path name is absulute path */ if(path_name[0] == '/') dir = dir_open_root(); else /* path name is relative path */ dir = dir_reopen(thread_current()->thread_dir); token = strtok_r(path_name, "/", &save_ptr); next_token = strtok_r(NULL, "/", &save_ptr); while(token != NULL && next_token != NULL) { /* find file named token in dir directory */ if(dir_lookup(dir, token, &inode) == false) { return NULL; } /* if token is not a directory */ if(inode_is_dir(inode) == false){ dir_close(dir); return NULL; } /* close dir */ dir_close(dir); /* set dir */ dir = dir_open(inode); /* advance */ token = next_token; next_token = strtok_r(NULL, "/", &save_ptr); } /* copy token to file_name */ strlcpy(file_name, token, strlen(token)+1); return dir; }
static int open_handler (const char *file) { if (file == NULL) { return -1; } struct inode *inode = filesys_open(file); if (inode == NULL) { return -1; } struct dir *sys_dir = NULL; struct file *sys_file = NULL; if (inode_is_dir(inode)) { sys_dir = dir_open(inode); if (sys_dir == NULL) { return -1; } } else { sys_file = file_open(inode); if (sys_file == NULL) { return -1; } } struct file_struct *fstruct = malloc(sizeof(struct file_struct)); if (fstruct == NULL) { if (sys_file != NULL) { file_close(sys_file); } else { dir_close(sys_dir); } return -1; } list_push_back(&thread_current()->files, &fstruct->elem); fstruct->fd = create_fd(); fstruct->sys_file = sys_file; fstruct->sys_dir = sys_dir; return fstruct->fd; }
gfarm_error_t process_get_dir_key(struct process *process, struct peer *peer, int fd, char **keyp, int *keylenp) { struct file_opening *fo; gfarm_error_t e = process_get_file_opening(process, fd, &fo); if (e != GFARM_ERR_NO_ERROR) return (e); if (!inode_is_dir(fo->inode)) return (GFARM_ERR_NOT_A_DIRECTORY); if (fo->opener != peer) return (GFARM_ERR_OPERATION_NOT_PERMITTED); if (fo->u.d.key == NULL) { *keyp = NULL; *keylenp = 0; } else { *keyp = fo->u.d.key; *keylenp = strlen(fo->u.d.key); } return (GFARM_ERR_NO_ERROR); }
/* Creates a file named NAME with the given INITIAL_SIZE. Returns true if successful, false otherwise. Fails if a file named NAME already exists, or if internal memory allocation fails. */ bool filesys_create (const char *name, off_t initial_size, uint32_t is_dir) { block_sector_t inode_sector = (block_sector_t) -1; struct inode *inode = NULL; struct dir *search_dir = get_cwd(name); if (search_dir == NULL) { return false; } char *part = malloc(NAME_MAX + 1); if (part == NULL) { return false; } memset(part, 0, NAME_MAX + 1); int retrieved_next_part; for (retrieved_next_part = get_next_part(part, &name); retrieved_next_part > 0; retrieved_next_part = get_next_part(part, &name)) { if (dir_lookup (search_dir, part, &inode)) { if (!inode_is_dir(inode)) { break; } else { dir_close(search_dir); search_dir = dir_open(inode); if (search_dir == NULL) { free(part); return false; } } } else { inode = NULL; break; } } if (inode != NULL || get_next_part(part, &name) != 0) { if (inode != NULL && !inode_is_dir(inode)) { inode_close(inode); } dir_close(search_dir); free(part); return false; } bool success = false; if (is_dir) { block_sector_t parent_sector = inode_get_inumber(dir_get_inode(search_dir)); success = (search_dir != NULL && free_map_allocate (1, &inode_sector) && dir_create (inode_sector, initial_size, parent_sector) && dir_add (search_dir, part, inode_sector)); } else { success = (search_dir != NULL && free_map_allocate (1, &inode_sector) && inode_create (inode_sector, initial_size, is_dir) && dir_add (search_dir, part, inode_sector)); } if (!success) free_map_release (inode_sector, 1); dir_close (search_dir); free(part); return success; }
/* Deletes the file named NAME. Returns true if successful, false on failure. Fails if no file named NAME exists, or if an internal memory allocation fails. */ bool filesys_remove (const char *name) { bool success = false; struct inode *inode = NULL; struct dir *search_dir = get_cwd(name); struct dir *parent_dir = NULL; if (search_dir == NULL) { return false; } parent_dir = dir_reopen(search_dir); char *part = malloc(NAME_MAX + 1); if (part == NULL) { return false; } memset(part, 0, NAME_MAX + 1); int retrieved_next_part; for (retrieved_next_part = get_next_part(part, &name); retrieved_next_part > 0; retrieved_next_part = get_next_part(part, &name)) { if (dir_lookup (search_dir, part, &inode)) { dir_close(parent_dir); parent_dir = dir_reopen(search_dir); if (parent_dir == NULL) { dir_close(search_dir); free(part); return false; } if (!inode_is_dir(inode)) { break; } else { dir_close(search_dir); search_dir = dir_open(inode); if (search_dir == NULL) { dir_close(parent_dir); free(part); return false; } } } else { inode = NULL; break; } } if (inode == NULL || get_next_part(part, &name) != 0) { if (inode != NULL && !inode_is_dir(inode)) { inode_close(inode); } dir_close(parent_dir); dir_close(search_dir); free(part); return false; } if (parent_dir == NULL || search_dir == NULL) { dir_close(search_dir); dir_close(parent_dir); free(part); return false; } if (inode_is_dir(inode)) { char buffer[NAME_MAX + 1]; if (inode_is_open(inode) || dir_readdir(search_dir, buffer)) { success = false; } else { inode_close(inode); success = dir_remove (parent_dir, part); } } else { inode_close(inode); success = dir_remove(parent_dir, part); } dir_close(search_dir); dir_close(parent_dir); free(part); return success; }
/* Opens the file with the given NAME. Returns the new file if successful or a null pointer otherwise. Fails if no file named NAME exists, or if an internal memory allocation fails. */ struct file * filesys_open (const char *name) { //struct dir *dir = dir_open_root (); /* Start of Project 4 */ struct dir *dir = dir_from_path (name); char* file_name = retrieve_file_name (name); struct inode *dir_node = NULL; bool success = false; if (dir!= NULL) { //char *file_name = retrieve_file_name(dir); if (strcmp (file_name, "..") == 0) { success = retrieve_dir_parent (dir, &dir_node); if (!success) { free (file_name); return NULL; } } else if ((check_if_root_dir(dir) && strlen (file_name) == 0) || strcmp (file_name, ".") == 0) { free (file_name); return (struct file *) dir; } else { dir_lookup (dir, file_name, &dir_node); //success = true; } } dir_close (dir); free(file_name); if (!dir_node) { return NULL; } if (inode_is_dir (dir_node)) { return (struct file *) dir_open(dir_node); } return file_open (dir_node); /*** if (success && dir_node == NULL) return (struct file *)dir; else if (dir_node != NULL) { dir_close (dir); //if (check_if_root_dir(dir)) if (inode_is_dir (dir_node)) return (struct file *) dir_open(dir_node); else return file_open (dir_node); } else { dir_close (dir); return NULL; } ***/ /* End of Project 4 */ }
bool file_is_dir (struct file *file) { ASSERT (file != NULL); return inode_is_dir (file->inode); }