|
|
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/kernel.h>
1.1.1.3 root 16:
1.1 root 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: {
1.1.1.4 ! root 26: struct inode * inode;
1.1 root 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: {
1.1.1.4 ! root 49: struct 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: {
1.1.1.4 ! root 77: struct inode * inode;
1.1 root 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: {
1.1.1.4 ! root 92: struct inode * inode;
1.1 root 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: {
1.1.1.4 ! root 107: struct inode * inode;
1.1 root 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: {
1.1.1.4 ! root 123: struct inode * inode;
1.1 root 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: {
1.1.1.4 ! root 140: struct inode * inode;
1.1 root 141: struct file * f;
142: int i,fd;
143:
144: for(fd=0 ; fd<NR_OPEN ; fd++)
145: if (!current->filp[fd])
146: break;
147: if (fd>=NR_OPEN)
148: return -EINVAL;
149: current->close_on_exec &= ~(1<<fd);
150: f=0+file_table;
151: for (i=0 ; i<NR_FILE ; i++,f++)
152: if (!f->f_count) break;
153: if (i>=NR_FILE)
154: return -EINVAL;
155: (current->filp[fd]=f)->f_count++;
156: if ((i=open_namei(filename,flag,mode,&inode))<0) {
157: current->filp[fd]=NULL;
158: f->f_count=0;
159: return i;
160: }
1.1.1.4 ! root 161: f->f_op = NULL;
! 162: f->f_mode = "\001\002\003\000"[flag & O_ACCMODE];
1.1 root 163: f->f_flags = flag;
164: f->f_count = 1;
165: f->f_inode = inode;
166: f->f_pos = 0;
1.1.1.4 ! root 167: if (inode->i_op && inode->i_op->open)
! 168: if (i = inode->i_op->open(inode,f)) {
! 169: iput(inode);
! 170: f->f_count=0;
! 171: current->filp[fd]=NULL;
! 172: return i;
! 173: }
1.1 root 174: return (fd);
175: }
176:
177: int sys_creat(const char * pathname, int mode)
178: {
1.1.1.4 ! root 179: return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
1.1 root 180: }
181:
182: int sys_close(unsigned int fd)
183: {
184: struct file * filp;
185:
186: if (fd >= NR_OPEN)
187: return -EINVAL;
188: current->close_on_exec &= ~(1<<fd);
189: if (!(filp = current->filp[fd]))
190: return -EINVAL;
191: current->filp[fd] = NULL;
192: if (filp->f_count == 0)
193: panic("Close: file count is 0");
194: if (--filp->f_count)
195: return (0);
196: iput(filp->f_inode);
197: return (0);
198: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.