* add p cc
[mascara-docs.git] / i386 / linux / linux-2.3.21 / arch / sparc64 / kernel / sys_sunos32.c
blob0f0c2a5367053155f157468c241bcd63391906c4
1 /* $Id: sys_sunos32.c,v 1.31 1999/08/30 10:01:19 davem Exp $
2 * sys_sunos32.c: SunOS binary compatability layer on sparc64.
4 * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
5 * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
7 * Based upon preliminary work which is:
9 * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu)
12 #include <linux/kernel.h>
13 #include <linux/sched.h>
14 #include <linux/types.h>
15 #include <linux/mman.h>
16 #include <linux/mm.h>
17 #include <linux/swap.h>
18 #include <linux/fs.h>
19 #include <linux/file.h>
20 #include <linux/resource.h>
21 #include <linux/ipc.h>
22 #include <linux/shm.h>
23 #include <linux/msg.h>
24 #include <linux/sem.h>
25 #include <linux/signal.h>
26 #include <linux/uio.h>
27 #include <linux/utsname.h>
28 #include <linux/major.h>
29 #include <linux/stat.h>
30 #include <linux/malloc.h>
31 #include <linux/pagemap.h>
32 #include <linux/errno.h>
33 #include <linux/smp.h>
34 #include <linux/smp_lock.h>
36 #include <asm/uaccess.h>
37 #include <asm/page.h>
38 #include <asm/pgtable.h>
39 #include <asm/pconf.h>
40 #include <asm/idprom.h> /* for gethostid() */
41 #include <asm/unistd.h>
42 #include <asm/system.h>
44 /* For the nfs mount emulation */
45 #include <linux/socket.h>
46 #include <linux/in.h>
47 #include <linux/nfs.h>
48 #include <linux/nfs_mount.h>
50 /* for sunos_select */
51 #include <linux/time.h>
52 #include <linux/personality.h>
54 /* Use this to get at 32-bit user passed pointers. */
55 #define A(__x) \
56 ({ unsigned long __ret; \
57 __asm__ ("srl %0, 0, %0" \
58 : "=r" (__ret) \
59 : "0" (__x)); \
60 __ret; \
63 #define SUNOS_NR_OPEN 256
65 asmlinkage u32 sunos_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 off)
67 struct file *file = NULL;
68 unsigned long retval, ret_type;
70 down(&current->mm->mmap_sem);
71 lock_kernel();
72 current->personality |= PER_BSD;
73 if(flags & MAP_NORESERVE) {
74 printk("%s: unimplemented SunOS MAP_NORESERVE mmap() flag\n",
75 current->comm);
76 flags &= ~MAP_NORESERVE;
78 retval = -EBADF;
79 if(!(flags & MAP_ANONYMOUS)) {
80 if(fd >= SUNOS_NR_OPEN)
81 goto out;
82 file = fget(fd);
83 if (!file)
84 goto out;
85 if (file->f_dentry && file->f_dentry->d_inode) {
86 struct inode * inode = file->f_dentry->d_inode;
87 if(MAJOR(inode->i_rdev) == MEM_MAJOR &&
88 MINOR(inode->i_rdev) == 5) {
89 flags |= MAP_ANONYMOUS;
90 fput(file);
91 file = NULL;
96 retval = -ENOMEM;
97 if(!(flags & MAP_FIXED) && !addr) {
98 unsigned long attempt = get_unmapped_area(addr, len);
99 if(!attempt || (attempt >= 0xf0000000UL))
100 goto out_putf;
101 addr = (u32) attempt;
103 if(!(flags & MAP_FIXED))
104 addr = 0;
105 ret_type = flags & _MAP_NEW;
106 flags &= ~_MAP_NEW;
108 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
109 retval = do_mmap(file,
110 (unsigned long) addr, (unsigned long) len,
111 (unsigned long) prot, (unsigned long) flags,
112 (unsigned long) off);
113 if(!ret_type)
114 retval = ((retval < 0xf0000000) ? 0 : retval);
115 out_putf:
116 if (file)
117 fput(file);
118 out:
119 unlock_kernel();
120 up(&current->mm->mmap_sem);
121 return (u32) retval;
124 asmlinkage int sunos_mctl(u32 addr, u32 len, int function, u32 arg)
126 return 0;
129 asmlinkage int sunos_brk(u32 baddr)
131 int freepages, retval = -ENOMEM;
132 unsigned long rlim;
133 unsigned long newbrk, oldbrk, brk = (unsigned long) baddr;
135 down(&current->mm->mmap_sem);
136 if (brk < current->mm->end_code)
137 goto out;
138 newbrk = PAGE_ALIGN(brk);
139 oldbrk = PAGE_ALIGN(current->mm->brk);
140 retval = 0;
141 if (oldbrk == newbrk) {
142 current->mm->brk = brk;
143 goto out;
145 /* Always allow shrinking brk. */
146 if (brk <= current->mm->brk) {
147 current->mm->brk = brk;
148 do_munmap(newbrk, oldbrk-newbrk);
149 goto out;
151 /* Check against rlimit and stack.. */
152 retval = -ENOMEM;
153 rlim = current->rlim[RLIMIT_DATA].rlim_cur;
154 if (rlim >= RLIM_INFINITY)
155 rlim = ~0;
156 if (brk - current->mm->end_code > rlim)
157 goto out;
158 /* Check against existing mmap mappings. */
159 if (find_vma_intersection(current->mm, oldbrk, newbrk+PAGE_SIZE))
160 goto out;
161 /* stupid algorithm to decide if we have enough memory: while
162 * simple, it hopefully works in most obvious cases.. Easy to
163 * fool it, but this should catch most mistakes.
165 freepages = atomic_read(&buffermem) >> PAGE_SHIFT;
166 freepages += atomic_read(&page_cache_size);
167 freepages >>= 1;
168 freepages += nr_free_pages;
169 freepages += nr_swap_pages;
170 freepages -= num_physpages >> 4;
171 freepages -= (newbrk-oldbrk) >> PAGE_SHIFT;
172 if (freepages < 0)
173 goto out;
174 /* Ok, we have probably got enough memory - let it rip. */
175 current->mm->brk = brk;
176 do_brk(oldbrk, newbrk-oldbrk);
177 retval = 0;
178 out:
179 up(&current->mm->mmap_sem);
180 return retval;
183 asmlinkage u32 sunos_sbrk(int increment)
185 int error, oldbrk;
187 /* This should do it hopefully... */
188 lock_kernel();
189 oldbrk = (int)current->mm->brk;
190 error = sunos_brk(((int) current->mm->brk) + increment);
191 if(!error)
192 error = oldbrk;
193 unlock_kernel();
194 return error;
197 asmlinkage u32 sunos_sstk(int increment)
199 lock_kernel();
200 printk("%s: Call to sunos_sstk(increment<%d>) is unsupported\n",
201 current->comm, increment);
202 unlock_kernel();
203 return (u32)-1;
206 /* Give hints to the kernel as to what paging strategy to use...
207 * Completely bogus, don't remind me.
209 #define VA_NORMAL 0 /* Normal vm usage expected */
210 #define VA_ABNORMAL 1 /* Abnormal/random vm usage probable */
211 #define VA_SEQUENTIAL 2 /* Accesses will be of a sequential nature */
212 #define VA_INVALIDATE 3 /* Page table entries should be flushed ??? */
213 static char *vstrings[] = {
214 "VA_NORMAL",
215 "VA_ABNORMAL",
216 "VA_SEQUENTIAL",
217 "VA_INVALIDATE",
220 asmlinkage void sunos_vadvise(u32 strategy)
222 /* I wanna see who uses this... */
223 lock_kernel();
224 printk("%s: Advises us to use %s paging strategy\n",
225 current->comm,
226 strategy <= 3 ? vstrings[strategy] : "BOGUS");
227 unlock_kernel();
230 /* Same as vadvise, and just as bogus, but for a range of virtual
231 * process address space.
233 #define MADV_NORMAL 0 /* Nothing special... */
234 #define MADV_RANDOM 1 /* I am emacs... */
235 #define MADV_SEQUENTIAL 2 /* I am researcher code... */
236 #define MADV_WILLNEED 3 /* Pages in this range will be needed */
237 #define MADV_DONTNEED 4 /* Pages in this range won't be needed */
239 static char *mstrings[] = {
240 "MADV_NORMAL",
241 "MADV_RANDOM",
242 "MADV_SEQUENTIAL",
243 "MADV_WILLNEED",
244 "MADV_DONTNEED",
247 asmlinkage void sunos_madvise(u32 address, u32 len, u32 strategy)
249 /* I wanna see who uses this... */
250 lock_kernel();
251 printk("%s: Advises us to use %s paging strategy for addr<%08x> len<%08x>\n",
252 current->comm, strategy <= 4 ? mstrings[strategy] : "BOGUS",
253 address, len);
254 unlock_kernel();
257 /* Places into character array, the status of all the pages in the passed
258 * range from 'addr' to 'addr + len'. -1 on failure, 0 on success...
259 * The encoding in each character is:
260 * low-bit is zero == Page is not in physical ram right now
261 * low-bit is one == Page is currently residing in core
262 * All other bits are undefined within the character so there...
263 * Also, if you try to get stats on an area outside of the user vm area
264 * *or* the passed base address is not aligned on a page boundary you
265 * get an error.
267 asmlinkage int sunos_mincore(u32 __addr, u32 len, u32 u_array)
269 pgd_t *pgdp;
270 pmd_t *pmdp;
271 pte_t *ptep;
272 unsigned long limit, addr = (unsigned long)__addr;
273 int num_pages, pnum, retval = -EINVAL;
274 char *array = (char *)A(u_array);
276 lock_kernel();
277 if(addr & ~(4096))
278 goto out;
279 num_pages = (len / 4096);
280 retval = -EFAULT;
281 if(verify_area(VERIFY_WRITE, array, num_pages))
282 goto out;
283 retval = -ENOMEM;
284 if((addr >= 0xf0000000) || ((addr + len) > 0xf0000000))
285 goto out; /* I'm sure you're curious about kernel mappings.. */
286 /* Wheee, go through pte's */
287 pnum = 0;
288 for(limit = addr + len; addr < limit; addr += 4096, pnum++) {
289 pgdp = pgd_offset(current->mm, addr);
290 if(pgd_none(*pgdp))
291 goto out; /* As per SunOS manpage */
292 pmdp = pmd_offset(pgdp, addr);
293 if(pmd_none(*pmdp))
294 goto out; /* As per SunOS manpage */
295 ptep = pte_offset(pmdp, addr);
296 if(pte_none(*ptep))
297 goto out; /* As per SunOS manpage */
298 /* Page in core or Swapped page? */
299 __put_user((pte_present(*ptep) ? 1 : 0), &array[pnum]);
301 retval = 0; /* Success... I think... */
302 out:
303 unlock_kernel();
304 return retval;
307 /* This just wants the soft limit (ie. rlim_cur element) of the RLIMIT_NOFILE
308 * resource limit and is for backwards compatibility with older sunos
309 * revs.
311 asmlinkage int sunos_getdtablesize(void)
313 return SUNOS_NR_OPEN;
317 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
319 asmlinkage u32 sunos_sigblock(u32 blk_mask)
321 u32 old;
323 spin_lock_irq(&current->sigmask_lock);
324 old = (u32) current->blocked.sig[0];
325 current->blocked.sig[0] |= (blk_mask & _BLOCKABLE);
326 spin_unlock_irq(&current->sigmask_lock);
327 return old;
330 asmlinkage u32 sunos_sigsetmask(u32 newmask)
332 u32 retval;
334 spin_lock_irq(&current->sigmask_lock);
335 retval = (u32) current->blocked.sig[0];
336 current->blocked.sig[0] = (newmask & _BLOCKABLE);
337 spin_unlock_irq(&current->sigmask_lock);
338 return retval;
341 /* SunOS getdents is very similar to the newer Linux (iBCS2 compliant) */
342 /* getdents system call, the format of the structure just has a different */
343 /* layout (d_off+d_ino instead of d_ino+d_off) */
344 struct sunos_dirent {
345 s32 d_off;
346 u32 d_ino;
347 u16 d_reclen;
348 u16 d_namlen;
349 char d_name[1];
352 struct sunos_dirent_callback {
353 struct sunos_dirent *curr;
354 struct sunos_dirent *previous;
355 int count;
356 int error;
359 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
360 #define ROUND_UP(x) (((x)+sizeof(s32)-1) & ~(sizeof(s32)-1))
362 static int sunos_filldir(void * __buf, const char * name, int namlen,
363 off_t offset, ino_t ino)
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);
369 buf->error = -EINVAL; /* only used if we fail.. */
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 copy_to_user(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;
388 asmlinkage int sunos_getdents(unsigned int fd, u32 u_dirent, int cnt)
390 struct file * file;
391 struct inode * inode;
392 struct sunos_dirent * lastdirent;
393 struct sunos_dirent_callback buf;
394 int error = -EBADF;
395 void *dirent = (void *)A(u_dirent);
397 lock_kernel();
398 if(fd >= SUNOS_NR_OPEN)
399 goto out;
401 file = fget(fd);
402 if(!file)
403 goto out;
405 error = -ENOTDIR;
406 if (!file->f_op || !file->f_op->readdir)
407 goto out_putf;
409 error = -EINVAL;
410 if(cnt < (sizeof(struct sunos_dirent) + 255))
411 goto out_putf;
413 buf.curr = (struct sunos_dirent *) dirent;
414 buf.previous = NULL;
415 buf.count = cnt;
416 buf.error = 0;
418 inode = file->f_dentry->d_inode;
419 down(&inode->i_sem);
420 error = file->f_op->readdir(file, &buf, sunos_filldir);
421 up(&inode->i_sem);
422 if (error < 0)
423 goto out_putf;
425 lastdirent = buf.previous;
426 error = buf.error;
427 if (lastdirent) {
428 put_user(file->f_pos, &lastdirent->d_off);
429 error = cnt - buf.count;
432 out_putf:
433 fput(file);
434 out:
435 unlock_kernel();
436 return error;
439 /* Old sunos getdirentries, severely broken compatibility stuff here. */
440 struct sunos_direntry {
441 u32 d_ino;
442 u16 d_reclen;
443 u16 d_namlen;
444 char d_name[1];
447 struct sunos_direntry_callback {
448 struct sunos_direntry *curr;
449 struct sunos_direntry *previous;
450 int count;
451 int error;
454 static int sunos_filldirentry(void * __buf, const char * name, int namlen,
455 off_t offset, ino_t ino)
457 struct sunos_direntry * dirent;
458 struct sunos_direntry_callback * buf = (struct sunos_direntry_callback *) __buf;
459 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
461 buf->error = -EINVAL; /* only used if we fail.. */
462 if (reclen > buf->count)
463 return -EINVAL;
464 dirent = buf->previous;
465 dirent = buf->curr;
466 buf->previous = dirent;
467 put_user(ino, &dirent->d_ino);
468 put_user(namlen, &dirent->d_namlen);
469 put_user(reclen, &dirent->d_reclen);
470 copy_to_user(dirent->d_name, name, namlen);
471 put_user(0, dirent->d_name + namlen);
472 ((char *) dirent) += reclen;
473 buf->curr = dirent;
474 buf->count -= reclen;
475 return 0;
478 asmlinkage int sunos_getdirentries(unsigned int fd, u32 u_dirent,
479 int cnt, u32 u_basep)
481 void *dirent = (void *) A(u_dirent);
482 unsigned int *basep = (unsigned int *)A(u_basep);
483 struct file * file;
484 struct inode * inode;
485 struct sunos_direntry * lastdirent;
486 int error = -EBADF;
487 struct sunos_direntry_callback buf;
489 lock_kernel();
490 if(fd >= SUNOS_NR_OPEN)
491 goto out;
493 file = fget(fd);
494 if(!file)
495 goto out;
497 error = -ENOTDIR;
498 if (!file->f_op || !file->f_op->readdir)
499 goto out_putf;
501 error = -EINVAL;
502 if(cnt < (sizeof(struct sunos_direntry) + 255))
503 goto out_putf;
505 buf.curr = (struct sunos_direntry *) dirent;
506 buf.previous = NULL;
507 buf.count = cnt;
508 buf.error = 0;
510 inode = file->f_dentry->d_inode;
511 down(&inode->i_sem);
512 error = file->f_op->readdir(file, &buf, sunos_filldirentry);
513 up(&inode->i_sem);
514 if (error < 0)
515 goto out_putf;
517 lastdirent = buf.previous;
518 error = buf.error;
519 if (lastdirent) {
520 put_user(file->f_pos, basep);
521 error = cnt - buf.count;
524 out_putf:
525 fput(file);
526 out:
527 unlock_kernel();
528 return error;
531 struct sunos_utsname {
532 char sname[9];
533 char nname[9];
534 char nnext[56];
535 char rel[9];
536 char ver[9];
537 char mach[9];
540 asmlinkage int sunos_uname(struct sunos_utsname *name)
542 int ret;
544 down(&uts_sem);
545 ret = copy_to_user(&name->sname[0], &system_utsname.sysname[0], sizeof(name->sname) - 1);
546 ret |= copy_to_user(&name->nname[0], &system_utsname.nodename[0], sizeof(name->nname) - 1);
547 ret |= put_user('\0', &name->nname[8]);
548 ret |= copy_to_user(&name->rel[0], &system_utsname.release[0], sizeof(name->rel) - 1);
549 ret |= copy_to_user(&name->ver[0], &system_utsname.version[0], sizeof(name->ver) - 1);
550 ret |= copy_to_user(&name->mach[0], &system_utsname.machine[0], sizeof(name->mach) - 1);
551 up(&uts_sem);
552 return ret;
555 asmlinkage int sunos_nosys(void)
557 struct pt_regs *regs;
559 lock_kernel();
560 regs = current->thread.kregs;
561 current->thread.sig_address = regs->tpc;
562 current->thread.sig_desc = regs->u_regs[UREG_G1];
563 send_sig(SIGSYS, current, 1);
564 printk("Process makes ni_syscall number %d, register dump:\n",
565 (int) regs->u_regs[UREG_G1]);
566 show_regs(regs);
567 unlock_kernel();
568 return -ENOSYS;
571 /* This is not a real and complete implementation yet, just to keep
572 * the easy SunOS binaries happy.
574 asmlinkage int sunos_fpathconf(int fd, int name)
576 int ret;
578 lock_kernel();
579 switch(name) {
580 case _PCONF_LINK:
581 ret = LINK_MAX;
582 break;
583 case _PCONF_CANON:
584 ret = MAX_CANON;
585 break;
586 case _PCONF_INPUT:
587 ret = MAX_INPUT;
588 break;
589 case _PCONF_NAME:
590 ret = NAME_MAX;
591 break;
592 case _PCONF_PATH:
593 ret = PATH_MAX;
594 break;
595 case _PCONF_PIPE:
596 ret = PIPE_BUF;
597 break;
598 case _PCONF_CHRESTRICT: /* XXX Investigate XXX */
599 ret = 1;
600 break;
601 case _PCONF_NOTRUNC: /* XXX Investigate XXX */
602 case _PCONF_VDISABLE:
603 ret = 0;
604 break;
605 default:
606 ret = -EINVAL;
607 break;
609 unlock_kernel();
610 return ret;
613 asmlinkage int sunos_pathconf(u32 u_path, int name)
615 int ret;
617 lock_kernel();
618 ret = sunos_fpathconf(0, name); /* XXX cheese XXX */
619 unlock_kernel();
620 return ret;
623 /* SunOS mount system call emulation */
624 extern asmlinkage int
625 sys32_select(int n, u32 inp, u32 outp, u32 exp, u32 tvp);
627 struct timeval32
629 int tv_sec, tv_usec;
632 asmlinkage int sunos_select(int width, u32 inp, u32 outp, u32 exp, u32 tvp_x)
634 int ret;
636 /* SunOS binaries expect that select won't change the tvp contents */
637 lock_kernel();
638 current->personality |= STICKY_TIMEOUTS;
639 ret = sys32_select (width, inp, outp, exp, tvp_x);
640 if (ret == -EINTR && tvp_x) {
641 struct timeval32 *tvp = (struct timeval32 *)A(tvp_x);
642 time_t sec, usec;
644 __get_user(sec, &tvp->tv_sec);
645 __get_user(usec, &tvp->tv_usec);
646 if (sec == 0 && usec == 0)
647 ret = 0;
649 unlock_kernel();
650 return ret;
653 asmlinkage void sunos_nop(void)
655 return;
658 /* XXXXXXXXXX SunOS mount/umount. XXXXXXXXXXX */
659 #define SMNT_RDONLY 1
660 #define SMNT_NOSUID 2
661 #define SMNT_NEWTYPE 4
662 #define SMNT_GRPID 8
663 #define SMNT_REMOUNT 16
664 #define SMNT_NOSUB 32
665 #define SMNT_MULTI 64
666 #define SMNT_SYS5 128
668 struct sunos_fh_t {
669 char fh_data [NFS_FHSIZE];
672 struct sunos_nfs_mount_args {
673 struct sockaddr_in *addr; /* file server address */
674 struct nfs_fh *fh; /* File handle to be mounted */
675 int flags; /* flags */
676 int wsize; /* write size in bytes */
677 int rsize; /* read size in bytes */
678 int timeo; /* initial timeout in .1 secs */
679 int retrans; /* times to retry send */
680 char *hostname; /* server's hostname */
681 int acregmin; /* attr cache file min secs */
682 int acregmax; /* attr cache file max secs */
683 int acdirmin; /* attr cache dir min secs */
684 int acdirmax; /* attr cache dir max secs */
685 char *netname; /* server's netname */
688 extern int do_mount(kdev_t, const char *, const char *, char *, int, void *);
689 extern dev_t get_unnamed_dev(void);
690 extern void put_unnamed_dev(dev_t);
691 extern asmlinkage int sys_mount(char *, char *, char *, unsigned long, void *);
692 extern asmlinkage int sys_connect(int fd, struct sockaddr *uservaddr, int addrlen);
693 extern asmlinkage int sys_socket(int family, int type, int protocol);
694 extern asmlinkage int sys_bind(int fd, struct sockaddr *umyaddr, int addrlen);
697 /* Bind the socket on a local reserved port and connect it to the
698 * remote server. This on Linux/i386 is done by the mount program,
699 * not by the kernel.
701 /* XXXXXXXXXXXXXXXXXXXX */
702 static int
703 sunos_nfs_get_server_fd (int fd, struct sockaddr_in *addr)
705 struct sockaddr_in local;
706 struct sockaddr_in server;
707 int try_port;
708 int ret;
709 struct socket *socket;
710 struct dentry *dentry;
711 struct inode *inode;
712 struct file *file;
714 file = fcheck(fd);
715 if(!file)
716 return 0;
718 dentry = file->f_dentry;
719 if(!dentry)
720 return 0;
722 inode = dentry->d_inode;
723 if(!inode)
724 return 0;
726 socket = &inode->u.socket_i;
727 local.sin_family = AF_INET;
728 local.sin_addr.s_addr = INADDR_ANY;
730 /* IPPORT_RESERVED = 1024, can't find the definition in the kernel */
731 try_port = 1024;
732 do {
733 local.sin_port = htons (--try_port);
734 ret = socket->ops->bind(socket, (struct sockaddr*)&local,
735 sizeof(local));
736 } while (ret && try_port > (1024 / 2));
738 if (ret)
739 return 0;
741 server.sin_family = AF_INET;
742 server.sin_addr = addr->sin_addr;
743 server.sin_port = NFS_PORT;
745 /* Call sys_connect */
746 ret = socket->ops->connect (socket, (struct sockaddr *) &server,
747 sizeof (server), file->f_flags);
748 if (ret < 0)
749 return 0;
750 return 1;
753 /* XXXXXXXXXXXXXXXXXXXX */
754 static int get_default (int value, int def_value)
756 if (value)
757 return value;
758 else
759 return def_value;
762 /* XXXXXXXXXXXXXXXXXXXX */
763 asmlinkage int sunos_nfs_mount(char *dir_name, int linux_flags, void *data)
765 int ret = -ENODEV;
766 int server_fd;
767 char *the_name;
768 struct nfs_mount_data linux_nfs_mount;
769 struct sunos_nfs_mount_args *sunos_mount = data;
770 dev_t dev;
772 /* Ok, here comes the fun part: Linux's nfs mount needs a
773 * socket connection to the server, but SunOS mount does not
774 * require this, so we use the information on the destination
775 * address to create a socket and bind it to a reserved
776 * port on this system
778 server_fd = sys_socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
779 if (server_fd < 0)
780 return -ENXIO;
782 if (!sunos_nfs_get_server_fd (server_fd, sunos_mount->addr)){
783 sys_close (server_fd);
784 return -ENXIO;
787 /* Now, bind it to a locally reserved port */
788 linux_nfs_mount.version = NFS_MOUNT_VERSION;
789 linux_nfs_mount.flags = sunos_mount->flags;
790 linux_nfs_mount.addr = *sunos_mount->addr;
791 linux_nfs_mount.root = *sunos_mount->fh;
792 linux_nfs_mount.fd = server_fd;
794 linux_nfs_mount.rsize = get_default (sunos_mount->rsize, 8192);
795 linux_nfs_mount.wsize = get_default (sunos_mount->wsize, 8192);
796 linux_nfs_mount.timeo = get_default (sunos_mount->timeo, 10);
797 linux_nfs_mount.retrans = sunos_mount->retrans;
799 linux_nfs_mount.acregmin = sunos_mount->acregmin;
800 linux_nfs_mount.acregmax = sunos_mount->acregmax;
801 linux_nfs_mount.acdirmin = sunos_mount->acdirmin;
802 linux_nfs_mount.acdirmax = sunos_mount->acdirmax;
804 the_name = getname(sunos_mount->hostname);
805 if(IS_ERR(the_name))
806 return -EFAULT;
808 strncpy (linux_nfs_mount.hostname, the_name, 254);
809 linux_nfs_mount.hostname [255] = 0;
810 putname (the_name);
812 dev = get_unnamed_dev ();
814 ret = do_mount (dev, "", dir_name, "nfs", linux_flags, &linux_nfs_mount);
815 if (ret)
816 put_unnamed_dev(dev);
818 return ret;
821 /* XXXXXXXXXXXXXXXXXXXX */
822 asmlinkage int
823 sunos_mount(char *type, char *dir, int flags, void *data)
825 int linux_flags = MS_MGC_MSK; /* new semantics */
826 int ret = -EINVAL;
827 char *dev_fname = 0;
829 if (!capable (CAP_SYS_ADMIN))
830 return -EPERM;
831 lock_kernel();
832 /* We don't handle the integer fs type */
833 if ((flags & SMNT_NEWTYPE) == 0)
834 goto out;
836 /* Do not allow for those flags we don't support */
837 if (flags & (SMNT_GRPID|SMNT_NOSUB|SMNT_MULTI|SMNT_SYS5))
838 goto out;
840 if(flags & SMNT_REMOUNT)
841 linux_flags |= MS_REMOUNT;
842 if(flags & SMNT_RDONLY)
843 linux_flags |= MS_RDONLY;
844 if(flags & SMNT_NOSUID)
845 linux_flags |= MS_NOSUID;
846 if(strcmp(type, "ext2") == 0) {
847 dev_fname = (char *) data;
848 } else if(strcmp(type, "iso9660") == 0) {
849 dev_fname = (char *) data;
850 } else if(strcmp(type, "minix") == 0) {
851 dev_fname = (char *) data;
852 } else if(strcmp(type, "nfs") == 0) {
853 ret = sunos_nfs_mount (dir, flags, data);
854 goto out;
855 } else if(strcmp(type, "ufs") == 0) {
856 printk("Warning: UFS filesystem mounts unsupported.\n");
857 ret = -ENODEV;
858 goto out;
859 } else if(strcmp(type, "proc")) {
860 ret = -ENODEV;
861 goto out;
863 ret = sys_mount(dev_fname, dir, type, linux_flags, NULL);
864 out:
865 unlock_kernel();
866 return ret;
869 extern asmlinkage int sys_setsid(void);
870 extern asmlinkage int sys_setpgid(pid_t, pid_t);
872 asmlinkage int sunos_setpgrp(pid_t pid, pid_t pgid)
874 int ret;
876 /* So stupid... */
877 lock_kernel();
878 if((!pid || pid == current->pid) &&
879 !pgid) {
880 sys_setsid();
881 ret = 0;
882 } else {
883 ret = sys_setpgid(pid, pgid);
885 unlock_kernel();
886 return ret;
889 /* So stupid... */
890 extern asmlinkage int sys32_wait4(__kernel_pid_t32 pid,
891 u32 stat_addr, int options, u32 ru);
893 asmlinkage int sunos_wait4(__kernel_pid_t32 pid, u32 stat_addr, int options, u32 ru)
895 int ret;
897 lock_kernel();
898 ret = sys32_wait4((pid ? pid : ((__kernel_pid_t32)-1)),
899 stat_addr, options, ru);
900 unlock_kernel();
901 return ret;
904 extern int kill_pg(int, int, int);
905 asmlinkage int sunos_killpg(int pgrp, int sig)
907 int ret;
909 lock_kernel();
910 ret = kill_pg(pgrp, sig, 0);
911 unlock_kernel();
912 return ret;
915 asmlinkage int sunos_audit(void)
917 lock_kernel();
918 printk ("sys_audit\n");
919 unlock_kernel();
920 return -1;
923 extern asmlinkage u32 sunos_gethostid(void)
925 u32 ret;
927 lock_kernel();
928 ret = (((u32)idprom->id_machtype << 24) | ((u32)idprom->id_sernum));
929 unlock_kernel();
930 return ret;
933 /* sysconf options, for SunOS compatibility */
934 #define _SC_ARG_MAX 1
935 #define _SC_CHILD_MAX 2
936 #define _SC_CLK_TCK 3
937 #define _SC_NGROUPS_MAX 4
938 #define _SC_OPEN_MAX 5
939 #define _SC_JOB_CONTROL 6
940 #define _SC_SAVED_IDS 7
941 #define _SC_VERSION 8
943 extern asmlinkage s32 sunos_sysconf (int name)
945 s32 ret;
947 lock_kernel();
948 switch (name){
949 case _SC_ARG_MAX:
950 ret = ARG_MAX;
951 break;
952 case _SC_CHILD_MAX:
953 ret = CHILD_MAX;
954 break;
955 case _SC_CLK_TCK:
956 ret = HZ;
957 break;
958 case _SC_NGROUPS_MAX:
959 ret = NGROUPS_MAX;
960 break;
961 case _SC_OPEN_MAX:
962 ret = OPEN_MAX;
963 break;
964 case _SC_JOB_CONTROL:
965 ret = 1; /* yes, we do support job control */
966 break;
967 case _SC_SAVED_IDS:
968 ret = 1; /* yes, we do support saved uids */
969 break;
970 case _SC_VERSION:
971 /* mhm, POSIX_VERSION is in /usr/include/unistd.h
972 * should it go on /usr/include/linux?
974 ret = 199009;
975 break;
976 default:
977 ret = -1;
978 break;
980 unlock_kernel();
981 return ret;
984 asmlinkage int sunos_semsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 ptr)
986 union semun arg4;
987 int ret;
989 lock_kernel();
990 switch (op) {
991 case 0:
992 /* Most arguments match on a 1:1 basis but cmd doesn't */
993 switch(arg3) {
994 case 4:
995 arg3=GETPID; break;
996 case 5:
997 arg3=GETVAL; break;
998 case 6:
999 arg3=GETALL; break;
1000 case 3:
1001 arg3=GETNCNT; break;
1002 case 7:
1003 arg3=GETZCNT; break;
1004 case 8:
1005 arg3=SETVAL; break;
1006 case 9:
1007 arg3=SETALL; break;
1009 /* sys_semctl(): */
1010 arg4.__pad=(void *)A(ptr); /* value to modify semaphore to */
1011 ret = sys_semctl((int)arg1, (int)arg2, (int)arg3, arg4);
1012 break;
1013 case 1:
1014 /* sys_semget(): */
1015 ret = sys_semget((key_t)arg1, (int)arg2, (int)arg3);
1016 break;
1017 case 2:
1018 /* sys_semop(): */
1019 ret = sys_semop((int)arg1, (struct sembuf *)A(arg2), (unsigned)arg3);
1020 break;
1021 default:
1022 ret = -EINVAL;
1023 break;
1025 unlock_kernel();
1026 return ret;
1029 struct msgbuf32 {
1030 s32 mtype;
1031 char mtext[1];
1034 struct ipc_perm32
1036 key_t key;
1037 __kernel_uid_t32 uid;
1038 __kernel_gid_t32 gid;
1039 __kernel_uid_t32 cuid;
1040 __kernel_gid_t32 cgid;
1041 __kernel_mode_t32 mode;
1042 unsigned short seq;
1045 struct msqid_ds32
1047 struct ipc_perm32 msg_perm;
1048 u32 msg_first;
1049 u32 msg_last;
1050 __kernel_time_t32 msg_stime;
1051 __kernel_time_t32 msg_rtime;
1052 __kernel_time_t32 msg_ctime;
1053 u32 wwait;
1054 u32 rwait;
1055 unsigned short msg_cbytes;
1056 unsigned short msg_qnum;
1057 unsigned short msg_qbytes;
1058 __kernel_ipc_pid_t32 msg_lspid;
1059 __kernel_ipc_pid_t32 msg_lrpid;
1062 static inline int sunos_msqid_get(struct msqid_ds32 *user,
1063 struct msqid_ds *kern)
1065 if(get_user(kern->msg_perm.key, &user->msg_perm.key) ||
1066 __get_user(kern->msg_perm.uid, &user->msg_perm.uid) ||
1067 __get_user(kern->msg_perm.gid, &user->msg_perm.gid) ||
1068 __get_user(kern->msg_perm.cuid, &user->msg_perm.cuid) ||
1069 __get_user(kern->msg_perm.cgid, &user->msg_perm.cgid) ||
1070 __get_user(kern->msg_stime, &user->msg_stime) ||
1071 __get_user(kern->msg_rtime, &user->msg_rtime) ||
1072 __get_user(kern->msg_ctime, &user->msg_ctime) ||
1073 __get_user(kern->msg_ctime, &user->msg_cbytes) ||
1074 __get_user(kern->msg_ctime, &user->msg_qnum) ||
1075 __get_user(kern->msg_ctime, &user->msg_qbytes) ||
1076 __get_user(kern->msg_ctime, &user->msg_lspid) ||
1077 __get_user(kern->msg_ctime, &user->msg_lrpid))
1078 return -EFAULT;
1079 return 0;
1082 static inline int sunos_msqid_put(struct msqid_ds32 *user,
1083 struct msqid_ds *kern)
1085 if(put_user(kern->msg_perm.key, &user->msg_perm.key) ||
1086 __put_user(kern->msg_perm.uid, &user->msg_perm.uid) ||
1087 __put_user(kern->msg_perm.gid, &user->msg_perm.gid) ||
1088 __put_user(kern->msg_perm.cuid, &user->msg_perm.cuid) ||
1089 __put_user(kern->msg_perm.cgid, &user->msg_perm.cgid) ||
1090 __put_user(kern->msg_stime, &user->msg_stime) ||
1091 __put_user(kern->msg_rtime, &user->msg_rtime) ||
1092 __put_user(kern->msg_ctime, &user->msg_ctime) ||
1093 __put_user(kern->msg_ctime, &user->msg_cbytes) ||
1094 __put_user(kern->msg_ctime, &user->msg_qnum) ||
1095 __put_user(kern->msg_ctime, &user->msg_qbytes) ||
1096 __put_user(kern->msg_ctime, &user->msg_lspid) ||
1097 __put_user(kern->msg_ctime, &user->msg_lrpid))
1098 return -EFAULT;
1099 return 0;
1102 static inline int sunos_msgbuf_get(struct msgbuf32 *user, struct msgbuf *kern, int len)
1104 if(get_user(kern->mtype, &user->mtype) ||
1105 __copy_from_user(kern->mtext, &user->mtext, len))
1106 return -EFAULT;
1107 return 0;
1110 static inline int sunos_msgbuf_put(struct msgbuf32 *user, struct msgbuf *kern, int len)
1112 if(put_user(kern->mtype, &user->mtype) ||
1113 __copy_to_user(user->mtext, kern->mtext, len))
1114 return -EFAULT;
1115 return 0;
1118 asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
1120 struct sparc_stackf32 *sp;
1121 struct msqid_ds kds;
1122 struct msgbuf *kmbuf;
1123 mm_segment_t old_fs = get_fs();
1124 u32 arg5;
1125 int rval;
1127 lock_kernel();
1128 switch(op) {
1129 case 0:
1130 rval = sys_msgget((key_t)arg1, (int)arg2);
1131 break;
1132 case 1:
1133 if(!sunos_msqid_get((struct msqid_ds32 *)A(arg3), &kds)) {
1134 set_fs(KERNEL_DS);
1135 rval = sys_msgctl((int)arg1, (int)arg2,
1136 (struct msqid_ds *)A(arg3));
1137 set_fs(old_fs);
1138 if(!rval)
1139 rval = sunos_msqid_put((struct msqid_ds32 *)A(arg3),
1140 &kds);
1141 } else
1142 rval = -EFAULT;
1143 break;
1144 case 2:
1145 rval = -EFAULT;
1146 kmbuf = (struct msgbuf *)kmalloc(sizeof(struct msgbuf) + arg3,
1147 GFP_KERNEL);
1148 if(!kmbuf)
1149 break;
1150 sp = (struct sparc_stackf32 *)
1151 (current->thread.kregs->u_regs[UREG_FP] & 0xffffffffUL);
1152 if(get_user(arg5, &sp->xxargs[0])) {
1153 rval = -EFAULT;
1154 break;
1156 set_fs(KERNEL_DS);
1157 rval = sys_msgrcv((int)arg1, kmbuf, (size_t)arg3,
1158 (long)arg4, (int)arg5);
1159 set_fs(old_fs);
1160 if(!rval)
1161 rval = sunos_msgbuf_put((struct msgbuf32 *)A(arg2),
1162 kmbuf, arg3);
1163 kfree(kmbuf);
1164 break;
1165 case 3:
1166 rval = -EFAULT;
1167 kmbuf = (struct msgbuf *)kmalloc(sizeof(struct msgbuf) + arg3,
1168 GFP_KERNEL);
1169 if(!kmbuf || sunos_msgbuf_get((struct msgbuf32 *)A(arg2),
1170 kmbuf, arg3))
1171 break;
1172 set_fs(KERNEL_DS);
1173 rval = sys_msgsnd((int)arg1, kmbuf, (size_t)arg3, (int)arg4);
1174 set_fs(old_fs);
1175 kfree(kmbuf);
1176 break;
1177 default:
1178 rval = -EINVAL;
1179 break;
1181 unlock_kernel();
1182 return rval;
1185 struct shmid_ds32 {
1186 struct ipc_perm32 shm_perm;
1187 int shm_segsz;
1188 __kernel_time_t32 shm_atime;
1189 __kernel_time_t32 shm_dtime;
1190 __kernel_time_t32 shm_ctime;
1191 __kernel_ipc_pid_t32 shm_cpid;
1192 __kernel_ipc_pid_t32 shm_lpid;
1193 unsigned short shm_nattch;
1196 static inline int sunos_shmid_get(struct shmid_ds32 *user,
1197 struct shmid_ds *kern)
1199 if(get_user(kern->shm_perm.key, &user->shm_perm.key) ||
1200 __get_user(kern->shm_perm.uid, &user->shm_perm.uid) ||
1201 __get_user(kern->shm_perm.gid, &user->shm_perm.gid) ||
1202 __get_user(kern->shm_perm.cuid, &user->shm_perm.cuid) ||
1203 __get_user(kern->shm_perm.cgid, &user->shm_perm.cgid) ||
1204 __get_user(kern->shm_segsz, &user->shm_segsz) ||
1205 __get_user(kern->shm_atime, &user->shm_atime) ||
1206 __get_user(kern->shm_dtime, &user->shm_dtime) ||
1207 __get_user(kern->shm_ctime, &user->shm_ctime) ||
1208 __get_user(kern->shm_cpid, &user->shm_cpid) ||
1209 __get_user(kern->shm_lpid, &user->shm_lpid) ||
1210 __get_user(kern->shm_nattch, &user->shm_nattch))
1211 return -EFAULT;
1212 return 0;
1215 static inline int sunos_shmid_put(struct shmid_ds32 *user,
1216 struct shmid_ds *kern)
1218 if(put_user(kern->shm_perm.key, &user->shm_perm.key) ||
1219 __put_user(kern->shm_perm.uid, &user->shm_perm.uid) ||
1220 __put_user(kern->shm_perm.gid, &user->shm_perm.gid) ||
1221 __put_user(kern->shm_perm.cuid, &user->shm_perm.cuid) ||
1222 __put_user(kern->shm_perm.cgid, &user->shm_perm.cgid) ||
1223 __put_user(kern->shm_segsz, &user->shm_segsz) ||
1224 __put_user(kern->shm_atime, &user->shm_atime) ||
1225 __put_user(kern->shm_dtime, &user->shm_dtime) ||
1226 __put_user(kern->shm_ctime, &user->shm_ctime) ||
1227 __put_user(kern->shm_cpid, &user->shm_cpid) ||
1228 __put_user(kern->shm_lpid, &user->shm_lpid) ||
1229 __put_user(kern->shm_nattch, &user->shm_nattch))
1230 return -EFAULT;
1231 return 0;
1234 asmlinkage int sunos_shmsys(int op, u32 arg1, u32 arg2, u32 arg3)
1236 struct shmid_ds ksds;
1237 unsigned long raddr;
1238 mm_segment_t old_fs = get_fs();
1239 int rval;
1241 lock_kernel();
1242 switch(op) {
1243 case 0:
1244 /* sys_shmat(): attach a shared memory area */
1245 rval = sys_shmat((int)arg1,(char *)A(arg2),(int)arg3,&raddr);
1246 if(!rval)
1247 rval = (int) raddr;
1248 break;
1249 case 1:
1250 /* sys_shmctl(): modify shared memory area attr. */
1251 if(!sunos_shmid_get((struct shmid_ds32 *)A(arg3), &ksds)) {
1252 set_fs(KERNEL_DS);
1253 rval = sys_shmctl((int)arg1,(int)arg2, &ksds);
1254 set_fs(old_fs);
1255 if(!rval)
1256 rval = sunos_shmid_put((struct shmid_ds32 *)A(arg3),
1257 &ksds);
1258 } else
1259 rval = -EFAULT;
1260 break;
1261 case 2:
1262 /* sys_shmdt(): detach a shared memory area */
1263 rval = sys_shmdt((char *)A(arg1));
1264 break;
1265 case 3:
1266 /* sys_shmget(): get a shared memory area */
1267 rval = sys_shmget((key_t)arg1,(int)arg2,(int)arg3);
1268 break;
1269 default:
1270 rval = -EINVAL;
1271 break;
1273 unlock_kernel();
1274 return rval;
1277 asmlinkage int sunos_open(u32 filename, int flags, int mode)
1279 int ret;
1281 lock_kernel();
1282 current->personality |= PER_BSD;
1283 ret = sys_open ((char *)A(filename), flags, mode);
1284 unlock_kernel();
1285 return ret;
1288 #define SUNOS_EWOULDBLOCK 35
1290 /* see the sunos man page read(2v) for an explanation
1291 of this garbage. We use O_NDELAY to mark
1292 file descriptors that have been set non-blocking
1293 using 4.2BSD style calls. (tridge) */
1295 static inline int check_nonblock(int ret, int fd)
1297 if (ret == -EAGAIN) {
1298 struct file * file = fcheck(fd);
1299 if (file && (file->f_flags & O_NDELAY))
1300 ret = -SUNOS_EWOULDBLOCK;
1302 return ret;
1305 extern asmlinkage int sys_read(unsigned int fd, char *buf, unsigned long count);
1306 extern asmlinkage int sys_write(unsigned int fd, char *buf, unsigned long count);
1307 extern asmlinkage int sys_recv(int fd, void *ubuf, size_t size, unsigned flags);
1308 extern asmlinkage int sys_send(int fd, void *buff, size_t len, unsigned flags);
1309 extern asmlinkage int sys_accept(int fd, struct sockaddr *sa, int *addrlen);
1310 extern asmlinkage int sys32_readv(u32 fd, u32 vector, s32 count);
1311 extern asmlinkage int sys32_writev(u32 fd, u32 vector, s32 count);
1313 asmlinkage int sunos_read(unsigned int fd, u32 buf, u32 count)
1315 int ret;
1317 lock_kernel();
1318 ret = check_nonblock(sys_read(fd, (char *)A(buf), count), fd);
1319 unlock_kernel();
1320 return ret;
1323 asmlinkage int sunos_readv(u32 fd, u32 vector, s32 count)
1325 int ret;
1327 lock_kernel();
1328 ret = check_nonblock(sys32_readv(fd, vector, count), fd);
1329 unlock_kernel();
1330 return ret;
1333 asmlinkage int sunos_write(unsigned int fd, u32 buf, u32 count)
1335 int ret;
1337 lock_kernel();
1338 ret = check_nonblock(sys_write(fd, (char *)A(buf), count), fd);
1339 unlock_kernel();
1340 return ret;
1343 asmlinkage int sunos_writev(u32 fd, u32 vector, s32 count)
1345 int ret;
1347 lock_kernel();
1348 ret = check_nonblock(sys32_writev(fd, vector, count), fd);
1349 unlock_kernel();
1350 return ret;
1353 asmlinkage int sunos_recv(int fd, u32 ubuf, int size, unsigned flags)
1355 int ret;
1357 lock_kernel();
1358 ret = check_nonblock(sys_recv(fd, (void *)A(ubuf), size, flags), fd);
1359 unlock_kernel();
1360 return ret;
1363 asmlinkage int sunos_send(int fd, u32 buff, int len, unsigned flags)
1365 int ret;
1367 lock_kernel();
1368 ret = check_nonblock(sys_send(fd, (void *)A(buff), len, flags), fd);
1369 unlock_kernel();
1370 return ret;
1373 extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
1374 char *optval, int optlen);
1376 asmlinkage int sunos_socket(int family, int type, int protocol)
1378 int ret, one = 1;
1380 lock_kernel();
1381 ret = sys_socket(family, type, protocol);
1382 if (ret < 0)
1383 goto out;
1385 sys_setsockopt(ret, SOL_SOCKET, SO_BSDCOMPAT,
1386 (char *)&one, sizeof(one));
1387 out:
1388 unlock_kernel();
1389 return ret;
1392 asmlinkage int sunos_accept(int fd, u32 sa, u32 addrlen)
1394 int ret, one = 1;
1396 lock_kernel();
1397 while (1) {
1398 ret = check_nonblock(sys_accept(fd, (struct sockaddr *)A(sa),
1399 (int *)A(addrlen)), fd);
1400 if (ret != -ENETUNREACH && ret != -EHOSTUNREACH)
1401 break;
1403 if (ret < 0)
1404 goto out;
1406 sys_setsockopt(ret, SOL_SOCKET, SO_BSDCOMPAT,
1407 (char *)&one, sizeof(one));
1408 out:
1409 unlock_kernel();
1410 return ret;
1413 #define SUNOS_SV_INTERRUPT 2
1415 asmlinkage int sunos_sigaction (int sig, u32 act, u32 oact)
1417 struct k_sigaction new_ka, old_ka;
1418 int ret;
1420 current->personality |= PER_BSD;
1422 if (act) {
1423 old_sigset_t32 mask;
1425 if (get_user((long)new_ka.sa.sa_handler, &((struct old_sigaction32 *)A(act))->sa_handler) ||
1426 __get_user(new_ka.sa.sa_flags, &((struct old_sigaction32 *)A(act))->sa_flags))
1427 return -EFAULT;
1428 __get_user(mask, &((struct old_sigaction32 *)A(act))->sa_mask);
1429 new_ka.sa.sa_restorer = NULL;
1430 new_ka.ka_restorer = NULL;
1431 siginitset(&new_ka.sa.sa_mask, mask);
1432 new_ka.sa.sa_flags ^= SUNOS_SV_INTERRUPT;
1435 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
1437 if (!ret && oact) {
1438 old_ka.sa.sa_flags ^= SUNOS_SV_INTERRUPT;
1439 if (put_user((long)old_ka.sa.sa_handler, &((struct old_sigaction32 *)A(oact))->sa_handler) ||
1440 __put_user(old_ka.sa.sa_flags, &((struct old_sigaction32 *)A(oact))->sa_flags))
1441 return -EFAULT;
1442 __put_user(old_ka.sa.sa_mask.sig[0], &((struct old_sigaction32 *)A(oact))->sa_mask);
1445 return ret;
1448 extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
1449 char *optval, int optlen);
1450 extern asmlinkage int sys32_getsockopt(int fd, int level, int optname,
1451 u32 optval, u32 optlen);
1453 asmlinkage int sunos_setsockopt(int fd, int level, int optname, u32 optval,
1454 int optlen)
1456 int tr_opt = optname;
1457 int ret;
1459 lock_kernel();
1460 if (level == SOL_IP) {
1461 /* Multicast socketopts (ttl, membership) */
1462 if (tr_opt >=2 && tr_opt <= 6)
1463 tr_opt += 30;
1465 ret = sys_setsockopt(fd, level, tr_opt, (char *)A(optval), optlen);
1466 unlock_kernel();
1467 return ret;
1470 asmlinkage int sunos_getsockopt(int fd, int level, int optname,
1471 u32 optval, u32 optlen)
1473 int tr_opt = optname;
1474 int ret;
1476 lock_kernel();
1477 if (level == SOL_IP) {
1478 /* Multicast socketopts (ttl, membership) */
1479 if (tr_opt >=2 && tr_opt <= 6)
1480 tr_opt += 30;
1482 ret = sys32_getsockopt(fd, level, tr_opt, optval, optlen);
1483 unlock_kernel();
1484 return ret;