This source file includes following definitions.
- sunos_mmap
- sunos_mctl
- sunos_brk
- sunos_sbrk
- sunos_sstk
- sunos_vadvise
- sunos_madvise
- sunos_mincore
- sunos_getdtablesize
- sunos_sigblock
- sunos_sigsetmask
- sunos_filldir
- sunos_getdents
- sunos_filldirentry
- sunos_getdirentries
- sunos_getdomainname
- sunos_uname
- sunos_nosys
- sunos_fpathconf
- sunos_pathconf
- sunos_select
- sunos_nop
- sunos_nfs_get_server_fd
- get_default
- sunos_nfs_mount
- sunos_mount
- sunos_setpgrp
- sunos_wait4
- sunos_killpg
- sunos_audit
- sunos_gethostid
- sunos_sysconf
- free_wait
- check
- sunos_poll
- sunos_shmsys
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include <linux/config.h>
30 #include <linux/kernel.h>
31 #include <linux/sched.h>
32 #include <linux/types.h>
33 #include <linux/mman.h>
34 #include <linux/mm.h>
35 #include <linux/swap.h>
36 #include <linux/fs.h>
37 #include <linux/resource.h>
38 #include <linux/ipc.h>
39 #include <linux/shm.h>
40 #include <linux/signal.h>
41 #include <linux/uio.h>
42 #include <linux/utsname.h>
43 #include <linux/fs.h>
44 #include <linux/major.h>
45 #include <linux/stat.h>
46 #include <linux/malloc.h>
47 #include <linux/pagemap.h>
48
49 #include <asm/segment.h>
50 #ifndef KERNEL_DS
51 #include <linux/segment.h>
52 #endif
53
54 #include <asm/page.h>
55 #include <asm/pgtable.h>
56 #include <asm/pconf.h>
57 #include <asm/idprom.h>
58 #include <asm/unistd.h>
59 #include <asm/system.h>
60
61
62 #include <linux/socket.h>
63 #include <linux/in.h>
64 #include <linux/nfs.h>
65 #include <linux/nfs_mount.h>
66
67
68 #include <linux/time.h>
69 #include <linux/personality.h>
70
71 extern unsigned long get_sparc_unmapped_area(unsigned long len);
72
73
74 asmlinkage unsigned long sunos_mmap(unsigned long addr, unsigned long len,
75 unsigned long prot, unsigned long flags,
76 unsigned long fd, unsigned long off)
77 {
78 struct file * file = NULL;
79 unsigned long retval, ret_type;
80
81 if(flags & MAP_NORESERVE) {
82 printk("%s: unimplemented SunOS MAP_NORESERVE mmap() flag\n",
83 current->comm);
84 flags &= ~MAP_NORESERVE;
85 }
86 if(!(flags & MAP_ANONYMOUS))
87 if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
88 return -EBADF;
89 if(!(flags & MAP_FIXED) && !addr) {
90 addr = get_sparc_unmapped_area(len);
91 if(!addr)
92 return -ENOMEM;
93 }
94
95
96
97
98 if(MAJOR(file->f_inode->i_rdev) == MEM_MAJOR &&
99 MINOR(file->f_inode->i_rdev) == 5) {
100 flags |= MAP_ANONYMOUS;
101 file = 0;
102 }
103 ret_type = flags & _MAP_NEW;
104 flags &= ~_MAP_NEW;
105 retval = do_mmap(file, addr, len, prot, flags, off);
106 if(ret_type)
107 return retval;
108 else
109 return ((retval < KERNBASE) ? 0 : retval);
110 }
111
112
113 asmlinkage int sunos_mctl(unsigned long addr, unsigned long len, int function, char *arg)
114 {
115 return 0;
116 }
117
118
119
120
121
122 asmlinkage int sunos_brk(unsigned long brk)
123 {
124 int freepages;
125 unsigned long rlim;
126 unsigned long newbrk, oldbrk;
127
128 if (brk < current->mm->end_code)
129 return -ENOMEM;
130
131 newbrk = PAGE_ALIGN(brk);
132 oldbrk = PAGE_ALIGN(current->mm->brk);
133 if (oldbrk == newbrk) {
134 current->mm->brk = brk;
135 return 0;
136 }
137
138
139
140
141 if (brk <= current->mm->brk) {
142 current->mm->brk = brk;
143 do_munmap(newbrk, oldbrk-newbrk);
144 return 0;
145 }
146
147
148
149 rlim = current->rlim[RLIMIT_DATA].rlim_cur;
150 if (rlim >= RLIM_INFINITY)
151 rlim = ~0;
152 if (brk - current->mm->end_code > rlim)
153 return -ENOMEM;
154
155
156
157
158 if (find_vma_intersection(current, oldbrk, newbrk+PAGE_SIZE))
159 return -ENOMEM;
160
161
162
163
164
165
166 freepages = buffermem >> PAGE_SHIFT;
167 freepages += page_cache_size;
168 freepages >>= 1;
169 freepages += nr_free_pages;
170 freepages += nr_swap_pages;
171 freepages -= MAP_NR(high_memory) >> 4;
172 freepages -= (newbrk-oldbrk) >> PAGE_SHIFT;
173 if (freepages < 0)
174 return -ENOMEM;
175
176
177
178 current->mm->brk = brk;
179 do_mmap(NULL, oldbrk, newbrk-oldbrk,
180 PROT_READ|PROT_WRITE|PROT_EXEC,
181 MAP_FIXED|MAP_PRIVATE, 0);
182 return 0;
183 }
184
185 asmlinkage unsigned long sunos_sbrk(int increment)
186 {
187 int error;
188
189
190 error = sunos_brk(((int) current->mm->brk) + increment);
191 if(error)
192 return error;
193 else
194 return current->mm->brk;
195 }
196
197
198
199
200
201
202 asmlinkage unsigned long sunos_sstk(int increment)
203 {
204 printk("%s: Call to sunos_sstk(increment<%d>) is unsupported\n",
205 current->comm, increment);
206 return -1;
207 }
208
209
210
211
212 #define VA_NORMAL 0
213 #define VA_ABNORMAL 1
214 #define VA_SEQUENTIAL 2
215 #define VA_INVALIDATE 3
216 static char *vstrings[] = {
217 "VA_NORMAL",
218 "VA_ABNORMAL",
219 "VA_SEQUENTIAL",
220 "VA_INVALIDATE",
221 };
222
223 asmlinkage void sunos_vadvise(unsigned long strategy)
224 {
225
226 printk("%s: Advises us to use %s paging strategy\n",
227 current->comm,
228 strategy <= 3 ? vstrings[strategy] : "BOGUS");
229 return;
230 }
231
232
233
234
235 #define MADV_NORMAL 0
236 #define MADV_RANDOM 1
237 #define MADV_SEQUENTIAL 2
238 #define MADV_WILLNEED 3
239 #define MADV_DONTNEED 4
240
241 static char *mstrings[] = {
242 "MADV_NORMAL",
243 "MADV_RANDOM",
244 "MADV_SEQUENTIAL",
245 "MADV_WILLNEED",
246 "MADV_DONTNEED",
247 };
248
249 asmlinkage void sunos_madvise(unsigned long address, unsigned long len,
250 unsigned long strategy)
251 {
252
253 printk("%s: Advises us to use %s paging strategy for addr<%08lx> len<%08lx>\n",
254 current->comm,
255 strategy <= 4 ? mstrings[strategy] : "BOGUS",
256 address, len);
257 return;
258 }
259
260
261
262
263
264
265
266
267
268
269
270 asmlinkage int sunos_mincore(unsigned long addr, unsigned long len, char *array)
271 {
272 pgd_t *pgdp;
273 pmd_t *pmdp;
274 pte_t *ptep;
275 unsigned long limit;
276 int num_pages, pnum;
277
278 if(addr & (PAGE_SIZE - 1))
279 return -EINVAL;
280
281 num_pages = (len / PAGE_SIZE);
282 if(verify_area(VERIFY_WRITE, array, num_pages))
283 return -EFAULT;
284 if((addr >= KERNBASE) || ((addr + len) > KERNBASE))
285 return -ENOMEM;
286
287
288 pnum = 0;
289 for(limit = addr + len; addr < limit; addr += PAGE_SIZE, pnum++) {
290 pgdp = pgd_offset(current->mm, addr);
291 if(pgd_none(*pgdp))
292 return -ENOMEM;
293 pmdp = pmd_offset(pgdp, addr);
294 if(pmd_none(*pmdp))
295 return -ENOMEM;
296 ptep = pte_offset(pmdp, addr);
297 if(pte_none(*ptep))
298 return -ENOMEM;
299
300 array[pnum] = pte_present(*ptep) ? 1 : 0;
301 }
302 return 0;
303 }
304
305
306
307
308
309 asmlinkage long sunos_getdtablesize(void)
310 {
311 return NR_OPEN;
312 }
313 #define _S(nr) (1<<((nr)-1))
314
315 #define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
316
317 asmlinkage unsigned long sunos_sigblock(unsigned long blk_mask)
318 {
319 unsigned long flags;
320 unsigned long old;
321
322 save_flags(flags); cli();
323 old = current->blocked;
324 current->blocked |= (blk_mask & _BLOCKABLE);
325 restore_flags(flags);
326 return old;
327 }
328
329 asmlinkage unsigned long sunos_sigsetmask(unsigned long newmask)
330 {
331 unsigned long flags;
332 unsigned long retval;
333
334 save_flags(flags); cli();
335 retval = current->blocked;
336 current->blocked = newmask & _BLOCKABLE;
337 restore_flags(flags);
338 return retval;
339 }
340
341
342
343
344 struct sunos_dirent {
345 long d_off;
346 unsigned long d_ino;
347 unsigned short d_reclen;
348 unsigned short d_namlen;
349 char d_name[1];
350 };
351
352 struct sunos_dirent_callback {
353 struct sunos_dirent *curr;
354 struct sunos_dirent *previous;
355 int count;
356 int error;
357 };
358
359 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
360 #define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1))
361
362 static int sunos_filldir(void * __buf, const char * name, int namlen,
363 off_t offset, ino_t ino)
364 {
365 struct sunos_dirent * dirent;
366 struct sunos_dirent_callback * buf = (struct sunos_dirent_callback *) __buf;
367 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
368
369 buf->error = -EINVAL;
370 if (reclen > buf->count)
371 return -EINVAL;
372 dirent = buf->previous;
373 if (dirent)
374 put_user(offset, &dirent->d_off);
375 dirent = buf->curr;
376 buf->previous = dirent;
377 put_user(ino, &dirent->d_ino);
378 put_user(namlen, &dirent->d_namlen);
379 put_user(reclen, &dirent->d_reclen);
380 memcpy_tofs(dirent->d_name, name, namlen);
381 put_user(0, dirent->d_name + namlen);
382 ((char *) dirent) += reclen;
383 buf->curr = dirent;
384 buf->count -= reclen;
385 return 0;
386 }
387
388 asmlinkage int sunos_getdents(unsigned int fd, void * dirent, int cnt)
389 {
390 struct file * file;
391 struct sunos_dirent * lastdirent;
392 struct sunos_dirent_callback buf;
393 int error;
394
395 if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
396 return -EBADF;
397 if (!file->f_op || !file->f_op->readdir)
398 return -ENOTDIR;
399 if(verify_area(VERIFY_WRITE, dirent, cnt))
400 return -EFAULT;
401 if(cnt < (sizeof(struct sunos_dirent) + 255))
402 return -EINVAL;
403
404 buf.curr = (struct sunos_dirent *) dirent;
405 buf.previous = NULL;
406 buf.count = cnt;
407 buf.error = 0;
408 error = file->f_op->readdir(file->f_inode, file, &buf, sunos_filldir);
409 if (error < 0)
410 return error;
411 lastdirent = buf.previous;
412 if (!lastdirent)
413 return buf.error;
414 put_user(file->f_pos, &lastdirent->d_off);
415 return cnt - buf.count;
416 }
417
418
419 struct sunos_direntry {
420 unsigned long d_ino;
421 unsigned short d_reclen;
422 unsigned short d_namlen;
423 char d_name[1];
424 };
425
426 struct sunos_direntry_callback {
427 struct sunos_direntry *curr;
428 struct sunos_direntry *previous;
429 int count;
430 int error;
431 };
432
433 static int sunos_filldirentry(void * __buf, const char * name, int namlen,
434 off_t offset, ino_t ino)
435 {
436 struct sunos_direntry * dirent;
437 struct sunos_direntry_callback * buf = (struct sunos_direntry_callback *) __buf;
438 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
439
440 buf->error = -EINVAL;
441 if (reclen > buf->count)
442 return -EINVAL;
443 dirent = buf->previous;
444 dirent = buf->curr;
445 buf->previous = dirent;
446 put_user(ino, &dirent->d_ino);
447 put_user(namlen, &dirent->d_namlen);
448 put_user(reclen, &dirent->d_reclen);
449 memcpy_tofs(dirent->d_name, name, namlen);
450 put_user(0, dirent->d_name + namlen);
451 ((char *) dirent) += reclen;
452 buf->curr = dirent;
453 buf->count -= reclen;
454 return 0;
455 }
456
457 asmlinkage int sunos_getdirentries(unsigned int fd, void * dirent, int cnt, unsigned int *basep)
458 {
459 struct file * file;
460 struct sunos_direntry * lastdirent;
461 struct sunos_direntry_callback buf;
462 int error;
463
464 if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
465 return -EBADF;
466 if (!file->f_op || !file->f_op->readdir)
467 return -ENOTDIR;
468 if(verify_area(VERIFY_WRITE, dirent, cnt) ||
469 verify_area(VERIFY_WRITE, basep, sizeof(unsigned int)))
470 return -EFAULT;
471 if(cnt < (sizeof(struct sunos_direntry) + 255))
472 return -EINVAL;
473
474 buf.curr = (struct sunos_direntry *) dirent;
475 buf.previous = NULL;
476 buf.count = cnt;
477 buf.error = 0;
478 error = file->f_op->readdir(file->f_inode, file, &buf, sunos_filldirentry);
479 if (error < 0)
480 return error;
481 lastdirent = buf.previous;
482 if (!lastdirent)
483 return buf.error;
484 put_user(file->f_pos, basep);
485 return cnt - buf.count;
486 }
487
488 asmlinkage int sunos_getdomainname(char *name, int len)
489 {
490 int error;
491
492 if(len > __NEW_UTS_LEN)
493 return -EFAULT;
494 error = verify_area(VERIFY_WRITE, name, len);
495 if(error)
496 return -EFAULT;
497 memcpy_tofs(name, system_utsname.domainname, len);
498 return 0;
499 }
500
501 struct sunos_utsname {
502 char sname[9];
503 char nname[9];
504 char nnext[56];
505 char rel[9];
506 char ver[9];
507 char mach[9];
508 };
509
510 asmlinkage int sunos_uname(struct sunos_utsname *name)
511 {
512 int error;
513 if(!name)
514 return -EFAULT;
515 error = verify_area(VERIFY_WRITE, name, sizeof *name);
516 if(error)
517 return error;
518 memcpy_tofs(&name->sname[0], &system_utsname.sysname[0],
519 sizeof(name->sname) - 1);
520 memcpy_tofs(&name->nname[0], &system_utsname.nodename[0],
521 sizeof(name->nname) - 1);
522 name->nname[8] = '\0';
523 memcpy_tofs(&name->rel[0], &system_utsname.release[0],
524 sizeof(name->rel) - 1);
525 memcpy_tofs(&name->ver[0], &system_utsname.version[0],
526 sizeof(name->ver) - 1);
527 memcpy_tofs(&name->mach[0], &system_utsname.machine[0],
528 sizeof(name->mach) - 1);
529 return 0;
530 }
531
532 asmlinkage int sunos_nosys(void)
533 {
534 struct pt_regs *regs;
535
536 regs = (struct pt_regs *) (current->saved_kernel_stack +
537 sizeof(struct reg_window));
538 current->tss.sig_address = regs->pc;
539 current->tss.sig_desc = regs->u_regs[UREG_G1];
540 send_sig(SIGSYS, current, 1);
541 printk("Process makes ni_syscall number %d, register dump:\n",
542 (int) regs->u_regs[UREG_G1]);
543 show_regs(regs);
544 return -ENOSYS;
545 }
546
547
548
549
550 asmlinkage int sunos_fpathconf(int fd, int name)
551 {
552 switch(name) {
553 case _PCONF_LINK:
554 return LINK_MAX;
555 case _PCONF_CANON:
556 return MAX_CANON;
557 case _PCONF_INPUT:
558 return MAX_INPUT;
559 case _PCONF_NAME:
560 return NAME_MAX;
561 case _PCONF_PATH:
562 return PATH_MAX;
563 case _PCONF_PIPE:
564 return PIPE_BUF;
565 case _PCONF_CHRESTRICT:
566 return 1;
567 case _PCONF_NOTRUNC:
568 return 0;
569 case _PCONF_VDISABLE:
570 return 0;
571 default:
572 return -EINVAL;
573 }
574 }
575
576 asmlinkage int sunos_pathconf(char *path, int name)
577 {
578 return sunos_fpathconf(0, name);
579 }
580
581
582 extern asmlinkage int
583 sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval *tvp);
584
585 asmlinkage int sunos_select(int width, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval *tvp)
586 {
587
588 current->personality |= STICKY_TIMEOUTS;
589 return sys_select (width, inp, outp, exp, tvp);
590 }
591
592 asmlinkage void sunos_nop(void)
593 {
594 return;
595 }
596
597
598 #define SMNT_RDONLY 1
599 #define SMNT_NOSUID 2
600 #define SMNT_NEWTYPE 4
601 #define SMNT_GRPID 8
602 #define SMNT_REMOUNT 16
603 #define SMNT_NOSUB 32
604 #define SMNT_MULTI 64
605 #define SMNT_SYS5 128
606
607 struct sunos_fh_t {
608 char fh_data [NFS_FHSIZE];
609 };
610
611 struct sunos_nfs_mount_args {
612 struct sockaddr_in *addr;
613 struct nfs_fh *fh;
614 int flags;
615 int wsize;
616 int rsize;
617 int timeo;
618 int retrans;
619 char *hostname;
620 int acregmin;
621 int acregmax;
622 int acdirmin;
623 int acdirmax;
624 char *netname;
625 };
626
627
628 extern int do_mount(kdev_t, const char *, const char *, char *, int, void *);
629 extern dev_t get_unnamed_dev(void);
630 extern void put_unnamed_dev(dev_t);
631 extern asmlinkage int sys_mount(char *, char *, char *, unsigned long, void *);
632 extern asmlinkage int sys_connect(int fd, struct sockaddr *uservaddr, int addrlen);
633 extern asmlinkage int sys_socket(int family, int type, int protocol);
634 extern asmlinkage int sys_bind(int fd, struct sockaddr *umyaddr, int addrlen);
635
636
637
638
639
640
641 static int
642 sunos_nfs_get_server_fd (int fd, struct sockaddr_in *addr)
643 {
644 struct sockaddr_in local;
645 struct sockaddr_in server;
646 int try_port;
647 int ret;
648 struct socket *socket;
649 struct inode *inode;
650 struct file *file;
651
652 file = current->files->fd [fd];
653 inode = file->f_inode;
654 if (!inode || !inode->i_sock)
655 return 0;
656
657 socket = &inode->u.socket_i;
658 local.sin_family = AF_INET;
659 local.sin_addr.s_addr = INADDR_ANY;
660
661
662 try_port = 1024;
663 do {
664 local.sin_port = htons (--try_port);
665 ret = socket->ops->bind(socket, (struct sockaddr*)&local,
666 sizeof(local));
667 } while (ret && try_port > (1024 / 2));
668
669 if (ret)
670 return 0;
671
672 server.sin_family = AF_INET;
673 server.sin_addr = addr->sin_addr;
674 server.sin_port = NFS_PORT;
675
676
677 ret = socket->ops->connect (socket, (struct sockaddr *) &server,
678 sizeof (server), file->f_flags);
679 if (ret < 0)
680 return 0;
681 return 1;
682 }
683
684 static int get_default (int value, int def_value)
685 {
686 if (value)
687 return value;
688 else
689 return def_value;
690 }
691
692 asmlinkage int sunos_nfs_mount(char *dir_name, int linux_flags, void *data)
693 {
694 int ret = -ENODEV, error;
695 int server_fd;
696 char *the_name;
697 struct nfs_mount_data linux_nfs_mount;
698 struct sunos_nfs_mount_args *sunos_mount = data;
699 dev_t dev;
700
701 error = verify_area(VERIFY_READ, data, sizeof (struct sunos_nfs_mount_args));
702 if (error)
703 return error;
704
705
706
707
708
709
710 server_fd = sys_socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
711 if (server_fd < 0)
712 return -ENXIO;
713
714 if (!sunos_nfs_get_server_fd (server_fd, sunos_mount->addr)){
715 sys_close (server_fd);
716 return -ENXIO;
717 }
718
719
720 linux_nfs_mount.version = NFS_MOUNT_VERSION;
721 linux_nfs_mount.flags = sunos_mount->flags;
722 linux_nfs_mount.addr = *sunos_mount->addr;
723 linux_nfs_mount.root = *sunos_mount->fh;
724 linux_nfs_mount.fd = server_fd;
725
726 linux_nfs_mount.rsize = get_default (sunos_mount->rsize, 8192);
727 linux_nfs_mount.wsize = get_default (sunos_mount->wsize, 8192);
728 linux_nfs_mount.timeo = get_default (sunos_mount->timeo, 10);
729 linux_nfs_mount.retrans = sunos_mount->retrans;
730
731 linux_nfs_mount.acregmin = sunos_mount->acregmin;
732 linux_nfs_mount.acregmax = sunos_mount->acregmax;
733 linux_nfs_mount.acdirmin = sunos_mount->acdirmin;
734 linux_nfs_mount.acdirmax = sunos_mount->acdirmax;
735
736 if (getname (sunos_mount->hostname, &the_name))
737 return -EFAULT;
738
739 strncpy (linux_nfs_mount.hostname, the_name, 254);
740 linux_nfs_mount.hostname [255] = 0;
741 putname (the_name);
742
743 dev = get_unnamed_dev ();
744
745 ret = do_mount (dev, "", dir_name, "nfs", linux_flags, &linux_nfs_mount);
746 if (ret)
747 put_unnamed_dev(dev);
748
749 return ret;
750 }
751
752 asmlinkage int
753 sunos_mount(char *type, char *dir, int flags, void *data)
754 {
755 int linux_flags = MS_MGC_MSK;
756 int error;
757 char *dev_fname = 0;
758
759
760 if ((flags & SMNT_NEWTYPE) == 0)
761 return -EINVAL;
762
763
764 if (flags & (SMNT_GRPID|SMNT_NOSUB|SMNT_MULTI|SMNT_SYS5))
765 return -EINVAL;
766
767 if(flags & SMNT_REMOUNT)
768 linux_flags |= MS_REMOUNT;
769 if(flags & SMNT_RDONLY)
770 linux_flags |= MS_RDONLY;
771 if(flags & SMNT_NOSUID)
772 linux_flags |= MS_NOSUID;
773 error = verify_area(VERIFY_READ, type, 16);
774 if(error)
775 return error;
776 if(strcmp(type, "ext2") == 0) {
777 dev_fname = (char *) data;
778 } else if(strcmp(type, "iso9660") == 0) {
779 dev_fname = (char *) data;
780 } else if(strcmp(type, "minix") == 0) {
781 dev_fname = (char *) data;
782 } else if(strcmp(type, "ext") == 0) {
783 dev_fname = (char *) data;
784 } else if(strcmp(type, "xiafs") == 0) {
785 dev_fname = (char *) data;
786 } else if(strcmp(type, "nfs") == 0) {
787 error = sunos_nfs_mount (dir, flags, data);
788 return error;
789 } else if(strcmp(type, "ufs") == 0) {
790 printk("Warning: UFS filesystem mounts unsupported.\n");
791 return -ENODEV;
792 } else if(strcmp(type, "proc")) {
793 return -ENODEV;
794 }
795 if(error)
796 return error;
797 error = sys_mount(dev_fname, dir, type, linux_flags, NULL);
798 return error;
799 }
800
801 extern asmlinkage int sys_setsid(void);
802 extern asmlinkage int sys_setpgid(pid_t, pid_t);
803
804 asmlinkage int sunos_setpgrp(pid_t pid, pid_t pgid)
805 {
806
807 if((!pid || pid == current->pid) &&
808 !pgid) {
809 sys_setsid();
810 return 0;
811 } else {
812 return sys_setpgid(pid, pgid);
813 }
814 }
815
816
817 extern asmlinkage int sys_wait4(pid_t, unsigned int *, int, struct rusage *);
818 asmlinkage int sunos_wait4(pid_t pid, unsigned int *stat_addr, int options, struct rusage *ru)
819 {
820 return sys_wait4((pid ? pid : -1), stat_addr, options, ru);
821 }
822
823 extern int kill_pg(int, int, int);
824 asmlinkage int sunos_killpg(int pgrp, int sig)
825 {
826 return kill_pg(pgrp, sig, 0);
827 }
828
829 asmlinkage int sunos_audit(void)
830 {
831 printk ("sys_audit\n");
832 return -1;
833 }
834
835 extern asmlinkage unsigned long sunos_gethostid(void)
836 {
837 return (unsigned long) idprom->id_sernum;
838 }
839
840 extern asmlinkage long sunos_sysconf (int name)
841 {
842 switch (name){
843 case _SC_ARG_MAX:
844 return ARG_MAX;
845 case _SC_CHILD_MAX:
846 return CHILD_MAX;
847 case _SC_CLK_TCK:
848 return HZ;
849 case _SC_NGROUPS_MAX:
850 return NGROUPS_MAX;
851 case _SC_OPEN_MAX:
852 return OPEN_MAX;
853 case _SC_JOB_CONTROL:
854 return 1;
855 case _SC_SAVED_IDS:
856 return 1;
857 case _SC_VERSION:
858
859
860
861 return 199009L;
862 }
863 return -1;
864 }
865
866 #define POLL_ROUND_UP(x,y) (((x)+(y)-1)/(y))
867
868 #define POLLIN 1
869 #define POLLPRI 2
870 #define POLLOUT 4
871 #define POLLERR 8
872 #define POLLHUP 16
873 #define POLLNVAL 32
874 #define POLLRDNORM 64
875 #define POLLWRNORM POLLOUT
876 #define POLLRDBAND 128
877 #define POLLWRBAND 256
878
879 #define LINUX_POLLIN (POLLRDNORM | POLLRDBAND | POLLIN)
880 #define LINUX_POLLOUT (POLLWRBAND | POLLWRNORM | POLLOUT)
881 #define LINUX_POLLERR (POLLERR)
882
883 static inline void free_wait(select_table * p)
884 {
885 struct select_table_entry * entry = p->entry + p->nr;
886
887 while (p->nr > 0) {
888 p->nr--;
889 entry--;
890 remove_wait_queue(entry->wait_address,&entry->wait);
891 }
892 }
893
894
895
896 static int check(int flag, select_table * wait, struct file * file)
897 {
898 struct inode * inode;
899 struct file_operations *fops;
900 int (*select) (struct inode *, struct file *, int, select_table *);
901
902 inode = file->f_inode;
903 if ((fops = file->f_op) && (select = fops->select))
904 return select(inode, file, flag, wait)
905 || (wait && select(inode, file, flag, NULL));
906 if (S_ISREG(inode->i_mode))
907 return 1;
908 return 0;
909 }
910
911 struct poll {
912 int fd;
913 short events;
914 short revents;
915 };
916
917 int sunos_poll(struct poll * ufds, size_t nfds, int timeout)
918 {
919 int i,j, count, fdcount, error, retflag;
920 struct poll * fdpnt;
921 struct poll * fds, *fds1;
922 select_table wait_table, *wait;
923 struct select_table_entry *entry;
924
925 if ((error = verify_area(VERIFY_READ, ufds, nfds*sizeof(struct poll))))
926 return error;
927
928 if (nfds > NR_OPEN)
929 return -EINVAL;
930
931 if (!(entry = (struct select_table_entry*)__get_free_page(GFP_KERNEL))
932 || !(fds = (struct poll *)kmalloc(nfds*sizeof(struct poll), GFP_KERNEL)))
933 return -ENOMEM;
934
935 memcpy_fromfs(fds, ufds, nfds*sizeof(struct poll));
936
937 if (timeout < 0)
938 current->timeout = 0x7fffffff;
939 else {
940 current->timeout = jiffies + POLL_ROUND_UP(timeout, (1000/HZ));
941 if (current->timeout <= jiffies)
942 current->timeout = 0;
943 }
944
945 count = 0;
946 wait_table.nr = 0;
947 wait_table.entry = entry;
948 wait = &wait_table;
949
950 for(fdpnt = fds, j = 0; j < (int)nfds; j++, fdpnt++) {
951 i = fdpnt->fd;
952 fdpnt->revents = 0;
953 if (!current->files->fd[i] || !current->files->fd[i]->f_inode)
954 fdpnt->revents = POLLNVAL;
955 }
956 repeat:
957 current->state = TASK_INTERRUPTIBLE;
958 for(fdpnt = fds, j = 0; j < (int)nfds; j++, fdpnt++) {
959 i = fdpnt->fd;
960
961 if(i < 0) continue;
962 if (!current->files->fd[i] || !current->files->fd[i]->f_inode) continue;
963
964 if ((fdpnt->events & LINUX_POLLIN)
965 && check(SEL_IN, wait, current->files->fd[i])) {
966 if (fdpnt->events & POLLIN)
967 retflag = POLLIN;
968 if (fdpnt->events & POLLRDNORM)
969 retflag = POLLRDNORM;
970 fdpnt->revents |= retflag;
971 count++;
972 wait = NULL;
973 }
974
975 if ((fdpnt->events & LINUX_POLLOUT) &&
976 check(SEL_OUT, wait, current->files->fd[i])) {
977 fdpnt->revents |= (LINUX_POLLOUT & fdpnt->events);
978 count++;
979 wait = NULL;
980 }
981
982 if (check(SEL_EX, wait, current->files->fd[i])) {
983 fdpnt->revents |= POLLHUP;
984 count++;
985 wait = NULL;
986 }
987 }
988
989 if ((current->signal & (~current->blocked)))
990 return -EINTR;
991
992 wait = NULL;
993 if (!count && current->timeout > jiffies) {
994 schedule();
995 goto repeat;
996 }
997
998 free_wait(&wait_table);
999 free_page((unsigned long) entry);
1000
1001
1002 fds1 = fds;
1003 fdcount = 0;
1004 for(i=0; i < (int)nfds; i++, ufds++, fds++) {
1005 if (fds->revents) {
1006 fdcount++;
1007 }
1008 put_fs_word(fds->revents, &ufds->revents);
1009 }
1010 kfree(fds1);
1011 current->timeout = 0;
1012 current->state = TASK_RUNNING;
1013 return fdcount;
1014 }
1015
1016 extern asmlinkage int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr);
1017 extern asmlinkage int sys_shmctl (int shmid, int cmd, struct shmid_ds *buf);
1018 extern asmlinkage int sys_shmdt (char *shmaddr);
1019 extern asmlinkage int sys_shmget (key_t key, int size, int shmflg);
1020
1021 asmlinkage int sunos_shmsys(int op, unsigned long arg1, unsigned long arg2,
1022 unsigned long arg3)
1023 {
1024 unsigned long raddr;
1025 int rval;
1026
1027 switch(op) {
1028 case 0:
1029
1030 rval = sys_shmat((int)arg1,(char *)arg2,(int)arg3,&raddr);
1031 if(rval != 0)
1032 return rval;
1033 return (int) raddr;
1034 case 1:
1035
1036 return sys_shmctl((int)arg1,(int)arg2,(struct shmid_ds *)arg3);
1037 case 2:
1038
1039 return sys_shmdt((char *)arg1);
1040 case 3:
1041
1042 return sys_shmget((key_t)arg1,(int)arg2,(int)arg3);
1043 default:
1044 return -EINVAL;
1045 }
1046 }