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

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

unix.superglobalmegacorp.com

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