Subversion Repositories HelenOS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /* This file contains the code for performing four system calls relating to
  2.  * status and directories.
  3.  */
  4.  
  5. /* Methods:
  6.  * do_chdir:  perform the CHDIR system call
  7.  * do_stat:   perform the STAT system call
  8.  * do_fstat:  perform the FSTAT system call
  9.  */
  10.  
  11.  
  12. #include "fs.h"
  13. #include "stat.h"
  14. #include "file.h"
  15. #include "fproc.h"
  16. #include "inode.h"
  17. #include "param.h"
  18.  
  19.  
  20. static int change(inode_t **iip, char *name_ptr, int len);
  21. static int stat_inode(inode_t *rip, filp_t *fil_ptr, char *user_addr);
  22.    
  23. int do_chdir()
  24. {
  25.      
  26.     /* Perform the chdir(file_name) system call */
  27.     int r;
  28.  
  29.     r = change(&fp->fp_workdir, file_name, strlen(file_name)+1);
  30.    
  31.     return r;
  32. }
  33.        
  34. int change(inode_t **iip, char *name_ptr, int len)
  35. {
  36.    
  37.     /*
  38.      * iip:     pointer to the inode pointer for the dir
  39.      * name_ptr:    pointer to the directory name to change to
  40.      * len:     length of the directory name string
  41.      */
  42.  
  43.     /* Do the actual work for chdir() and chroot(). */
  44.    
  45.     inode_t *rip;
  46.     register int r;
  47.      
  48.     r = OK;
  49.  
  50.     /* Try to open the new directory. */
  51.     if (fetch_name(name_ptr, len) != OK)
  52.         return err_code;
  53.      
  54.     if ((rip = eat_path(user_path)) == NIL_INODE)
  55.         return err_code;
  56.      
  57.     /* It must be a directory and also be searchable. */
  58.     if ((rip->i_mode & I_TYPE) != I_DIRECTORY)
  59.         r = FS_ENOTDIR;
  60.  
  61.     /* If error, return inode. */
  62.     if (r != OK) {
  63.         put_inode(rip);
  64.         return r;
  65.     }
  66.        
  67.     /* Everything is OK.  Make the change. */
  68.     put_inode(*iip);    /* release the old directory */
  69.     *iip = rip;     /* acquire the new one */
  70.  
  71.     return OK;
  72. }
  73.    
  74. int do_stat()
  75. {
  76.    
  77.     /* Perform the stat(name, buf) system call. */
  78.    
  79.     register inode_t *rip;
  80.     register int r;
  81.    
  82.     /* Both stat() and fstat() use the same routine to do the real work.  That
  83.      * routine expects an inode, so acquire it temporarily.
  84.      */
  85.      
  86.     if (fetch_name(file_name, strlen(file_name)+1) != OK)
  87.         return err_code;
  88.      
  89.     if ((rip = eat_path(user_path)) == NIL_INODE)
  90.         return err_code;
  91.      
  92.     r = stat_inode(rip, NIL_FILP, fp->buffer); /* actually do the work.*/
  93.     put_inode(rip);     /* release the inode */
  94.      
  95.     return r;
  96. }
  97.    
  98. int do_fstat()
  99. {
  100.    
  101.     /* Perform the fstat(fd, buf) system call. */
  102.    
  103.     register filp_t *rfilp;
  104.      
  105.  
  106.     /* Is the file descriptor valid? */
  107.     if ((rfilp = get_filp(fd)) == NIL_FILP)
  108.         return err_code;
  109.      
  110.     if (rfilp->filp_ino == NIL_INODE)
  111.         return FS_ENOENT;
  112.      
  113.     return(stat_inode(rfilp->filp_ino, NIL_FILP, fp->buffer));
  114. }
  115.    
  116. int stat_inode(register inode_t *rip, filp_t *fil_ptr, char *user_addr)
  117. {  
  118.    
  119.     /*
  120.      * rip:         pointer to inode to stat
  121.      * fil_ptr:     filp pointer, supplied by 'fstat'
  122.      * user_addr:   user space address where stat buf goes
  123.      */
  124.  
  125.     /* Common code for stat and fstat system calls. */
  126.    
  127.     stat_t statbuf;
  128.    
  129.     /* Fill in the statbuf struct. */
  130.     statbuf.st_ino = rip->i_num;
  131.     statbuf.st_mode = rip->i_mode;
  132.     statbuf.st_nlink = rip->i_nlinks & BYTE;
  133.     statbuf.st_size = rip->i_size;
  134.    
  135.     /* Copy infomations to userspace. */
  136.     memcpy(user_addr, &statbuf, sizeof(statbuf));
  137.      
  138.     return OK;
  139. }
  140.  
  141.