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
- osf_shmat
- osf_proplist_syscall
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 #include <linux/shm.h>
30
31 #include <asm/segment.h>
32 #include <asm/system.h>
33 #include <asm/io.h>
34
35 extern int do_mount(dev_t, const char *, char *, int, void *);
36 extern int do_pipe(int *);
37
38 extern struct file_operations * get_blkfops(unsigned int);
39 extern struct file_operations * get_chrfops(unsigned int);
40
41 extern dev_t get_unnamed_dev(void);
42 extern void put_unnamed_dev(dev_t);
43
44 extern asmlinkage int sys_umount(char *);
45 extern asmlinkage int sys_swapon(const char *specialfile, int swap_flags);
46
47
48
49
50
51
52
53
54 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
55 #define ROUND_UP(x) (((x)+3) & ~3)
56
57 struct osf_dirent {
58 unsigned int d_ino;
59 unsigned short d_reclen;
60 unsigned short d_namlen;
61 char d_name[1];
62 };
63
64 struct osf_dirent_callback {
65 struct osf_dirent * dirent;
66 long *basep;
67 int count;
68 int error;
69 };
70
71 static int osf_filldir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino)
72 {
73 struct osf_dirent * dirent;
74 struct osf_dirent_callback * buf = (struct osf_dirent_callback *) __buf;
75 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
76
77 buf->error = -EINVAL;
78 if (reclen > buf->count)
79 return -EINVAL;
80 if (buf->basep) {
81 put_user(offset, buf->basep);
82 buf->basep = NULL;
83 }
84 dirent = buf->dirent;
85 put_user(ino, &dirent->d_ino);
86 put_user(namlen, &dirent->d_namlen);
87 put_user(reclen, &dirent->d_reclen);
88 memcpy_tofs(dirent->d_name, name, namlen);
89 put_fs_byte(0, dirent->d_name + namlen);
90 ((char *) dirent) += reclen;
91 buf->dirent = dirent;
92 buf->count -= reclen;
93 return 0;
94 }
95
96 asmlinkage int osf_getdirentries(unsigned int fd, struct osf_dirent * dirent,
97 unsigned int count, long *basep)
98 {
99 int error;
100 struct file * file;
101 struct osf_dirent_callback buf;
102
103 if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
104 return -EBADF;
105 if (!file->f_op || !file->f_op->readdir)
106 return -ENOTDIR;
107 error = verify_area(VERIFY_WRITE, dirent, count);
108 if (error)
109 return error;
110 if (basep) {
111 error = verify_area(VERIFY_WRITE, basep, sizeof(long));
112 if (error)
113 return error;
114 }
115 buf.dirent = dirent;
116 buf.basep = basep;
117 buf.count = count;
118 buf.error = 0;
119 error = file->f_op->readdir(file->f_inode, file, &buf, osf_filldir);
120 if (error < 0)
121 return error;
122 if (count == buf.count)
123 return buf.error;
124 return count - buf.count;
125 }
126
127
128
129
130 asmlinkage unsigned long sys_madvise(void)
131 {
132 return 0;
133 }
134
135 asmlinkage unsigned long sys_getxuid(int a0, int a1, int a2, int a3, int a4, int a5,
136 struct pt_regs regs)
137 {
138 (®s)->r20 = current->euid;
139 return current->uid;
140 }
141
142 asmlinkage unsigned long sys_getxgid(int a0, int a1, int a2, int a3, int a4, int a5,
143 struct pt_regs regs)
144 {
145 (®s)->r20 = current->egid;
146 return current->gid;
147 }
148
149 asmlinkage unsigned long sys_getxpid(int a0, int a1, int a2, int a3, int a4, int a5,
150 struct pt_regs regs)
151 {
152 (®s)->r20 = current->p_opptr->pid;
153 return current->pid;
154 }
155
156 #define OSF_MAP_ANONYMOUS 0x0010
157 #define OSF_MAP_FIXED 0x0100
158 #define OSF_MAP_HASSEMAPHORE 0x0200
159 #define OSF_MAP_INHERIT 0x0400
160 #define OSF_MAP_UNALIGNED 0x0800
161
162 asmlinkage unsigned long osf_mmap(unsigned long addr, unsigned long len,
163 unsigned long prot, unsigned long osf_flags, unsigned long fd,
164 unsigned long off)
165 {
166 struct file * file = NULL;
167 unsigned long flags = osf_flags & 0x0f;
168
169 if (osf_flags & (OSF_MAP_HASSEMAPHORE | OSF_MAP_INHERIT | OSF_MAP_UNALIGNED))
170 printk("%s: unimplemented OSF mmap flags %04lx\n", current->comm, osf_flags);
171 if (osf_flags & OSF_MAP_FIXED)
172 flags |= MAP_FIXED;
173 if (osf_flags & OSF_MAP_ANONYMOUS)
174 flags |= MAP_ANONYMOUS;
175 else {
176 if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
177 return -EBADF;
178 }
179 return do_mmap(file, addr, len, prot, flags, off);
180 }
181
182 asmlinkage int osf_statfs(char * path, struct statfs * buffer, unsigned long bufsiz)
183 {
184 struct inode * inode;
185 int retval;
186
187 if (bufsiz > sizeof(struct statfs))
188 bufsiz = sizeof(struct statfs);
189 retval = verify_area(VERIFY_WRITE, buffer, bufsiz);
190 if (retval)
191 return retval;
192 retval = namei(path, &inode);
193 if (retval)
194 return retval;
195 if (!inode->i_sb->s_op->statfs) {
196 iput(inode);
197 return -ENOSYS;
198 }
199 inode->i_sb->s_op->statfs(inode->i_sb, buffer, bufsiz);
200 iput(inode);
201 return 0;
202 }
203
204 asmlinkage int osf_fstatfs(unsigned long fd, struct statfs * buffer, unsigned long bufsiz)
205 {
206 struct file * file;
207 struct inode * inode;
208 int retval;
209
210 retval = verify_area(VERIFY_WRITE, buffer, bufsiz);
211 if (retval)
212 return retval;
213 if (bufsiz > sizeof(struct statfs))
214 bufsiz = sizeof(struct statfs);
215 if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
216 return -EBADF;
217 if (!(inode = file->f_inode))
218 return -ENOENT;
219 if (!inode->i_sb->s_op->statfs)
220 return -ENOSYS;
221 inode->i_sb->s_op->statfs(inode->i_sb, buffer, bufsiz);
222 return 0;
223 }
224
225
226
227
228
229
230 struct ufs_args {
231 char * devname;
232 int flags;
233 uid_t exroot;
234 };
235
236 struct cdfs_args {
237 char * devname;
238 int flags;
239 uid_t exroot;
240
241
242
243
244 };
245
246 struct procfs_args {
247 char * devname;
248 int flags;
249 uid_t exroot;
250 };
251
252 static int getdev(const char * name, int rdonly, struct inode ** ino)
253 {
254 dev_t dev;
255 struct inode * inode;
256 struct file_operations * fops;
257 int retval;
258
259 retval = namei(name, &inode);
260 if (retval)
261 return retval;
262 if (!S_ISBLK(inode->i_mode)) {
263 iput(inode);
264 return -ENOTBLK;
265 }
266 if (IS_NODEV(inode)) {
267 iput(inode);
268 return -EACCES;
269 }
270 dev = inode->i_rdev;
271 if (MAJOR(dev) >= MAX_BLKDEV) {
272 iput(inode);
273 return -ENXIO;
274 }
275 fops = get_blkfops(MAJOR(dev));
276 if (!fops) {
277 iput(inode);
278 return -ENODEV;
279 }
280 if (fops->open) {
281 struct file dummy;
282 memset(&dummy, 0, sizeof(dummy));
283 dummy.f_inode = inode;
284 dummy.f_mode = rdonly ? 1 : 3;
285 retval = fops->open(inode, &dummy);
286 if (retval) {
287 iput(inode);
288 return retval;
289 }
290 }
291 *ino = inode;
292 return 0;
293 }
294
295 static void putdev(struct inode * inode)
296 {
297 struct file_operations * fops;
298
299 fops = get_blkfops(MAJOR(inode->i_rdev));
300 if (fops->release)
301 fops->release(inode, NULL);
302 }
303
304
305
306
307
308
309 static int osf_ufs_mount(char * dirname, struct ufs_args * args, int flags)
310 {
311 int retval;
312 struct inode * inode;
313 struct cdfs_args tmp;
314
315 retval = verify_area(VERIFY_READ, args, sizeof(*args));
316 if (retval)
317 return retval;
318 memcpy_fromfs(&tmp, args, sizeof(tmp));
319 retval = getdev(tmp.devname, 0, &inode);
320 if (retval)
321 return retval;
322 retval = do_mount(inode->i_rdev, dirname, "ext2", flags, NULL);
323 if (retval)
324 putdev(inode);
325 iput(inode);
326 return retval;
327 }
328
329 static int osf_cdfs_mount(char * dirname, struct cdfs_args * args, int flags)
330 {
331 int retval;
332 struct inode * inode;
333 struct cdfs_args tmp;
334
335 retval = verify_area(VERIFY_READ, args, sizeof(*args));
336 if (retval)
337 return retval;
338 memcpy_fromfs(&tmp, args, sizeof(tmp));
339 retval = getdev(tmp.devname, 1, &inode);
340 if (retval)
341 return retval;
342 retval = do_mount(inode->i_rdev, dirname, "iso9660", flags, NULL);
343 if (retval)
344 putdev(inode);
345 iput(inode);
346 return retval;
347 }
348
349 static int osf_procfs_mount(char * dirname, struct procfs_args * args, int flags)
350 {
351 dev_t dev;
352 int retval;
353 struct procfs_args tmp;
354
355 retval = verify_area(VERIFY_READ, args, sizeof(*args));
356 if (retval)
357 return retval;
358 memcpy_fromfs(&tmp, args, sizeof(tmp));
359 dev = get_unnamed_dev();
360 if (!dev)
361 return -ENODEV;
362 retval = do_mount(dev, dirname, "proc", flags, NULL);
363 if (retval)
364 put_unnamed_dev(dev);
365 return retval;
366 }
367
368 asmlinkage int osf_mount(unsigned long typenr, char * path, int flag, void * data)
369 {
370 int retval;
371
372 retval = -EINVAL;
373 switch (typenr) {
374 case 1:
375 retval = osf_ufs_mount(path, (struct ufs_args *) data, flag);
376 break;
377 case 6:
378 retval = osf_cdfs_mount(path, (struct cdfs_args *) data, flag);
379 break;
380 case 9:
381 retval = osf_procfs_mount(path, (struct procfs_args *) data, flag);
382 break;
383 default:
384 printk("osf_mount(%ld, %x)\n", typenr, flag);
385 }
386 return retval;
387 }
388
389 asmlinkage int osf_umount(char * path, int flag)
390 {
391 return sys_umount(path);
392 }
393
394
395
396
397
398
399 asmlinkage int osf_usleep_thread(struct timeval * sleep, struct timeval * remain)
400 {
401 struct timeval tmp;
402 unsigned long ticks;
403 int retval;
404
405 retval = verify_area(VERIFY_READ, sleep, sizeof(*sleep));
406 if (retval)
407 return retval;
408 if (remain && (retval = verify_area(VERIFY_WRITE, remain, sizeof(*remain))))
409 return retval;
410 memcpy_fromfs(&tmp, sleep, sizeof(*sleep));
411 ticks = tmp.tv_usec;
412 ticks = (ticks + (1000000 / HZ) - 1) / (1000000 / HZ);
413 ticks += tmp.tv_sec * HZ;
414 current->timeout = ticks + jiffies;
415 current->state = TASK_INTERRUPTIBLE;
416 schedule();
417 if (!remain)
418 return 0;
419 ticks = jiffies;
420 if (ticks < current->timeout)
421 ticks = current->timeout - ticks;
422 else
423 ticks = 0;
424 current->timeout = 0;
425 tmp.tv_sec = ticks / HZ;
426 tmp.tv_usec = ticks % HZ;
427 memcpy_tofs(remain, &tmp, sizeof(*remain));
428 return 0;
429 }
430
431 asmlinkage int osf_utsname(char * name)
432 {
433 int error = verify_area(VERIFY_WRITE, name, 5*32);
434 if (error)
435 return error;
436 memcpy_tofs(name + 0, system_utsname.sysname, 32);
437 memcpy_tofs(name + 32, system_utsname.nodename, 32);
438 memcpy_tofs(name + 64, system_utsname.release, 32);
439 memcpy_tofs(name + 96, system_utsname.version, 32);
440 memcpy_tofs(name + 128, system_utsname.machine, 32);
441 return 0;
442 }
443
444 asmlinkage int osf_swapon(const char * path, int flags, int lowat, int hiwat)
445 {
446
447 return sys_swapon(path, flags);
448 }
449
450 asmlinkage unsigned long sys_getpagesize(void)
451 {
452 return PAGE_SIZE;
453 }
454
455 asmlinkage unsigned long sys_getdtablesize(void)
456 {
457 return NR_OPEN;
458 }
459
460 asmlinkage int sys_pipe(int a0, int a1, int a2, int a3, int a4, int a5,
461 struct pt_regs regs)
462 {
463 int fd[2];
464 int error;
465
466 error = do_pipe(fd);
467 if (error)
468 return error;
469 (®s)->r20 = fd[1];
470 return fd[0];
471 }
472
473
474
475
476 asmlinkage int osf_getdomainname(char *name, int namelen)
477 {
478 unsigned len;
479 int i, error;
480
481 error = verify_area(VERIFY_WRITE, name, namelen);
482 if (error)
483 return error;
484
485 len = namelen;
486 if (namelen > 32)
487 len = 32;
488
489 for (i = 0; i < len; ++i) {
490 put_user(system_utsname.domainname[i], name + i);
491 if (system_utsname.domainname[i] == '\0')
492 break;
493 }
494 return 0;
495 }
496
497
498 asmlinkage long osf_shmat(int shmid, void *shmaddr, int shmflg)
499 {
500 unsigned long raddr;
501 int err;
502
503 err = sys_shmat(shmid, shmaddr, shmflg, &raddr);
504 if (err)
505 return err;
506
507
508
509
510 return raddr;
511 }
512
513
514
515
516
517
518
519
520
521
522
523
524 #define PLE_PROPAGATE_ON_COPY 0x1
525
526 #define PLE_FLAG_MASK 0x1
527 #define PLE_FLAG_ALL -1
528
529 struct proplistname_args {
530 unsigned int pl_mask;
531 unsigned int pl_numnames;
532 char **pl_names;
533 };
534
535 union pl_args {
536 struct setargs {
537 char *path;
538 long follow;
539 long nbytes;
540 char *buf;
541 } set;
542 struct fsetargs {
543 long fd;
544 long nbytes;
545 char *buf;
546 } fset;
547 struct getargs {
548 char *path;
549 long follow;
550 struct proplistname_args *name_args;
551 long nbytes;
552 char *buf;
553 int *min_buf_size;
554 } get;
555 struct fgetargs {
556 long fd;
557 struct proplistname_args *name_args;
558 long nbytes;
559 char *buf;
560 int *min_buf_size;
561 } fget;
562 struct delargs {
563 char *path;
564 long follow;
565 struct proplistname_args *name_args;
566 } del;
567 struct fdelargs {
568 long fd;
569 struct proplistname_args *name_args;
570 } fdel;
571 };
572
573 enum pl_code {
574 PL_SET = 1, PL_FSET = 2,
575 PL_GET = 3, PL_FGET = 4,
576 PL_DEL = 5, PL_FDEL = 6
577 };
578
579 asmlinkage long osf_proplist_syscall (enum pl_code code, union pl_args *args)
580 {
581 long error;
582 int *min_buf_size_ptr;
583
584 switch (code) {
585 case PL_SET:
586 error = verify_area(VERIFY_READ, &args->set.nbytes,
587 sizeof(args->set.nbytes));
588 if (error)
589 return error;
590 return args->set.nbytes;
591
592 case PL_FSET:
593 error = verify_area(VERIFY_READ, &args->fset.nbytes,
594 sizeof(args->fset.nbytes));
595 if (error)
596 return error;
597 return args->fset.nbytes;
598
599 case PL_GET:
600 error = verify_area(VERIFY_READ, &args->get.min_buf_size,
601 sizeof(args->get.min_buf_size));
602 if (error)
603 return error;
604 min_buf_size_ptr = get_user(&args->get.min_buf_size);
605 error = verify_area(VERIFY_WRITE, min_buf_size_ptr,
606 sizeof(*min_buf_size_ptr));
607 if (error)
608 return error;
609 put_user(0, min_buf_size_ptr);
610 return 0;
611
612 case PL_FGET:
613 error = verify_area(VERIFY_READ, &args->fget.min_buf_size,
614 sizeof(args->fget.min_buf_size));
615 if (error)
616 return error;
617 min_buf_size_ptr = get_user(&args->fget.min_buf_size);
618 error = verify_area(VERIFY_WRITE, min_buf_size_ptr,
619 sizeof(*min_buf_size_ptr));
620 if (error)
621 return error;
622 put_user(0, min_buf_size_ptr);
623 return 0;
624
625 case PL_DEL:
626 case PL_FDEL:
627 return 0;
628
629 default:
630 return -EOPNOTSUPP;
631 }
632 }