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

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