[source navigation] [diff markup] [identifier search] [freetext search] [file search]

Oldlinux Cross Reference
Linux/fs/open.c

Version: [1.0] [0.99.11] [0.99] [0.98] [0.97] [0.96a] [0.95] [0.12] [0.11] [0.01]
Architecture: [i386]

  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/tty.h>
 16 #include <linux/kernel.h>
 17 #include <asm/segment.h>
 18 
 19 int sys_ustat(int dev, struct ustat * ubuf)
 20 {
 21         return -ENOSYS;
 22 }
 23 
 24 int sys_utime(char * filename, struct utimbuf * times)
 25 {
 26         struct m_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)
 48 {
 49         struct m_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)
 76 {
 77         struct m_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)
 91 {
 92         struct m_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)
106 {
107         struct m_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)
122 {
123         struct m_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)
139 {
140         struct m_inode * inode;
141         struct file * f;
142         int i,fd;
143 
144         mode &= 0777 & ~current->umask;
145         for(fd=0 ; fd<NR_OPEN ; fd++)
146                 if (!current->filp[fd])
147                         break;
148         if (fd>=NR_OPEN)
149                 return -EINVAL;
150         current->close_on_exec &= ~(1<<fd);
151         f=0+file_table;
152         for (i=0 ; i<NR_FILE ; i++,f++)
153                 if (!f->f_count) break;
154         if (i>=NR_FILE)
155                 return -EINVAL;
156         (current->filp[fd]=f)->f_count++;
157         if ((i=open_namei(filename,flag,mode,&inode))<0) {
158                 current->filp[fd]=NULL;
159                 f->f_count=0;
160                 return i;
161         }
162 /* ttys are somewhat special (ttyxx major==4, tty major==5) */
163         if (S_ISCHR(inode->i_mode))
164                 if (MAJOR(inode->i_zone[0])==4) {
165                         if (current->leader && current->tty<0) {
166                                 current->tty = MINOR(inode->i_zone[0]);
167                                 tty_table[current->tty].pgrp = current->pgrp;
168                         }
169                 } else if (MAJOR(inode->i_zone[0])==5)
170                         if (current->tty<0) {
171                                 iput(inode);
172                                 current->filp[fd]=NULL;
173                                 f->f_count=0;
174                                 return -EPERM;
175                         }
176 /* Likewise with block-devices: check for floppy_change */
177         if (S_ISBLK(inode->i_mode))
178                 check_disk_change(inode->i_zone[0]);
179         f->f_mode = inode->i_mode;
180         f->f_flags = flag;
181         f->f_count = 1;
182         f->f_inode = inode;
183         f->f_pos = 0;
184         return (fd);
185 }
186 
187 int sys_creat(const char * pathname, int mode)
188 {
189         return sys_open(pathname, O_CREAT | O_TRUNC, mode);
190 }
191 
192 int sys_close(unsigned int fd)
193 {       
194         struct file * filp;
195 
196         if (fd >= NR_OPEN)
197                 return -EINVAL;
198         current->close_on_exec &= ~(1<<fd);
199         if (!(filp = current->filp[fd]))
200                 return -EINVAL;
201         current->filp[fd] = NULL;
202         if (filp->f_count == 0)
203                 panic("Close: file count is 0");
204         if (--filp->f_count)
205                 return (0);
206         iput(filp->f_inode);
207         return (0);
208 }
209 

[source navigation] [diff markup] [identifier search] [freetext search] [file search]

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.