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