|
|
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 *) ×->actime);
34: modtime = get_fs_long((unsigned long *) ×->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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.