Example #1
0
/* Traverse -- if thread is non-NULL, update the path of the thread */
block_sector_t
path_traverse (char *path, struct thread *t)
{
  char *token, *save_ptr;
  bool found;
  struct dir dir;
  struct dir_entry entry;
  block_sector_t sector;

  if (path == NULL) return thread_get_cwd ();

  /* Check if absolute path */
  if (path[0] == '/')
  {
    sector = free_map_root_sector ();
    path++;
    if (t != NULL) thread_clear_dirs (t);
  } else {
    sector = thread_get_cwd ();
  }

  for (token = strtok_r (path, "/", &save_ptr); token != NULL;
       token = strtok_r (NULL, "/", &save_ptr))
  {
    /* Open the inode for this directory */
    dir.inode = inode_open (sector);
    dir.pos = 0;
    if (dir.inode == NULL || !inode_is_directory (dir.inode))
    {
      sector = INODE_INVALID_BLOCK_SECTOR;
      inode_close (dir.inode);
      break;
    }
    
    /* Make the thread leave the directory if applicable */
    if (t != NULL) 
      thread_leave_dir (t, dir.inode);

    /* Look up in current directory */
    found = lookup (&dir, token, &entry, NULL);
    if (found)
    {
      sector = entry.inode_sector;

      /* Make thread enter the directory if applicable */
      if (t != NULL)
        thread_enter_dir (t, dir.inode);

      inode_close (dir.inode);
    } else {
      sector = INODE_INVALID_BLOCK_SECTOR;
      inode_close (dir.inode);
      break;
    }
  }

  return sector;
}
Example #2
0
/* Deletes NAME from 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);

  lock_acquire (&dir->l);

  /* 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 directory, make sure it's empty */
  if (inode_is_directory (inode))
  {
    struct dir *inner = dir_open (inode_open (e.inode_sector));
    int size = dir_size (inner);
    dir_close (inner);
    if (size != 0)
      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. */
  success = inode_remove (inode);

done:
  lock_release (&dir->l);
  inode_close (inode);
  return success;
}
Example #3
0
/* Opens a file for the given INODE, of which it takes ownership,
   and returns the new file.  Returns a null pointer if an
   allocation fails or if INODE is null. */
struct file *
file_open (struct inode *inode) 
{
  struct file *file = calloc (1, sizeof *file);
  if (inode != NULL && file != NULL)
  {
    file->inode = inode;
    file->pos = 0;
    if (inode_is_directory (inode)) 
      file->dir = dir_open (file->inode);
    file->deny_write = false;
    return file;
  }
  else
  {
    inode_close (inode);
    free (file);
    return NULL; 
  }
}
Example #4
0
int sys_open(const char* file) {
  // memory validation
  check_user((const uint8_t*) file);

  struct file* file_opened;
  struct file_desc* fd = palloc_get_page(0);
  if (!fd) {
    return -1;
  }

  lock_acquire (&filesys_lock);
  file_opened = filesys_open(file);
  if (!file_opened) {
    palloc_free_page (fd);
    lock_release (&filesys_lock);
    return -1;
  }

  fd->file = file_opened; //file save

  // directory handling
  struct inode *inode = file_get_inode(fd->file);
  if(inode != NULL && inode_is_directory(inode)) {
    fd->dir = dir_open( inode_reopen(inode) );
  }
  else fd->dir = NULL;

  struct list* fd_list = &thread_current()->file_descriptors;
  if (list_empty(fd_list)) {
    // 0, 1, 2 are reserved for stdin, stdout, stderr
    fd->id = 3;
  }
  else {
    fd->id = (list_entry(list_back(fd_list), struct file_desc, elem)->id) + 1;
  }
  list_push_back(fd_list, &(fd->elem));

  lock_release (&filesys_lock);
  return fd->id;
}