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

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/tty.h>
                     16: #include <linux/kernel.h>
1.1.1.3 ! root       17: 
1.1       root       18: #include <asm/segment.h>
                     19: 
1.1.1.2   root       20: int sys_ustat(int dev, struct ustat * ubuf)
                     21: {
                     22:        return -ENOSYS;
                     23: }
                     24: 
1.1       root       25: int sys_utime(char * filename, struct utimbuf * times)
                     26: {
                     27:        struct m_inode * inode;
                     28:        long actime,modtime;
                     29: 
                     30:        if (!(inode=namei(filename)))
                     31:                return -ENOENT;
                     32:        if (times) {
                     33:                actime = get_fs_long((unsigned long *) &times->actime);
                     34:                modtime = get_fs_long((unsigned long *) &times->modtime);
                     35:        } else
                     36:                actime = modtime = CURRENT_TIME;
                     37:        inode->i_atime = actime;
                     38:        inode->i_mtime = modtime;
                     39:        inode->i_dirt = 1;
                     40:        iput(inode);
                     41:        return 0;
                     42: }
                     43: 
1.1.1.2   root       44: /*
                     45:  * XXX should we use the real or effective uid?  BSD uses the real uid,
                     46:  * so as to make this call useful to setuid programs.
                     47:  */
1.1       root       48: int sys_access(const char * filename,int mode)
                     49: {
                     50:        struct m_inode * inode;
1.1.1.2   root       51:        int res, i_mode;
1.1       root       52: 
                     53:        mode &= 0007;
                     54:        if (!(inode=namei(filename)))
                     55:                return -EACCES;
1.1.1.2   root       56:        i_mode = res = inode->i_mode & 0777;
1.1       root       57:        iput(inode);
1.1.1.2   root       58:        if (current->uid == inode->i_uid)
1.1       root       59:                res >>= 6;
1.1.1.2   root       60:        else if (current->gid == inode->i_gid)
1.1       root       61:                res >>= 6;
                     62:        if ((res & 0007 & mode) == mode)
                     63:                return 0;
1.1.1.2   root       64:        /*
                     65:         * XXX we are doing this test last because we really should be
                     66:         * swapping the effective with the real user id (temporarily),
                     67:         * and then calling suser() routine.  If we do call the
                     68:         * suser() routine, it needs to be called last. 
                     69:         */
                     70:        if ((!current->uid) &&
                     71:            (!(mode & 1) || (i_mode & 0111)))
                     72:                return 0;
1.1       root       73:        return -EACCES;
                     74: }
                     75: 
                     76: int sys_chdir(const char * filename)
                     77: {
                     78:        struct m_inode * inode;
                     79: 
                     80:        if (!(inode = namei(filename)))
                     81:                return -ENOENT;
                     82:        if (!S_ISDIR(inode->i_mode)) {
                     83:                iput(inode);
                     84:                return -ENOTDIR;
                     85:        }
                     86:        iput(current->pwd);
                     87:        current->pwd = inode;
                     88:        return (0);
                     89: }
                     90: 
                     91: int sys_chroot(const char * filename)
                     92: {
                     93:        struct m_inode * inode;
                     94: 
                     95:        if (!(inode=namei(filename)))
                     96:                return -ENOENT;
                     97:        if (!S_ISDIR(inode->i_mode)) {
                     98:                iput(inode);
                     99:                return -ENOTDIR;
                    100:        }
                    101:        iput(current->root);
                    102:        current->root = inode;
                    103:        return (0);
                    104: }
                    105: 
                    106: int sys_chmod(const char * filename,int mode)
                    107: {
                    108:        struct m_inode * inode;
                    109: 
                    110:        if (!(inode=namei(filename)))
                    111:                return -ENOENT;
1.1.1.2   root      112:        if ((current->euid != inode->i_uid) && !suser()) {
                    113:                iput(inode);
                    114:                return -EACCES;
                    115:        }
1.1       root      116:        inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777);
                    117:        inode->i_dirt = 1;
                    118:        iput(inode);
                    119:        return 0;
                    120: }
                    121: 
                    122: int sys_chown(const char * filename,int uid,int gid)
                    123: {
                    124:        struct m_inode * inode;
                    125: 
                    126:        if (!(inode=namei(filename)))
                    127:                return -ENOENT;
1.1.1.2   root      128:        if (!suser()) {
1.1       root      129:                iput(inode);
                    130:                return -EACCES;
                    131:        }
                    132:        inode->i_uid=uid;
                    133:        inode->i_gid=gid;
                    134:        inode->i_dirt=1;
                    135:        iput(inode);
                    136:        return 0;
                    137: }
                    138: 
1.1.1.3 ! root      139: static int check_char_dev(struct m_inode * inode, int dev, int flag)
        !           140: {
        !           141:        struct tty_struct *tty;
        !           142:        int min;
        !           143: 
        !           144:        if (MAJOR(dev) == 4 || MAJOR(dev) == 5) {
        !           145:                if (MAJOR(dev) == 5)
        !           146:                        min = current->tty;
        !           147:                else
        !           148:                        min = MINOR(dev);
        !           149:                if (min < 0)
        !           150:                        return -1;
        !           151:                if ((IS_A_PTY_MASTER(min)) && (inode->i_count>1))
        !           152:                        return -1;
        !           153:                tty = TTY_TABLE(min);
        !           154:                if (!(flag & O_NOCTTY) &&
        !           155:                    current->leader &&
        !           156:                    current->tty<0 &&
        !           157:                    tty->session==0) {
        !           158:                        current->tty = min;
        !           159:                        tty->session= current->session;
        !           160:                        tty->pgrp = current->pgrp;
        !           161:                }
        !           162:                if (flag & O_NONBLOCK) {
        !           163:                        TTY_TABLE(min)->termios.c_cc[VMIN] =0;
        !           164:                        TTY_TABLE(min)->termios.c_cc[VTIME] =0;
        !           165:                        TTY_TABLE(min)->termios.c_lflag &= ~ICANON;
        !           166:                }
        !           167:        }
        !           168:        return 0;
        !           169: }
        !           170: 
1.1       root      171: int sys_open(const char * filename,int flag,int mode)
                    172: {
                    173:        struct m_inode * inode;
                    174:        struct file * f;
                    175:        int i,fd;
                    176: 
                    177:        mode &= 0777 & ~current->umask;
                    178:        for(fd=0 ; fd<NR_OPEN ; fd++)
                    179:                if (!current->filp[fd])
                    180:                        break;
                    181:        if (fd>=NR_OPEN)
                    182:                return -EINVAL;
                    183:        current->close_on_exec &= ~(1<<fd);
                    184:        f=0+file_table;
                    185:        for (i=0 ; i<NR_FILE ; i++,f++)
                    186:                if (!f->f_count) break;
                    187:        if (i>=NR_FILE)
                    188:                return -EINVAL;
                    189:        (current->filp[fd]=f)->f_count++;
                    190:        if ((i=open_namei(filename,flag,mode,&inode))<0) {
                    191:                current->filp[fd]=NULL;
                    192:                f->f_count=0;
                    193:                return i;
                    194:        }
                    195: /* ttys are somewhat special (ttyxx major==4, tty major==5) */
                    196:        if (S_ISCHR(inode->i_mode))
1.1.1.3 ! root      197:                if (check_char_dev(inode,inode->i_zone[0],flag)) {
        !           198:                        iput(inode);
        !           199:                        current->filp[fd]=NULL;
        !           200:                        f->f_count=0;
        !           201:                        return -EAGAIN;
        !           202:                }
1.1.1.2   root      203: /* Likewise with block-devices: check for floppy_change */
                    204:        if (S_ISBLK(inode->i_mode))
                    205:                check_disk_change(inode->i_zone[0]);
1.1       root      206:        f->f_mode = inode->i_mode;
                    207:        f->f_flags = flag;
                    208:        f->f_count = 1;
                    209:        f->f_inode = inode;
                    210:        f->f_pos = 0;
                    211:        return (fd);
                    212: }
                    213: 
                    214: int sys_creat(const char * pathname, int mode)
                    215: {
                    216:        return sys_open(pathname, O_CREAT | O_TRUNC, mode);
                    217: }
                    218: 
                    219: int sys_close(unsigned int fd)
                    220: {      
                    221:        struct file * filp;
                    222: 
                    223:        if (fd >= NR_OPEN)
                    224:                return -EINVAL;
                    225:        current->close_on_exec &= ~(1<<fd);
                    226:        if (!(filp = current->filp[fd]))
                    227:                return -EINVAL;
                    228:        current->filp[fd] = NULL;
                    229:        if (filp->f_count == 0)
                    230:                panic("Close: file count is 0");
                    231:        if (--filp->f_count)
                    232:                return (0);
                    233:        iput(filp->f_inode);
                    234:        return (0);
                    235: }

unix.superglobalmegacorp.com

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