root/fs/open.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sys_ustat
  2. sys_utime
  3. sys_access
  4. sys_chdir
  5. sys_chroot
  6. sys_chmod
  7. sys_chown
  8. sys_open
  9. sys_creat
  10. sys_close

   1 /*
   2  *  linux/fs/open.c
   3  *
   4  *  (C) 1991  Linus Torvalds
   5  */
   6 
   7 #include <string.h>
   8 #include <errno.h>
   9 #include <fcntl.h>
  10 #include <sys/types.h>
  11 #include <utime.h>
  12 #include <sys/stat.h>
  13 
  14 #include <linux/sched.h>
  15 #include <linux/kernel.h>
  16 
  17 #include <asm/segment.h>
  18 
  19 int sys_ustat(int dev, struct ustat * ubuf)
     /* [previous][next][first][last][top][bottom][index][help] */
  20 {
  21         return -ENOSYS;
  22 }
  23 
  24 int sys_utime(char * filename, struct utimbuf * times)
     /* [previous][next][first][last][top][bottom][index][help] */
  25 {
  26         struct inode * inode;
  27         long actime,modtime;
  28 
  29         if (!(inode=namei(filename)))
  30                 return -ENOENT;
  31         if (times) {
  32                 actime = get_fs_long((unsigned long *) &times->actime);
  33                 modtime = get_fs_long((unsigned long *) &times->modtime);
  34         } else
  35                 actime = modtime = CURRENT_TIME;
  36         inode->i_atime = actime;
  37         inode->i_mtime = modtime;
  38         inode->i_dirt = 1;
  39         iput(inode);
  40         return 0;
  41 }
  42 
  43 /*
  44  * XXX should we use the real or effective uid?  BSD uses the real uid,
  45  * so as to make this call useful to setuid programs.
  46  */
  47 int sys_access(const char * filename,int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
  48 {
  49         struct inode * inode;
  50         int res, i_mode;
  51 
  52         mode &= 0007;
  53         if (!(inode=namei(filename)))
  54                 return -EACCES;
  55         i_mode = res = inode->i_mode & 0777;
  56         iput(inode);
  57         if (current->uid == inode->i_uid)
  58                 res >>= 6;
  59         else if (current->gid == inode->i_gid)
  60                 res >>= 6;
  61         if ((res & 0007 & mode) == mode)
  62                 return 0;
  63         /*
  64          * XXX we are doing this test last because we really should be
  65          * swapping the effective with the real user id (temporarily),
  66          * and then calling suser() routine.  If we do call the
  67          * suser() routine, it needs to be called last. 
  68          */
  69         if ((!current->uid) &&
  70             (!(mode & 1) || (i_mode & 0111)))
  71                 return 0;
  72         return -EACCES;
  73 }
  74 
  75 int sys_chdir(const char * filename)
     /* [previous][next][first][last][top][bottom][index][help] */
  76 {
  77         struct inode * inode;
  78 
  79         if (!(inode = namei(filename)))
  80                 return -ENOENT;
  81         if (!S_ISDIR(inode->i_mode)) {
  82                 iput(inode);
  83                 return -ENOTDIR;
  84         }
  85         iput(current->pwd);
  86         current->pwd = inode;
  87         return (0);
  88 }
  89 
  90 int sys_chroot(const char * filename)
     /* [previous][next][first][last][top][bottom][index][help] */
  91 {
  92         struct inode * inode;
  93 
  94         if (!(inode=namei(filename)))
  95                 return -ENOENT;
  96         if (!S_ISDIR(inode->i_mode)) {
  97                 iput(inode);
  98                 return -ENOTDIR;
  99         }
 100         iput(current->root);
 101         current->root = inode;
 102         return (0);
 103 }
 104 
 105 int sys_chmod(const char * filename,int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 106 {
 107         struct inode * inode;
 108 
 109         if (!(inode=namei(filename)))
 110                 return -ENOENT;
 111         if ((current->euid != inode->i_uid) && !suser()) {
 112                 iput(inode);
 113                 return -EACCES;
 114         }
 115         inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777);
 116         inode->i_dirt = 1;
 117         iput(inode);
 118         return 0;
 119 }
 120 
 121 int sys_chown(const char * filename,int uid,int gid)
     /* [previous][next][first][last][top][bottom][index][help] */
 122 {
 123         struct inode * inode;
 124 
 125         if (!(inode=namei(filename)))
 126                 return -ENOENT;
 127         if (!suser()) {
 128                 iput(inode);
 129                 return -EACCES;
 130         }
 131         inode->i_uid=uid;
 132         inode->i_gid=gid;
 133         inode->i_dirt=1;
 134         iput(inode);
 135         return 0;
 136 }
 137 
 138 int sys_open(const char * filename,int flag,int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 139 {
 140         struct inode * inode;
 141         struct file * f;
 142         int i,fd;
 143 
 144         for(fd=0 ; fd<NR_OPEN ; fd++)
 145                 if (!current->filp[fd])
 146                         break;
 147         if (fd>=NR_OPEN)
 148                 return -EINVAL;
 149         current->close_on_exec &= ~(1<<fd);
 150         f=0+file_table;
 151         for (i=0 ; i<NR_FILE ; i++,f++)
 152                 if (!f->f_count) break;
 153         if (i>=NR_FILE)
 154                 return -EINVAL;
 155         (current->filp[fd]=f)->f_count++;
 156         if ((i=open_namei(filename,flag,mode,&inode))<0) {
 157                 current->filp[fd]=NULL;
 158                 f->f_count=0;
 159                 return i;
 160         }
 161         f->f_op = NULL;
 162         f->f_mode = "\001\002\003\000"[flag & O_ACCMODE];
 163         f->f_flags = flag;
 164         f->f_count = 1;
 165         f->f_inode = inode;
 166         f->f_pos = 0;
 167         if (inode->i_op && inode->i_op->open)
 168                 if (i = inode->i_op->open(inode,f)) {
 169                         iput(inode);
 170                         f->f_count=0;
 171                         current->filp[fd]=NULL;
 172                         return i;
 173                 }
 174         return (fd);
 175 }
 176 
 177 int sys_creat(const char * pathname, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 178 {
 179         return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
 180 }
 181 
 182 int sys_close(unsigned int fd)
     /* [previous][next][first][last][top][bottom][index][help] */
 183 {       
 184         struct file * filp;
 185 
 186         if (fd >= NR_OPEN)
 187                 return -EINVAL;
 188         current->close_on_exec &= ~(1<<fd);
 189         if (!(filp = current->filp[fd]))
 190                 return -EINVAL;
 191         current->filp[fd] = NULL;
 192         if (filp->f_count == 0)
 193                 panic("Close: file count is 0");
 194         if (--filp->f_count)
 195                 return (0);
 196         iput(filp->f_inode);
 197         return (0);
 198 }

/* [previous][next][first][last][top][bottom][index][help] */