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

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: 
                     12: #include <sys/vfs.h>
1.1       root       13: 
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       root      104: int sys_utime(char * filename, struct utimbuf * times)
                    105: {
1.1.1.4   root      106:        struct inode * inode;
1.1       root      107:        long actime,modtime;
                    108: 
                    109:        if (!(inode=namei(filename)))
                    110:                return -ENOENT;
                    111:        if (times) {
1.1.1.5   root      112:                if (current->euid != inode->i_uid &&
                    113:                    !permission(inode,MAY_WRITE)) {
                    114:                        iput(inode);
1.1.1.6   root      115:                        return -EACCES;
1.1.1.5   root      116:                }
1.1       root      117:                actime = get_fs_long((unsigned long *) &times->actime);
                    118:                modtime = get_fs_long((unsigned long *) &times->modtime);
                    119:        } else
                    120:                actime = modtime = CURRENT_TIME;
                    121:        inode->i_atime = actime;
                    122:        inode->i_mtime = modtime;
                    123:        inode->i_dirt = 1;
                    124:        iput(inode);
                    125:        return 0;
                    126: }
                    127: 
1.1.1.2   root      128: /*
                    129:  * XXX should we use the real or effective uid?  BSD uses the real uid,
                    130:  * so as to make this call useful to setuid programs.
                    131:  */
1.1       root      132: int sys_access(const char * filename,int mode)
                    133: {
1.1.1.4   root      134:        struct inode * inode;
1.1.1.2   root      135:        int res, i_mode;
1.1       root      136: 
                    137:        mode &= 0007;
                    138:        if (!(inode=namei(filename)))
                    139:                return -EACCES;
1.1.1.2   root      140:        i_mode = res = inode->i_mode & 0777;
1.1       root      141:        iput(inode);
1.1.1.2   root      142:        if (current->uid == inode->i_uid)
1.1       root      143:                res >>= 6;
1.1.1.7 ! root      144:        else if (in_group_p(inode->i_gid))
        !           145:                res >>= 3;
1.1       root      146:        if ((res & 0007 & mode) == mode)
                    147:                return 0;
1.1.1.2   root      148:        /*
                    149:         * XXX we are doing this test last because we really should be
                    150:         * swapping the effective with the real user id (temporarily),
                    151:         * and then calling suser() routine.  If we do call the
                    152:         * suser() routine, it needs to be called last. 
                    153:         */
                    154:        if ((!current->uid) &&
                    155:            (!(mode & 1) || (i_mode & 0111)))
                    156:                return 0;
1.1       root      157:        return -EACCES;
                    158: }
                    159: 
                    160: int sys_chdir(const char * filename)
                    161: {
1.1.1.4   root      162:        struct inode * inode;
1.1       root      163: 
                    164:        if (!(inode = namei(filename)))
                    165:                return -ENOENT;
                    166:        if (!S_ISDIR(inode->i_mode)) {
                    167:                iput(inode);
                    168:                return -ENOTDIR;
                    169:        }
1.1.1.6   root      170:        if (!permission(inode,MAY_EXEC)) {
                    171:                iput(inode);
                    172:                return -EACCES;
                    173:        }
1.1       root      174:        iput(current->pwd);
                    175:        current->pwd = inode;
                    176:        return (0);
                    177: }
                    178: 
                    179: int sys_chroot(const char * filename)
                    180: {
1.1.1.4   root      181:        struct inode * inode;
1.1       root      182: 
                    183:        if (!(inode=namei(filename)))
                    184:                return -ENOENT;
                    185:        if (!S_ISDIR(inode->i_mode)) {
                    186:                iput(inode);
                    187:                return -ENOTDIR;
                    188:        }
1.1.1.6   root      189:        if (!suser()) {
                    190:                iput(inode);
                    191:                return -EPERM;
                    192:        }
1.1       root      193:        iput(current->root);
                    194:        current->root = inode;
                    195:        return (0);
                    196: }
                    197: 
1.1.1.6   root      198: int sys_fchmod(unsigned int fd, mode_t mode)
1.1       root      199: {
1.1.1.4   root      200:        struct inode * inode;
1.1.1.6   root      201:        struct file * file;
1.1       root      202: 
1.1.1.6   root      203:        if (fd >= NR_OPEN || !(file = current->filp[fd]))
                    204:                return -EBADF;
                    205:        if (!(inode = file->f_inode))
                    206:                return -ENOENT;
                    207:        if ((current->euid != inode->i_uid) && !suser())
                    208:                return -EPERM;
                    209:        inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777);
                    210:        inode->i_dirt = 1;
                    211:        return 0;
                    212: }
                    213: 
                    214: int sys_chmod(const char * filename, mode_t mode)
                    215: {
                    216:        struct inode * inode;
                    217: 
                    218:        if (!(inode = namei(filename)))
1.1       root      219:                return -ENOENT;
1.1.1.2   root      220:        if ((current->euid != inode->i_uid) && !suser()) {
                    221:                iput(inode);
1.1.1.6   root      222:                return -EPERM;
1.1.1.2   root      223:        }
1.1       root      224:        inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777);
                    225:        inode->i_dirt = 1;
                    226:        iput(inode);
                    227:        return 0;
                    228: }
                    229: 
1.1.1.6   root      230: int sys_fchown(unsigned int fd, uid_t user, gid_t group)
1.1       root      231: {
1.1.1.4   root      232:        struct inode * inode;
1.1.1.6   root      233:        struct file * file;
1.1       root      234: 
1.1.1.6   root      235:        if (fd >= NR_OPEN || !(file = current->filp[fd]))
                    236:                return -EBADF;
                    237:        if (!(inode = file->f_inode))
1.1       root      238:                return -ENOENT;
1.1.1.6   root      239:        if ((current->euid == inode->i_uid && user == inode->i_uid &&
                    240:             (in_group_p(group) || group == inode->i_gid)) ||
                    241:            suser()) {
                    242:                inode->i_uid = user;
                    243:                inode->i_gid = group;
                    244:                inode->i_dirt=1;
                    245:                return 0;
                    246:        }
                    247:        return -EPERM;
                    248: }
                    249: 
                    250: int sys_chown(const char * filename, uid_t user, gid_t group)
                    251: {
                    252:        struct inode * inode;
                    253: 
                    254:        if (!(inode = lnamei(filename)))
                    255:                return -ENOENT;
                    256:        if ((current->euid == inode->i_uid && user == inode->i_uid &&
                    257:             (in_group_p(group) || group == inode->i_gid)) ||
                    258:            suser()) {
                    259:                inode->i_uid = user;
                    260:                inode->i_gid = group;
                    261:                inode->i_dirt=1;
1.1       root      262:                iput(inode);
1.1.1.6   root      263:                return 0;
1.1       root      264:        }
                    265:        iput(inode);
1.1.1.6   root      266:        return -EPERM;
1.1       root      267: }
                    268: 
                    269: int sys_open(const char * filename,int flag,int mode)
                    270: {
1.1.1.4   root      271:        struct inode * inode;
1.1       root      272:        struct file * f;
                    273:        int i,fd;
                    274: 
                    275:        for(fd=0 ; fd<NR_OPEN ; fd++)
                    276:                if (!current->filp[fd])
                    277:                        break;
                    278:        if (fd>=NR_OPEN)
1.1.1.7 ! root      279:                return -EMFILE;
1.1       root      280:        current->close_on_exec &= ~(1<<fd);
                    281:        f=0+file_table;
                    282:        for (i=0 ; i<NR_FILE ; i++,f++)
                    283:                if (!f->f_count) break;
                    284:        if (i>=NR_FILE)
1.1.1.7 ! root      285:                return -ENFILE;
1.1.1.6   root      286:        (current->filp[fd] = f)->f_count++;
                    287:        if ((i = open_namei(filename,flag,mode,&inode))<0) {
1.1       root      288:                current->filp[fd]=NULL;
                    289:                f->f_count=0;
                    290:                return i;
                    291:        }
1.1.1.4   root      292:        f->f_mode = "\001\002\003\000"[flag & O_ACCMODE];
1.1       root      293:        f->f_flags = flag;
                    294:        f->f_count = 1;
                    295:        f->f_inode = inode;
                    296:        f->f_pos = 0;
1.1.1.6   root      297:        f->f_reada = 0;
                    298:        f->f_op = NULL;
                    299:        if (inode->i_op)
                    300:                f->f_op = inode->i_op->default_file_ops;
                    301:        if (f->f_op && f->f_op->open)
                    302:                if (i = f->f_op->open(inode,f)) {
1.1.1.4   root      303:                        iput(inode);
                    304:                        f->f_count=0;
                    305:                        current->filp[fd]=NULL;
                    306:                        return i;
                    307:                }
1.1       root      308:        return (fd);
                    309: }
                    310: 
                    311: int sys_creat(const char * pathname, int mode)
                    312: {
1.1.1.4   root      313:        return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
1.1       root      314: }
                    315: 
                    316: int sys_close(unsigned int fd)
                    317: {      
                    318:        struct file * filp;
                    319: 
                    320:        if (fd >= NR_OPEN)
                    321:                return -EINVAL;
                    322:        current->close_on_exec &= ~(1<<fd);
                    323:        if (!(filp = current->filp[fd]))
                    324:                return -EINVAL;
                    325:        current->filp[fd] = NULL;
1.1.1.6   root      326:        if (filp->f_count == 0) {
                    327:                printk("Close: file count is 0\n");
                    328:                return 0;
                    329:        }
                    330:        if (filp->f_count > 1) {
                    331:                filp->f_count--;
                    332:                return 0;
                    333:        }
                    334:        if (filp->f_op && filp->f_op->release)
                    335:                filp->f_op->release(filp->f_inode,filp);
1.1       root      336:        iput(filp->f_inode);
1.1.1.6   root      337:        filp->f_count--;
                    338:        return 0;
1.1       root      339: }

unix.superglobalmegacorp.com

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