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