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

1.1.1.2   root        1: /*
                      2:  *  linux/fs/open.c
                      3:  *
                      4:  *  (C) 1991  Linus Torvalds
                      5:  */
                      6: 
1.1       root        7: #include <errno.h>
                      8: #include <fcntl.h>
                      9: #include <sys/types.h>
                     10: #include <utime.h>
1.1.1.6 ! root       11: 
1.1       root       12: #include <sys/stat.h>
1.1.1.6 ! root       13: #include <sys/vfs.h>
1.1       root       14: 
1.1.1.6 ! root       15: #include <linux/string.h>
1.1       root       16: #include <linux/sched.h>
                     17: #include <linux/kernel.h>
1.1.1.3   root       18: 
1.1       root       19: #include <asm/segment.h>
                     20: 
1.1.1.6 ! root       21: struct file_operations * chrdev_fops[MAX_CHRDEV] = {
        !            22:        NULL,
        !            23: };
        !            24: 
        !            25: struct file_operations * blkdev_fops[MAX_BLKDEV] = {
        !            26:        NULL,
        !            27: };
        !            28: 
1.1.1.2   root       29: int sys_ustat(int dev, struct ustat * ubuf)
                     30: {
                     31:        return -ENOSYS;
                     32: }
                     33: 
1.1.1.6 ! root       34: int sys_statfs(const char * path, struct statfs * buf)
        !            35: {
        !            36:        printk("statfs not implemented\n");
        !            37:        return -ENOSYS;
        !            38: }
        !            39: 
        !            40: int sys_fstatfs(unsigned int fd, struct statfs * buf)
        !            41: {
        !            42:        printk("fstatfs not implemented\n");
        !            43:        return -ENOSYS;
        !            44: }
        !            45: 
        !            46: int sys_truncate(const char * path, unsigned int length)
        !            47: {
        !            48:        struct inode * inode;
        !            49: 
        !            50:        if (!(inode = namei(path)))
        !            51:                return -ENOENT;
        !            52:        if (S_ISDIR(inode->i_mode) || !permission(inode,MAY_WRITE)) {
        !            53:                iput(inode);
        !            54:                return -EACCES;
        !            55:        }
        !            56:        inode->i_size = length;
        !            57:        if (inode->i_op && inode->i_op->truncate)
        !            58:                inode->i_op->truncate(inode);
        !            59:        inode->i_atime = inode->i_mtime = CURRENT_TIME;
        !            60:        inode->i_dirt = 1;
        !            61:        iput(inode);
        !            62:        return 0;
        !            63: }
        !            64: 
        !            65: int sys_ftruncate(unsigned int fd, unsigned int length)
        !            66: {
        !            67:        struct inode * inode;
        !            68:        struct file * file;
        !            69: 
        !            70:        if (fd >= NR_OPEN || !(file = current->filp[fd]))
        !            71:                return -EBADF;
        !            72:        if (!(inode = file->f_inode))
        !            73:                return -ENOENT;
        !            74:        if (S_ISDIR(inode->i_mode) || !(file->f_flags & 2))
        !            75:                return -EACCES;
        !            76:        inode->i_size = length;
        !            77:        if (inode->i_op && inode->i_op->truncate)
        !            78:                inode->i_op->truncate(inode);
        !            79:        inode->i_atime = inode->i_mtime = CURRENT_TIME;
        !            80:        inode->i_dirt = 1;
        !            81:        return 0;
        !            82: }
        !            83: 
1.1       root       84: int sys_utime(char * filename, struct utimbuf * times)
                     85: {
1.1.1.4   root       86:        struct inode * inode;
1.1       root       87:        long actime,modtime;
                     88: 
                     89:        if (!(inode=namei(filename)))
                     90:                return -ENOENT;
                     91:        if (times) {
1.1.1.5   root       92:                if (current->euid != inode->i_uid &&
                     93:                    !permission(inode,MAY_WRITE)) {
                     94:                        iput(inode);
1.1.1.6 ! root       95:                        return -EACCES;
1.1.1.5   root       96:                }
1.1       root       97:                actime = get_fs_long((unsigned long *) &times->actime);
                     98:                modtime = get_fs_long((unsigned long *) &times->modtime);
                     99:        } else
                    100:                actime = modtime = CURRENT_TIME;
                    101:        inode->i_atime = actime;
                    102:        inode->i_mtime = modtime;
                    103:        inode->i_dirt = 1;
                    104:        iput(inode);
                    105:        return 0;
                    106: }
                    107: 
1.1.1.2   root      108: /*
                    109:  * XXX should we use the real or effective uid?  BSD uses the real uid,
                    110:  * so as to make this call useful to setuid programs.
                    111:  */
1.1       root      112: int sys_access(const char * filename,int mode)
                    113: {
1.1.1.4   root      114:        struct inode * inode;
1.1.1.2   root      115:        int res, i_mode;
1.1       root      116: 
                    117:        mode &= 0007;
                    118:        if (!(inode=namei(filename)))
                    119:                return -EACCES;
1.1.1.2   root      120:        i_mode = res = inode->i_mode & 0777;
1.1       root      121:        iput(inode);
1.1.1.2   root      122:        if (current->uid == inode->i_uid)
1.1       root      123:                res >>= 6;
1.1.1.2   root      124:        else if (current->gid == inode->i_gid)
1.1       root      125:                res >>= 6;
                    126:        if ((res & 0007 & mode) == mode)
                    127:                return 0;
1.1.1.2   root      128:        /*
                    129:         * XXX we are doing this test last because we really should be
                    130:         * swapping the effective with the real user id (temporarily),
                    131:         * and then calling suser() routine.  If we do call the
                    132:         * suser() routine, it needs to be called last. 
                    133:         */
                    134:        if ((!current->uid) &&
                    135:            (!(mode & 1) || (i_mode & 0111)))
                    136:                return 0;
1.1       root      137:        return -EACCES;
                    138: }
                    139: 
                    140: int sys_chdir(const char * filename)
                    141: {
1.1.1.4   root      142:        struct inode * inode;
1.1       root      143: 
                    144:        if (!(inode = namei(filename)))
                    145:                return -ENOENT;
                    146:        if (!S_ISDIR(inode->i_mode)) {
                    147:                iput(inode);
                    148:                return -ENOTDIR;
                    149:        }
1.1.1.6 ! root      150:        if (!permission(inode,MAY_EXEC)) {
        !           151:                iput(inode);
        !           152:                return -EACCES;
        !           153:        }
1.1       root      154:        iput(current->pwd);
                    155:        current->pwd = inode;
                    156:        return (0);
                    157: }
                    158: 
                    159: int sys_chroot(const char * filename)
                    160: {
1.1.1.4   root      161:        struct inode * inode;
1.1       root      162: 
                    163:        if (!(inode=namei(filename)))
                    164:                return -ENOENT;
                    165:        if (!S_ISDIR(inode->i_mode)) {
                    166:                iput(inode);
                    167:                return -ENOTDIR;
                    168:        }
1.1.1.6 ! root      169:        if (!suser()) {
        !           170:                iput(inode);
        !           171:                return -EPERM;
        !           172:        }
1.1       root      173:        iput(current->root);
                    174:        current->root = inode;
                    175:        return (0);
                    176: }
                    177: 
1.1.1.6 ! root      178: int sys_fchmod(unsigned int fd, mode_t mode)
1.1       root      179: {
1.1.1.4   root      180:        struct inode * inode;
1.1.1.6 ! root      181:        struct file * file;
1.1       root      182: 
1.1.1.6 ! root      183:        if (fd >= NR_OPEN || !(file = current->filp[fd]))
        !           184:                return -EBADF;
        !           185:        if (!(inode = file->f_inode))
        !           186:                return -ENOENT;
        !           187:        if ((current->euid != inode->i_uid) && !suser())
        !           188:                return -EPERM;
        !           189:        inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777);
        !           190:        inode->i_dirt = 1;
        !           191:        return 0;
        !           192: }
        !           193: 
        !           194: int sys_chmod(const char * filename, mode_t mode)
        !           195: {
        !           196:        struct inode * inode;
        !           197: 
        !           198:        if (!(inode = namei(filename)))
1.1       root      199:                return -ENOENT;
1.1.1.2   root      200:        if ((current->euid != inode->i_uid) && !suser()) {
                    201:                iput(inode);
1.1.1.6 ! root      202:                return -EPERM;
1.1.1.2   root      203:        }
1.1       root      204:        inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777);
                    205:        inode->i_dirt = 1;
                    206:        iput(inode);
                    207:        return 0;
                    208: }
                    209: 
1.1.1.6 ! root      210: int sys_fchown(unsigned int fd, uid_t user, gid_t group)
1.1       root      211: {
1.1.1.4   root      212:        struct inode * inode;
1.1.1.6 ! root      213:        struct file * file;
1.1       root      214: 
1.1.1.6 ! root      215:        if (fd >= NR_OPEN || !(file = current->filp[fd]))
        !           216:                return -EBADF;
        !           217:        if (!(inode = file->f_inode))
1.1       root      218:                return -ENOENT;
1.1.1.6 ! root      219:        if ((current->euid == inode->i_uid && user == inode->i_uid &&
        !           220:             (in_group_p(group) || group == inode->i_gid)) ||
        !           221:            suser()) {
        !           222:                inode->i_uid = user;
        !           223:                inode->i_gid = group;
        !           224:                inode->i_dirt=1;
        !           225:                return 0;
        !           226:        }
        !           227:        return -EPERM;
        !           228: }
        !           229: 
        !           230: int sys_chown(const char * filename, uid_t user, gid_t group)
        !           231: {
        !           232:        struct inode * inode;
        !           233: 
        !           234:        if (!(inode = lnamei(filename)))
        !           235:                return -ENOENT;
        !           236:        if ((current->euid == inode->i_uid && user == inode->i_uid &&
        !           237:             (in_group_p(group) || group == inode->i_gid)) ||
        !           238:            suser()) {
        !           239:                inode->i_uid = user;
        !           240:                inode->i_gid = group;
        !           241:                inode->i_dirt=1;
1.1       root      242:                iput(inode);
1.1.1.6 ! root      243:                return 0;
1.1       root      244:        }
                    245:        iput(inode);
1.1.1.6 ! root      246:        return -EPERM;
1.1       root      247: }
                    248: 
                    249: int sys_open(const char * filename,int flag,int mode)
                    250: {
1.1.1.4   root      251:        struct inode * inode;
1.1       root      252:        struct file * f;
                    253:        int i,fd;
                    254: 
                    255:        for(fd=0 ; fd<NR_OPEN ; fd++)
                    256:                if (!current->filp[fd])
                    257:                        break;
                    258:        if (fd>=NR_OPEN)
                    259:                return -EINVAL;
                    260:        current->close_on_exec &= ~(1<<fd);
                    261:        f=0+file_table;
                    262:        for (i=0 ; i<NR_FILE ; i++,f++)
                    263:                if (!f->f_count) break;
                    264:        if (i>=NR_FILE)
                    265:                return -EINVAL;
1.1.1.6 ! root      266:        (current->filp[fd] = f)->f_count++;
        !           267:        if ((i = open_namei(filename,flag,mode,&inode))<0) {
1.1       root      268:                current->filp[fd]=NULL;
                    269:                f->f_count=0;
                    270:                return i;
                    271:        }
1.1.1.4   root      272:        f->f_mode = "\001\002\003\000"[flag & O_ACCMODE];
1.1       root      273:        f->f_flags = flag;
                    274:        f->f_count = 1;
                    275:        f->f_inode = inode;
                    276:        f->f_pos = 0;
1.1.1.6 ! root      277:        f->f_reada = 0;
        !           278:        f->f_op = NULL;
        !           279:        if (inode->i_op)
        !           280:                f->f_op = inode->i_op->default_file_ops;
        !           281:        if (f->f_op && f->f_op->open)
        !           282:                if (i = f->f_op->open(inode,f)) {
1.1.1.4   root      283:                        iput(inode);
                    284:                        f->f_count=0;
                    285:                        current->filp[fd]=NULL;
                    286:                        return i;
                    287:                }
1.1       root      288:        return (fd);
                    289: }
                    290: 
                    291: int sys_creat(const char * pathname, int mode)
                    292: {
1.1.1.4   root      293:        return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
1.1       root      294: }
                    295: 
                    296: int sys_close(unsigned int fd)
                    297: {      
                    298:        struct file * filp;
                    299: 
                    300:        if (fd >= NR_OPEN)
                    301:                return -EINVAL;
                    302:        current->close_on_exec &= ~(1<<fd);
                    303:        if (!(filp = current->filp[fd]))
                    304:                return -EINVAL;
                    305:        current->filp[fd] = NULL;
1.1.1.6 ! root      306:        if (filp->f_count == 0) {
        !           307:                printk("Close: file count is 0\n");
        !           308:                return 0;
        !           309:        }
        !           310:        if (filp->f_count > 1) {
        !           311:                filp->f_count--;
        !           312:                return 0;
        !           313:        }
        !           314:        if (filp->f_op && filp->f_op->release)
        !           315:                filp->f_op->release(filp->f_inode,filp);
1.1       root      316:        iput(filp->f_inode);
1.1.1.6 ! root      317:        filp->f_count--;
        !           318:        return 0;
1.1       root      319: }

unix.superglobalmegacorp.com

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