Annotation of linux/fs/open.c, revision 1.1.1.5

1.1.1.2   root        1: /*
                      2:  *  linux/fs/open.c
                      3:  *
                      4:  *  (C) 1991  Linus Torvalds
                      5:  */
                      6: 
1.1       root        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>
1.1.1.3   root       16: 
1.1       root       17: #include <asm/segment.h>
                     18: 
1.1.1.2   root       19: int sys_ustat(int dev, struct ustat * ubuf)
                     20: {
                     21:        return -ENOSYS;
                     22: }
                     23: 
1.1       root       24: int sys_utime(char * filename, struct utimbuf * times)
                     25: {
1.1.1.4   root       26:        struct inode * inode;
1.1       root       27:        long actime,modtime;
                     28: 
                     29:        if (!(inode=namei(filename)))
                     30:                return -ENOENT;
                     31:        if (times) {
1.1.1.5 ! root       32:                if (current->euid != inode->i_uid &&
        !            33:                    !permission(inode,MAY_WRITE)) {
        !            34:                        iput(inode);
        !            35:                        return -EPERM;
        !            36:                }
1.1       root       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: 
1.1.1.2   root       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:  */
1.1       root       52: int sys_access(const char * filename,int mode)
                     53: {
1.1.1.4   root       54:        struct inode * inode;
1.1.1.2   root       55:        int res, i_mode;
1.1       root       56: 
                     57:        mode &= 0007;
                     58:        if (!(inode=namei(filename)))
                     59:                return -EACCES;
1.1.1.2   root       60:        i_mode = res = inode->i_mode & 0777;
1.1       root       61:        iput(inode);
1.1.1.2   root       62:        if (current->uid == inode->i_uid)
1.1       root       63:                res >>= 6;
1.1.1.2   root       64:        else if (current->gid == inode->i_gid)
1.1       root       65:                res >>= 6;
                     66:        if ((res & 0007 & mode) == mode)
                     67:                return 0;
1.1.1.2   root       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;
1.1       root       77:        return -EACCES;
                     78: }
                     79: 
                     80: int sys_chdir(const char * filename)
                     81: {
1.1.1.4   root       82:        struct inode * inode;
1.1       root       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)
                     96: {
1.1.1.4   root       97:        struct inode * inode;
1.1       root       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)
                    111: {
1.1.1.4   root      112:        struct inode * inode;
1.1       root      113: 
                    114:        if (!(inode=namei(filename)))
                    115:                return -ENOENT;
1.1.1.2   root      116:        if ((current->euid != inode->i_uid) && !suser()) {
                    117:                iput(inode);
                    118:                return -EACCES;
                    119:        }
1.1       root      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)
                    127: {
1.1.1.4   root      128:        struct inode * inode;
1.1       root      129: 
                    130:        if (!(inode=namei(filename)))
                    131:                return -ENOENT;
1.1.1.2   root      132:        if (!suser()) {
1.1       root      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)
                    144: {
1.1.1.4   root      145:        struct inode * inode;
1.1       root      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:        }
1.1.1.4   root      166:        f->f_op = NULL;
                    167:        f->f_mode = "\001\002\003\000"[flag & O_ACCMODE];
1.1       root      168:        f->f_flags = flag;
                    169:        f->f_count = 1;
                    170:        f->f_inode = inode;
                    171:        f->f_pos = 0;
1.1.1.4   root      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:                }
1.1       root      179:        return (fd);
                    180: }
                    181: 
                    182: int sys_creat(const char * pathname, int mode)
                    183: {
1.1.1.4   root      184:        return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
1.1       root      185: }
                    186: 
                    187: int sys_close(unsigned int fd)
                    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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.