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