This source file includes following definitions.
- osf_filldir
- osf_getdirentries
- sys_madvise
- sys_getxuid
- sys_getxgid
- sys_getxpid
- osf_mmap
- osf_statfs
- osf_fstatfs
- getdev
- putdev
- osf_ufs_mount
- osf_cdfs_mount
- osf_procfs_mount
- osf_mount
- osf_umount
- osf_usleep_thread
- osf_utsname
- osf_swapon
- sys_getpagesize
- sys_getdtablesize
- sys_pipe
- osf_getdomainname
1
2
3
4
5
6
7
8
9
10
11
12
13 #include <linux/errno.h>
14 #include <linux/sched.h>
15 #include <linux/kernel.h>
16 #include <linux/mm.h>
17 #include <linux/stddef.h>
18 #include <linux/unistd.h>
19 #include <linux/ptrace.h>
20 #include <linux/malloc.h>
21 #include <linux/ldt.h>
22 #include <linux/user.h>
23 #include <linux/a.out.h>
24 #include <linux/utsname.h>
25 #include <linux/time.h>
26 #include <linux/major.h>
27 #include <linux/stat.h>
28 #include <linux/mman.h>
29
30 #include <asm/segment.h>
31 #include <asm/system.h>
32 #include <asm/io.h>
33
34 extern int do_mount(dev_t, const char *, char *, int, void *);
35 extern int do_pipe(int *);
36
37 extern struct file_operations * get_blkfops(unsigned int);
38 extern struct file_operations * get_chrfops(unsigned int);
39
40 extern dev_t get_unnamed_dev(void);
41 extern void put_unnamed_dev(dev_t);
42
43 extern asmlinkage int sys_umount(char *);
44 extern asmlinkage int sys_swapon(const char *specialfile);
45
46
47
48
49
50
51
52
53 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
54 #define ROUND_UP(x) (((x)+7) & ~7)
55
56 struct osf_dirent {
57 unsigned int d_ino;
58 unsigned short d_reclen;
59 unsigned short d_namlen;
60 char d_name[1];
61 };
62
63 struct osf_dirent_callback {
64 struct osf_dirent * dirent;
65 long *basep;
66 int count;
67 int error;
68 };
69
70 static int osf_filldir(void * __buf, char * name, int namlen, off_t offset, ino_t ino)
71 {
72 struct osf_dirent * dirent;
73 struct osf_dirent_callback * buf = (struct osf_dirent_callback *) __buf;
74 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
75
76 buf->error = -EINVAL;
77 if (reclen > buf->count)
78 return -EINVAL;
79 if (buf->basep) {
80 put_user(offset, buf->basep);
81 buf->basep = NULL;
82 }
83 dirent = buf->dirent;
84 put_user(ino, &dirent->d_ino);
85 put_user(namlen, &dirent->d_namlen);
86 put_user(reclen, &dirent->d_reclen);
87 memcpy_tofs(dirent->d_name, name, namlen);
88 put_fs_byte(0, dirent->d_name + namlen);
89 ((char *) dirent) += reclen;
90 buf->dirent = dirent;
91 buf->count -= reclen;
92 return 0;
93 }
94
95 asmlinkage int osf_getdirentries(unsigned int fd, struct osf_dirent * dirent,
96 unsigned int count, long *basep)
97 {
98 int error;
99 struct file * file;
100 struct osf_dirent_callback buf;
101
102 if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
103 return -EBADF;
104 if (!file->f_op || !file->f_op->readdir)
105 return -ENOTDIR;
106 error = verify_area(VERIFY_WRITE, dirent, count);
107 if (error)
108 return error;
109 if (basep) {
110 error = verify_area(VERIFY_WRITE, basep, sizeof(long));
111 if (error)
112 return error;
113 }
114 buf.dirent = dirent;
115 buf.basep = basep;
116 buf.count = count;
117 buf.error = 0;
118 error = file->f_op->readdir(file->f_inode, file, dirent, osf_filldir);
119 if (error < 0)
120 return error;
121 if (count == buf.count)
122 return buf.error;
123 return count - buf.count;
124 }
125
126
127
128
129 asmlinkage unsigned long sys_madvise(void)
130 {
131 return 0;
132 }
133
134 asmlinkage unsigned long sys_getxuid(int a0, int a1, int a2, int a3, int a4, int a5,
135 struct pt_regs regs)
136 {
137 (®s)->r20 = current->euid;
138 return current->uid;
139 }
140
141 asmlinkage unsigned long sys_getxgid(int a0, int a1, int a2, int a3, int a4, int a5,
142 struct pt_regs regs)
143 {
144 (®s)->r20 = current->egid;
145 return current->gid;
146 }
147
148 asmlinkage unsigned long sys_getxpid(int a0, int a1, int a2, int a3, int a4, int a5,
149 struct pt_regs regs)
150 {
151 (®s)->r20 = current->p_opptr->pid;
152 return current->pid;
153 }
154
155 #define OSF_MAP_ANONYMOUS 0x0010
156 #define OSF_MAP_FIXED 0x0100
157 #define OSF_MAP_HASSEMAPHORE 0x0200
158 #define OSF_MAP_INHERIT 0x0400
159 #define OSF_MAP_UNALIGNED 0x0800
160
161 asmlinkage unsigned long osf_mmap(unsigned long addr, unsigned long len,
162 unsigned long prot, unsigned long osf_flags, unsigned long fd,
163 unsigned long off)
164 {
165 struct file * file = NULL;
166 unsigned long flags = osf_flags & 0x0f;
167
168 if (osf_flags & (OSF_MAP_HASSEMAPHORE | OSF_MAP_INHERIT | OSF_MAP_UNALIGNED))
169 printk("%s: unimplemented OSF mmap flags %04lx\n", current->comm, osf_flags);
170 if (osf_flags & OSF_MAP_FIXED)
171 flags |= MAP_FIXED;
172 if (osf_flags & OSF_MAP_ANONYMOUS)
173 flags |= MAP_ANONYMOUS;
174 else {
175 if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
176 return -EBADF;
177 }
178 return do_mmap(file, addr, len, prot, flags, off);
179 }
180
181 asmlinkage int osf_statfs(char * path, struct statfs * buffer, unsigned long bufsiz)
182 {
183 struct inode * inode;
184 int retval;
185
186 if (bufsiz > sizeof(struct statfs))
187 bufsiz = sizeof(struct statfs);
188 retval = verify_area(VERIFY_WRITE, buffer, bufsiz);
189 if (retval)
190 return retval;
191 retval = namei(path, &inode);
192 if (retval)
193 return retval;
194 if (!inode->i_sb->s_op->statfs) {
195 iput(inode);
196 return -ENOSYS;
197 }
198 inode->i_sb->s_op->statfs(inode->i_sb, buffer, bufsiz);
199 iput(inode);
200 return 0;
201 }
202
203 asmlinkage int osf_fstatfs(unsigned long fd, struct statfs * buffer, unsigned long bufsiz)
204 {
205 struct file * file;
206 struct inode * inode;
207 int retval;
208
209 retval = verify_area(VERIFY_WRITE, buffer, bufsiz);
210 if (retval)
211 return retval;
212 if (bufsiz > sizeof(struct statfs))
213 bufsiz = sizeof(struct statfs);
214 if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
215 return -EBADF;
216 if (!(inode = file->f_inode))
217 return -ENOENT;
218 if (!inode->i_sb->s_op->statfs)
219 return -ENOSYS;
220 inode->i_sb->s_op->statfs(inode->i_sb, buffer, bufsiz);
221 return 0;
222 }
223
224
225
226
227
228
229 struct ufs_args {
230 char * devname;
231 int flags;
232 uid_t exroot;
233 };
234
235 struct cdfs_args {
236 char * devname;
237 int flags;
238 uid_t exroot;
239
240
241
242
243 };
244
245 struct procfs_args {
246 char * devname;
247 int flags;
248 uid_t exroot;
249 };
250
251 static int getdev(const char * name, int rdonly, struct inode ** ino)
252 {
253 dev_t dev;
254 struct inode * inode;
255 struct file_operations * fops;
256 int retval;
257
258 retval = namei(name, &inode);
259 if (retval)
260 return retval;
261 if (!S_ISBLK(inode->i_mode)) {
262 iput(inode);
263 return -ENOTBLK;
264 }
265 if (IS_NODEV(inode)) {
266 iput(inode);
267 return -EACCES;
268 }
269 dev = inode->i_rdev;
270 if (MAJOR(dev) >= MAX_BLKDEV) {
271 iput(inode);
272 return -ENXIO;
273 }
274 fops = get_blkfops(MAJOR(dev));
275 if (!fops) {
276 iput(inode);
277 return -ENODEV;
278 }
279 if (fops->open) {
280 struct file dummy;
281 memset(&dummy, 0, sizeof(dummy));
282 dummy.f_inode = inode;
283 dummy.f_mode = rdonly ? 1 : 3;
284 retval = fops->open(inode, &dummy);
285 if (retval) {
286 iput(inode);
287 return retval;
288 }
289 }
290 *ino = inode;
291 return 0;
292 }
293
294 static void putdev(struct inode * inode)
295 {
296 struct file_operations * fops;
297
298 fops = get_blkfops(MAJOR(inode->i_rdev));
299 if (fops->release)
300 fops->release(inode, NULL);
301 }
302
303
304
305
306
307
308 static int osf_ufs_mount(char * dirname, struct ufs_args * args, int flags)
309 {
310 int retval;
311 struct inode * inode;
312 struct cdfs_args tmp;
313
314 retval = verify_area(VERIFY_READ, args, sizeof(*args));
315 if (retval)
316 return retval;
317 memcpy_fromfs(&tmp, args, sizeof(tmp));
318 retval = getdev(tmp.devname, 0, &inode);
319 if (retval)
320 return retval;
321 retval = do_mount(inode->i_rdev, dirname, "ext2", flags, NULL);
322 if (retval)
323 putdev(inode);
324 iput(inode);
325 return retval;
326 }
327
328 static int osf_cdfs_mount(char * dirname, struct cdfs_args * args, int flags)
329 {
330 int retval;
331 struct inode * inode;
332 struct cdfs_args tmp;
333
334 retval = verify_area(VERIFY_READ, args, sizeof(*args));
335 if (retval)
336 return retval;
337 memcpy_fromfs(&tmp, args, sizeof(tmp));
338 retval = getdev(tmp.devname, 1, &inode);
339 if (retval)
340 return retval;
341 retval = do_mount(inode->i_rdev, dirname, "iso9660", flags, NULL);
342 if (retval)
343 putdev(inode);
344 iput(inode);
345 return retval;
346 }
347
348 static int osf_procfs_mount(char * dirname, struct procfs_args * args, int flags)
349 {
350 dev_t dev;
351 int retval;
352 struct procfs_args tmp;
353
354 retval = verify_area(VERIFY_READ, args, sizeof(*args));
355 if (retval)
356 return retval;
357 memcpy_fromfs(&tmp, args, sizeof(tmp));
358 dev = get_unnamed_dev();
359 if (!dev)
360 return -ENODEV;
361 retval = do_mount(dev, dirname, "proc", flags, NULL);
362 if (retval)
363 put_unnamed_dev(dev);
364 return retval;
365 }
366
367 asmlinkage int osf_mount(unsigned long typenr, char * path, int flag, void * data)
368 {
369 int retval;
370
371 retval = -EINVAL;
372 switch (typenr) {
373 case 1:
374 retval = osf_ufs_mount(path, (struct ufs_args *) data, flag);
375 break;
376 case 6:
377 retval = osf_cdfs_mount(path, (struct cdfs_args *) data, flag);
378 break;
379 case 9:
380 retval = osf_procfs_mount(path, (struct procfs_args *) data, flag);
381 break;
382 default:
383 printk("osf_mount(%ld, %x)\n", typenr, flag);
384 }
385 return retval;
386 }
387
388 asmlinkage int osf_umount(char * path, int flag)
389 {
390 return sys_umount(path);
391 }
392
393
394
395
396
397
398 asmlinkage int osf_usleep_thread(struct timeval * sleep, struct timeval * remain)
399 {
400 struct timeval tmp;
401 unsigned long ticks;
402 int retval;
403
404 retval = verify_area(VERIFY_READ, sleep, sizeof(*sleep));
405 if (retval)
406 return retval;
407 if (remain && (retval = verify_area(VERIFY_WRITE, remain, sizeof(*remain))))
408 return retval;
409 memcpy_fromfs(&tmp, sleep, sizeof(*sleep));
410 ticks = tmp.tv_usec;
411 ticks = (ticks + (1000000 / HZ) - 1) / (1000000 / HZ);
412 ticks += tmp.tv_sec * HZ;
413 current->timeout = ticks + jiffies;
414 current->state = TASK_INTERRUPTIBLE;
415 schedule();
416 if (!remain)
417 return 0;
418 ticks = jiffies;
419 if (ticks < current->timeout)
420 ticks = current->timeout - ticks;
421 else
422 ticks = 0;
423 current->timeout = 0;
424 tmp.tv_sec = ticks / HZ;
425 tmp.tv_usec = ticks % HZ;
426 memcpy_tofs(remain, &tmp, sizeof(*remain));
427 return 0;
428 }
429
430 asmlinkage int osf_utsname(char * name)
431 {
432 int error = verify_area(VERIFY_WRITE, name, 5*32);
433 if (error)
434 return error;
435 memcpy_tofs(name + 0, system_utsname.sysname, 32);
436 memcpy_tofs(name + 32, system_utsname.nodename, 32);
437 memcpy_tofs(name + 64, system_utsname.release, 32);
438 memcpy_tofs(name + 96, system_utsname.version, 32);
439 memcpy_tofs(name + 128, system_utsname.machine, 32);
440 return 0;
441 }
442
443 asmlinkage int osf_swapon(const char * path, int flags, int lowat, int hiwat)
444 {
445
446 return sys_swapon(path);
447 }
448
449 asmlinkage unsigned long sys_getpagesize(void)
450 {
451 return PAGE_SIZE;
452 }
453
454 asmlinkage unsigned long sys_getdtablesize(void)
455 {
456 return NR_OPEN;
457 }
458
459 asmlinkage int sys_pipe(int a0, int a1, int a2, int a3, int a4, int a5,
460 struct pt_regs regs)
461 {
462 int fd[2];
463 int error;
464
465 error = do_pipe(fd);
466 if (error)
467 return error;
468 (®s)->r20 = fd[1];
469 return fd[0];
470 }
471
472
473
474
475 asmlinkage int osf_getdomainname(char *name, int namelen)
476 {
477 unsigned len;
478 int i, error;
479
480 error = verify_area(VERIFY_WRITE, name, namelen);
481 if (error)
482 return error;
483
484 len = namelen;
485 if (namelen > 32)
486 len = 32;
487
488 for (i = 0; i < len; ++i) {
489 put_user(system_utsname.domainname[i], name + i);
490 if (system_utsname.domainname[i] == '\0')
491 break;
492 }
493 return 0;
494 }