Example #1
0
static struct dir* filesys_get_dir (const char* path)
{
  struct dir* dir;
  int len = strlen(path);
  char *p = (char *)malloc(sizeof(char) * (len + 1));
  memcpy(p, path, len);
  p[len]='\0';

  bool openRoot = p[0]=='/' || thread_current ()->cur_dir == NULL;
  dir = openRoot ? dir_open_root() : dir_reopen(thread_current()->cur_dir);

  char *save_ptr;
  char *token = strtok_r(p, "/", &save_ptr);
  char *next_token = token!=NULL ? strtok_r(NULL, "/", &save_ptr): NULL;
  struct inode *inode;
  bool isdir;

  while (next_token!=NULL){
    if (dir_lookup(dir, token, &inode, &isdir) == NULL) return NULL;
    dir_close(dir);
    dir = dir_open(inode);
    if (isdir == false){
      dir_close(dir);
      return NULL;
    }
    token = next_token;
    next_token = strtok_r(NULL, "/", &save_ptr);
  }
  return dir;

}
Example #2
0
static struct dir *get_cwd (const char *name) {
  struct dir *search_dir = NULL;
  if (name[0] == '/') {
    search_dir = dir_open_root();
  } else {
    struct dir *cwd = thread_current()->cwd;
    if (cwd != NULL) {
      search_dir = dir_reopen(cwd);
    } else if (thread_current()->parent_data != NULL && thread_current()->parent_data->cwd != NULL) {
      search_dir = dir_reopen(thread_current()->parent_data->cwd);
    } else {
      search_dir = dir_open_root();
    }
  }

  return search_dir;
}
Example #3
0
/* 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 (strnlen (name, FULLPATH_MAX_LEN) == 0)
        return NULL;

    if (strcmp (".", name) == 0)
    {
        block_sector_t cwd = thread_current ()->cwd_sector;
        struct inode *curr = NULL;
        curr = inode_open (cwd);

        struct dir *p;
        p = dir_open (inode_open (curr->data.parent_dir_sector));

        struct dir_entry e;
        size_t ofs;

        ASSERT (p != NULL);

        for (ofs = 0;
                inode_read_at (p->inode, &e, sizeof e, ofs) == sizeof e;
                ofs += sizeof e)
        {
            if (e.inode_sector == cwd && e.in_use)
            {
                return filesys_open (e.name);
            }
        }
        return NULL;
    }
    struct inode *crr = NULL;
    crr = inode_open (thread_current ()->cwd_sector);

    struct dir *parent_dir = dir_reopen(dir_get_parent_dir (name));
    //if (crr->data.is_dir)
    //parent_dir = dir_open (inode_open (crr->data.parent_dir_sector));
    //else
    if (parent_dir == NULL)
        return NULL;

    struct inode *inode = NULL;

    char leaf_name[NAME_MAX + 1];
    if (!dir_get_leaf_name (name, leaf_name) &&
            strnlen(leaf_name, NAME_MAX) == 0)
    {
        inode = inode_reopen (dir_get_inode (parent_dir));
        dir_close (parent_dir);
        return file_open (inode);
    }

    if (parent_dir != NULL)
        dir_lookup (parent_dir, leaf_name, &inode);
    dir_close (parent_dir);

    return file_open (inode);
}
Example #4
0
//returns the inode of the last dir in name before the last /
//the user has to check for existing file after the /
struct dir *
dir_lookup_rec (const char *name) {

	//printf("lookup path is %s\n",name);

	//if the string starts with / it is an absolut path
	//root dir
	if ( strcmp( name, "/") == 0 ) return dir_open_root();

	//for the return value
	int success = 0;
	char *token ,*save_ptr;
	char * temp = (char *)malloc(strlen(name) + 1 );
	strlcpy (temp, name, strlen(name) + 1); 

	//open root and start 
	struct dir * current;

	//if it is relative make it absolute 
	if ( name[0] != '/' ) {
		current = dir_reopen(thread_current()->pwd);
	} else {
		current = dir_open_root();
	}
	
	struct inode * nextdir = dir_get_inode(current);

	//go through and check that the previous direcrtories exist
	for (token = strtok_r (temp, "/", &save_ptr); token != NULL; token = strtok_r (NULL, "/", &save_ptr)) {

		//somethings wrong if this hapens	
		if (current == NULL ) break;
		//last round has to be not existing
		if (strlen(save_ptr) == 0) {
			success = 1;
			break;
				
		}

		//goto next if token is empty in case of //a/
		if(strlen(token) !=  0) {
			//check if this directory exists true if exists
			if ( dir_lookup (current, token,&nextdir) ) {
				//check if it is a directory and then open it
				enum file_type type =  inode_type (nextdir);
				//is it a dir
				if(type == FILE_DIR) {
					dir_close(current);
					current = dir_open(nextdir);
				}
				else break;
			}
			else break;
		}
	}

  if( success == 1) return current; else return NULL;
}
Example #5
0
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;
}
Example #6
0
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;
}
Example #7
0
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;
}
Example #8
0
bool filesys_chdir(const char *name)
{
  bool success=false;
  struct inode *inode = NULL;
  struct thread *t = thread_current();
  char *file_name = get_file_name(name);
  struct dir *dir = get_directory(name);
//  printf("lookup start\n");
  if (dir != NULL)
  {
    if( strcmp(file_name,".")==0)
    {
      t->curr_dir = dir_reopen(dir);
      free(file_name);
      return true;
    }
    else if(strcmp(file_name,"..")==0)
    {
      if( inode_get_inumber(dir_get_inode(dir))==1 )
      {
        t->curr_dir = dir_open(inode_open(1));
        free(file_name);
        dir_close(dir);
        return true;
      }
      else
      {
        t->curr_dir = dir_open( inode_open(inode_get_parent(dir_get_inode(dir))));
        free(file_name);
        dir_close(dir);
        return true;
      }
    }
    success=dir_lookup (dir, file_name, &inode);
  }
  dir_close (dir);
  if(success)
  {
    t->curr_dir = dir_open(inode);
  }
  free(file_name);
/*  printf("changed dir sector: %d\n",inode_get_inumber(dir_get_inode(t->curr_dir)));
  printf("value %d\n",inode_get_data(dir_get_inode(t->curr_dir),0));*/
  return success;
}
Example #9
0
/* Adds a file named NAME to DIR, which must not already contain a
   file by that name.  The file's inode is in sector
   INODE_SECTOR.
   Returns true if successful, false on failure.
   Fails if NAME is invalid (i.e. too long) or a disk or memory
   error occurs. */
bool
dir_add (struct dir *dir, const char *name, block_sector_t inode_sector)
{
  struct dir_entry e;
  off_t ofs;
  bool success = false;

  ASSERT (dir != NULL);
  ASSERT (name != NULL);

  /* Check NAME for validity. */
  if (*name == '\0' || strlen (name) > NAME_MAX)
    return false;

  /* Check that NAME is not in use. */
  if (lookup (dir, name, NULL, NULL))
    goto done;

	struct inode* inode = inode_open(inode_sector);
	inode->up_dir = dir_reopen(dir);
	inode_close(inode);

  /* Set OFS to offset of free slot.
     If there are no free slots, then it will be set to the
     current end-of-file.
     
     inode_read_at() will only return a short read at end of file.
     Otherwise, we'd need to verify that we didn't get a short
     read due to something intermittent such as low memory. */
  for (ofs = 0; inode_read_at (dir->inode, &e, sizeof e, ofs) == sizeof e;
       ofs += sizeof e) 
    if (!e.in_use)
      break;

  /* Write slot. */
  e.in_use = true;
  strlcpy (e.name, name, sizeof e.name);
  e.inode_sector = inode_sector;
  success = inode_write_at (dir->inode, &e, sizeof e, ofs) == sizeof e;

 done:
  return success;
}
Example #10
0
/* 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;
}
Example #11
0
/* 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;
}
Example #12
0
static struct dir *get_directory(char *path)
{
  char s[1024];
  memcpy(s,path,strlen(path)+1);
  char *token, *save_ptr,*prev_token="", *next_token="";//,*save,*real;
  token = strtok_r(s,"/",&save_ptr);
//  real = strtok_r(token,"/",&save);
  struct dir *start;
    struct inode *inode;
  if( s[0]=='/' || !thread_current()->curr_dir )
  {
//    printf("when create a/b\n");
    start = dir_open_root();
  }
  else
  {
//    printf("come on\n");
    if( inode_is_removed(dir_get_inode(thread_current()->curr_dir)))
      return NULL;
    else
      start = dir_reopen(thread_current()->curr_dir);
  }
/*  
  if( strcmp(token,"." )==0)
  {
  }
  else if( strcmp(token,"..") == 0)
  {
    if( thread_current()->curr_dir)
      start = dir_get_parent(thread_current()->curr_dir);
    else
      start = dir_open_root();
  }
  else
  {
    printf("here\n");
    if(thread_current()->curr_dir)
    {
//      printf("also here\n");
      start = dir_reopen(thread_current()->curr_dir);
    }
    else
    {      
//    printf("when create a/b\n");
      start = dir_open_root();
    }
  }*/
//  printf("first setting\n");
//  real = strtok_r(token,"/",&save);
//  printf("token %s  s %s\n",token,s);
  if(token)
  {
    next_token = strtok_r(NULL,"/",&save_ptr);
/*    if(next_token == NULL)
      printf("AAAA\n");
    else
      printf("%s\n",next_token);*/
//  printf("first %s second %s\n",token,next_token);
  }
  while( next_token!=NULL)
  {
//    printf("but not here\n");
    if( strcmp(token,"." )==0)
    {
      continue;
    }
    else if( strcmp(token,"..") == 0)
    {
      if(inode_get_inumber(dir_get_inode(start))!=1)
      {
        start=dir_get_parent(start);
      }
    }
    else
    {
      if(dir_lookup(start ,token, &inode))
      {
//    printf("when create a/b token:%s\n",token);
//        printf("aaaa\n");
        dir_close(start);
        start = dir_open(inode);
      }
      else
        return NULL;
//      dir_close(start);
/*      if( inode==NULL )
      {

        return NULL;
      }
      else if(inode_is_removed(inode))
        return NULL;*/
//      start = dir_open(inode);
    }
    prev_token = token;
    token = next_token;
    next_token = strtok_r(NULL,"/",&save_ptr);
//      printf("first %s second %s\n",token,next_token);
  }
//  printf("directory name : %s \n",token);
  return start;
}
Example #13
0
/* Decomposes the given path (dir) to a final file or directory name and
 * its parent directory. Write the name to ret_name, and the parent directory
 * struct to par_dir. Returns true if the decomposition is successfull, i.e.
 * successfully decomposed the final name, and open all the directories in 
 * path successfully. */
bool decompose_dir(const char* dir, char* ret_name, struct dir** par_dir){
    /* parent directory*/
    struct dir* cur_dir;
    
    /* inode for iteration*/
    struct inode* next_inode;
    
    /* iterator for the path string*/
    unsigned i;
    
    /* Current process*/
    struct thread* t = thread_current();
    
    /* Final name of the file or the directory*/
    char name[15];
    
    /* Check that give path is not empty*/
    if (*dir == NULL || dir[0] == '\0')
        return false;

    if (dir[0] == '/') {
        /* If give an absolute path, then first set cur_dir as root. */
        cur_dir = dir_open_root();
    } else if (t->cur_dir == NULL) {
        /* Given path is relative. However, as the process's cur_dir is
         * NULL, which is equivelant to the root directory in our 
         * implemtation. Also set update proccess's cur_dir to root. */
        cur_dir = dir_open_root();
        t->cur_dir = dir_open_root();
    } else {
        /* Give path is also relative. And set cur_dir same as the process's 
         * working director. */
        if (dir_get_inode(t->cur_dir)->removed)
            /* If the working directory has been removed, then return false 
             * right away. */
            return false;
        cur_dir = dir_reopen(t->cur_dir);    
    }

    /* Iterate the path with dir as iterator until the null terminator. */
    while (*dir != '\0'){
        /* Reset the index iterator. for extract next subdirectory name. */
        i = 0;
        
        /*Skip the directory symbol*/
        while (*dir == '/')
            ++dir;
        
        /* Increment i until the directory symbol or null terminator*/
        while ((*(dir + i) != '/' && *(dir + i) != '\0') && (i <= 15)){
            ++i;
        }
        
        /* Enforces NAME_MAX length to all directories*/
        if (i > 15) {
            dir_close(cur_dir);
            return false;
        }

        /* Copy this directory name to name*/
        memcpy(name, dir, i);
        name[i] = '\0';

        /* If this is the last name, then we got our final dir / file name,
         * i.e. finished decomposition of path. */
        if (*(dir + i) == '\0')
            break;
        
        /* Look up the file / dir from the parent directory cur_dir. */
        if (!dir_lookup(cur_dir, name, &next_inode)) {
            dir_close(cur_dir);
            return false;
        }
        
        /* Close the current parent directory, as we have found the next 
         * one.*/
        dir_close(cur_dir);
        
        /* Makes sure that we are always opening a directory. */
        if  (next_inode->data.type != DIR_INODE_DISK) {
            inode_close(next_inode);
            return false;
        }
        
        /* Open up the next directory in path. */
        cur_dir = dir_open(next_inode);
        
        if (cur_dir == NULL) {
            inode_close(next_inode);
            return false;
        }
        
        /* Advance. */
        dir += i;
    }
    
    /* Set the parent directory as cur_dir*/
    *par_dir = cur_dir;
    
    /*Copy the final name ret_name*/
    strlcpy(ret_name, name, strlen(name) + 1);

    return true;
}
Example #14
0
/*! Changes the working directory of the current process (i.e. 
 * thread->cur_dir). Returns true if the operation is successfull
 * and false otherwise. */
bool _chdir(const char* dir){
    /* The current process*/
    struct thread* t = thread_current();
    
    /* inode for the new directory*/
    struct inode* next_inode;
    
    /* new directory struct*/
    struct dir* cur_dir;
    
    /* name of the directory*/
    char name[15];
    
    
    /* Check validity of the pointer*/
    if (!checkva(dir)){
       exit(-1);
    }
   
   /* Decompose the path to a final name and parent directory. */
    if (!decompose_dir(dir, name, &cur_dir))
        return false;
    
    if (strcmp(name, "\0") != 0){
        
        /* If name is not empty, then we simply look for the name
         * under the parent directory cur_dir, and get the inode
         * of this destination directory. */
        if (!dir_lookup(cur_dir, name, &next_inode)) {
            dir_close(cur_dir);
            return false;
        }
        
        /* Close the parent directory, as we do not need it any more. */
        dir_close(cur_dir);
        
        /* Check that the inode we are opening is a directory. */
        if  (next_inode->data.type != DIR_INODE_DISK) {
            inode_close(next_inode);
            return false;
        }
        
        /* Open up the inode to directory struct*/
        cur_dir = dir_open(next_inode);
        if (cur_dir == NULL) {
            inode_close(next_inode);
            return false;
        }
        
    } else if (dir[strlen(dir)] != '/'){
        /* If the name is not empty, and the give path does not end with "/" 
         * then this path is an invalid directory path. 
         * Note if the path is in fact valid and the name we get is empty,
         * then the distiniation directory has been already opened in 
         * cur_dir. */
        dir_close(cur_dir);
        return false;
    }
    
    /* Update the current process's working directory */
    dir_close(t->cur_dir);
    t->cur_dir = dir_reopen(cur_dir);
    dir_close(cur_dir);
    
    return true;
}
Example #15
0
/*! Open a file or an directory */
int open(const char *f_name) {
    /* The parent directory of the opening file or directory. */
    struct dir* cur_dir;
    
    /* Name of the file or the directory. */
    char name[15];
    
    /* CUrrent thread. */
    struct thread *t;
    
    /* file info struct for creating fd to this thread. */
    struct f_info *f;
    
    /* dir struct or file struct depending what we are opening */
    struct dir* d_open;
    struct file* f_open;
    
    /* The flag for whether we are opening a directory. */
    bool isdir;
    
    /* fd number assigned to this file / directory */
    uint32_t fd;
    
    /* Inode of the file / dir we are opening. */
    struct inode* inode;

    /* Checks the validity of the given pointer */
    if (!checkva(f_name) || f_name[0] == '\0'){
       return -1;
    }
    
    /* Decomposes a path to the final file / dir name
     * and its corresponding parent dir. */
    if (!decompose_dir(f_name, name, &cur_dir)){
        return -1;
    }
    
    /* Open the file when locking the file system. */
    lock_acquire(&filesys_lock);
    
    if (strcmp(name, "\0") != 0){
        /* If file / dir name is not empty, then look for it in its parent 
         * directory. */
        if (!dir_lookup(cur_dir, name, &inode)){
            lock_release(&filesys_lock);
            return -1;
        }
        
        /* Decide whether the inode is a directory or a file. */
        isdir = (inode->data.type == DIR_INODE_DISK);
        
        /* Open the file / dir */
        if (isdir)
            d_open = dir_open(inode);
        else
            f_open = file_open(inode);
        lock_release(&filesys_lock);
    } else {
        /* Since we decomposed the entire path to a diretory
         * then we must be opening a directory. */
        isdir = true;
        /* Reopen the directory, to store in f_info */
        d_open = dir_reopen(cur_dir);
    }
    
    if (f_open == NULL && dir_open == NULL) {
        inode_close(inode);
        /* If file open failed, then exit with error. */
        return -1;
    } else {
        /* Assign fd to the file / dir */
        t = thread_current();
        if (t->f_count > 127){
            if (isdir){
                dir_close(d_open);
            } else {
                file_close(f_open);  
            }
            return -1;
        }
        
        /* Set up new f_info */
        f = (struct f_info*) malloc(sizeof(struct f_info));
        f->isdir = isdir;
        if (isdir)
            f->d = d_open;
        else
            f->f = f_open;
        f->pos = 0;
        
        /* Update the process's fd info */
        lock_acquire(&filesys_lock);
        fd = (++(t->fd_max));
        f->fd = fd;
        
        /* Push f_info to the thread's list, 
         * and update thread's list count. */
        list_push_back(&(t->f_lst), &(f->elem));
        ++(t->f_count);
        lock_release(&filesys_lock);
    }
    return fd;

}