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