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

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

unix.superglobalmegacorp.com

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