ultrix_misc.c revision 1.44 1 /* $NetBSD: ultrix_misc.c,v 1.44 1998/09/26 16:24:14 drochner Exp $ */
2
3 /*
4 * Copyright (c) 1995, 1997 Jonathan Stone (hereinafter referred to as the author)
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Jonathan Stone for
18 * the NetBSD Project.
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35 /*
36 * Copyright (c) 1992, 1993
37 * The Regents of the University of California. All rights reserved.
38 *
39 * This software was developed by the Computer Systems Engineering group
40 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
41 * contributed to Berkeley.
42 *
43 * All advertising materials mentioning features or use of this software
44 * must display the following acknowledgement:
45 * This product includes software developed by the University of
46 * California, Lawrence Berkeley Laboratory.
47 *
48 * Redistribution and use in source and binary forms, with or without
49 * modification, are permitted provided that the following conditions
50 * are met:
51 * 1. Redistributions of source code must retain the above copyright
52 * notice, this list of conditions and the following disclaimer.
53 * 2. Redistributions in binary form must reproduce the above copyright
54 * notice, this list of conditions and the following disclaimer in the
55 * documentation and/or other materials provided with the distribution.
56 * 3. All advertising materials mentioning features or use of this software
57 * must display the following acknowledgement:
58 * This product includes software developed by the University of
59 * California, Berkeley and its contributors.
60 * 4. Neither the name of the University nor the names of its contributors
61 * may be used to endorse or promote products derived from this software
62 * without specific prior written permission.
63 *
64 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
65 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
66 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
67 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
68 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
69 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
70 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
71 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
72 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
73 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
74 * SUCH DAMAGE.
75 *
76 *
77 * @(#)sun_misc.c 8.1 (Berkeley) 6/18/93
78 *
79 * from: Header: sun_misc.c,v 1.16 93/04/07 02:46:27 torek Exp
80 */
81
82 #include "opt_nfsserver.h"
83
84 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
85
86 __KERNEL_RCSID(0, "$NetBSD: ultrix_misc.c,v 1.44 1998/09/26 16:24:14 drochner Exp $");
87
88 /*
89 * SunOS compatibility module.
90 *
91 * SunOS system calls that are implemented differently in BSD are
92 * handled here.
93 */
94
95 #include "fs_nfs.h"
96
97 #include <sys/param.h>
98 #include <sys/systm.h>
99 #include <sys/namei.h>
100 #include <sys/dirent.h>
101 #include <sys/proc.h>
102 #include <sys/file.h>
103 #include <sys/filedesc.h>
104 /*#include <sys/stat.h>*/
105 /*#include <sys/ioctl.h>*/
106 #include <sys/kernel.h>
107 #include <sys/exec.h>
108 #include <sys/malloc.h>
109 #include <sys/mbuf.h>
110 #include <sys/mman.h>
111 #include <sys/mount.h>
112 #include <sys/resource.h>
113 #include <sys/resourcevar.h>
114 #include <sys/signal.h>
115 #include <sys/signalvar.h>
116 #include <sys/socket.h>
117 #include <sys/vnode.h>
118 #include <sys/uio.h>
119 #include <sys/wait.h>
120 #include <sys/utsname.h>
121 #include <sys/unistd.h>
122 #include <sys/ipc.h>
123
124 #include <sys/syscallargs.h>
125
126 #include <compat/ultrix/ultrix_syscall.h>
127 #include <compat/ultrix/ultrix_syscallargs.h>
128 #include <compat/common/compat_util.h>
129
130 #include <netinet/in.h>
131
132 #include <miscfs/specfs/specdev.h>
133
134 #include <nfs/rpcv2.h>
135 #include <nfs/nfsproto.h>
136 #include <nfs/nfs.h>
137
138 #include <vm/vm.h> /* pmap declarations */
139
140 #include <sys/conf.h> /* iszerodev() */
141 #include <sys/socketvar.h> /* sosetopt() */
142
143
144 extern struct sysent ultrix_sysent[];
145 extern char *ultrix_syscallnames[];
146
147
148 /*
149 * Select the appropriate setregs callback for the target architecture.
150 */
151 #ifdef mips
152 #include <machine/ecoff_machdep.h>
153 #define ULTRIX_EXEC_SETREGS cpu_exec_ecoff_setregs
154 #endif /* mips */
155
156 #ifdef vax
157 #define ULTRIX_EXEC_SETREGS setregs
158 #endif /* mips */
159
160
161 extern void ULTRIX_EXEC_SETREGS __P((struct proc *, struct exec_package *,
162 u_long));
163 extern char sigcode[], esigcode[];
164
165 struct emul emul_ultrix = {
166 "ultrix",
167 NULL,
168 sendsig,
169 ULTRIX_SYS_syscall,
170 ULTRIX_SYS_MAXSYSCALL,
171 ultrix_sysent,
172 ultrix_syscallnames,
173 0,
174 copyargs,
175 ULTRIX_EXEC_SETREGS,
176 sigcode,
177 esigcode,
178 };
179
180 #define GSI_PROG_ENV 1
181
182 int
183 ultrix_sys_getsysinfo(p, v, retval)
184 struct proc *p;
185 void *v;
186 register_t *retval;
187 {
188 struct ultrix_sys_getsysinfo_args *uap = v;
189 static short progenv = 0;
190
191 switch (SCARG(uap, op)) {
192 /* operations implemented: */
193 case GSI_PROG_ENV:
194 if (SCARG(uap, nbytes) < sizeof(short))
195 return EINVAL;
196 *retval = 1;
197 return (copyout(&progenv, SCARG(uap, buffer), sizeof(short)));
198 default:
199 *retval = 0; /* info unavail */
200 return 0;
201 }
202 }
203
204 int
205 ultrix_sys_setsysinfo(p, v, retval)
206 struct proc *p;
207 void *v;
208 register_t *retval;
209 {
210
211 #ifdef notyet
212 struct ultrix_sys_setsysinfo_args *uap = v;
213 #endif
214
215 *retval = 0;
216 return 0;
217 }
218
219 int
220 ultrix_sys_waitpid(p, v, retval)
221 struct proc *p;
222 void *v;
223 register_t *retval;
224 {
225 struct ultrix_sys_waitpid_args *uap = v;
226 struct sys_wait4_args ua;
227
228 SCARG(&ua, pid) = SCARG(uap, pid);
229 SCARG(&ua, status) = SCARG(uap, status);
230 SCARG(&ua, options) = SCARG(uap, options);
231 SCARG(&ua, rusage) = 0;
232
233 return (sys_wait4(p, &ua, retval));
234 }
235
236 int
237 ultrix_sys_wait3(p, v, retval)
238 struct proc *p;
239 void *v;
240 register_t *retval;
241 {
242 struct ultrix_sys_wait3_args *uap = v;
243 struct sys_wait4_args ua;
244
245 SCARG(&ua, pid) = -1;
246 SCARG(&ua, status) = SCARG(uap, status);
247 SCARG(&ua, options) = SCARG(uap, options);
248 SCARG(&ua, rusage) = SCARG(uap, rusage);
249
250 return (sys_wait4(p, &ua, retval));
251 }
252
253 /*
254 * Ultrix binaries pass in FD_MAX as the first arg to select().
255 * On Ultrix, FD_MAX is 4096, which is more than the NetBSD sys_select()
256 * can handle.
257 * Since we can't have more than the (native) FD_MAX descriptors open,
258 * limit nfds to at most FD_MAX.
259 */
260 int
261 ultrix_sys_select(p, v, retval)
262 struct proc *p;
263 void *v;
264 register_t *retval;
265 {
266 struct sys_select_args *uap = v;
267 struct timeval atv;
268 int error;
269
270 /* Limit number of FDs selected on to the native maximum */
271
272 if (SCARG(uap, nd) > FD_SETSIZE)
273 SCARG(uap, nd) = FD_SETSIZE;
274
275 /* Check for negative timeval */
276 if (SCARG(uap, tv)) {
277 error = copyin((caddr_t)SCARG(uap, tv), (caddr_t)&atv,
278 sizeof(atv));
279 if (error)
280 goto done;
281 #ifdef DEBUG
282 /* Ultrix clients sometimes give negative timeouts? */
283 if (atv.tv_sec < 0 || atv.tv_usec < 0)
284 printf("ultrix select( %ld, %ld): negative timeout\n",
285 atv.tv_sec, atv.tv_usec);
286 /*tvp = (timeval *)STACKGAPBASE;*/
287 #endif
288
289 }
290 error = sys_select(p, (void*) uap, retval);
291 if (error == EINVAL)
292 printf("ultrix select: bad args?\n");
293
294 done:
295 return error;
296 }
297
298 #if defined(NFS)
299 int
300 async_daemon(p, v, retval)
301 struct proc *p;
302 void *v;
303 register_t *retval;
304 {
305 struct sys_nfssvc_args ouap;
306
307 SCARG(&ouap, flag) = NFSSVC_BIOD;
308 SCARG(&ouap, argp) = NULL;
309
310 return (sys_nfssvc(p, &ouap, retval));
311 }
312 #endif /* NFS */
313
314
315 #define SUN__MAP_NEW 0x80000000 /* if not, old mmap & cannot handle */
316
317 int
318 ultrix_sys_mmap(p, v, retval)
319 register struct proc *p;
320 void *v;
321 register_t *retval;
322 {
323 register struct ultrix_sys_mmap_args *uap = v;
324 struct sys_mmap_args ouap;
325 register struct filedesc *fdp;
326 register struct file *fp;
327 register struct vnode *vp;
328
329 /*
330 * Verify the arguments.
331 */
332 if (SCARG(uap, prot) & ~(PROT_READ|PROT_WRITE|PROT_EXEC))
333 return (EINVAL); /* XXX still needed? */
334
335 if ((SCARG(uap, flags) & SUN__MAP_NEW) == 0)
336 return (EINVAL);
337
338 SCARG(&ouap, flags) = SCARG(uap, flags) & ~SUN__MAP_NEW;
339 SCARG(&ouap, addr) = SCARG(uap, addr);
340
341 if ((SCARG(&ouap, flags) & MAP_FIXED) == 0 &&
342 SCARG(&ouap, addr) != 0 &&
343 SCARG(&ouap, addr) < (void *)round_page(p->p_vmspace->vm_daddr+MAXDSIZ))
344 SCARG(&ouap, addr) = (void *)round_page(p->p_vmspace->vm_daddr+MAXDSIZ);
345
346 SCARG(&ouap, len) = SCARG(uap, len);
347 SCARG(&ouap, prot) = SCARG(uap, prot);
348 SCARG(&ouap, fd) = SCARG(uap, fd);
349 SCARG(&ouap, pos) = SCARG(uap, pos);
350
351 /*
352 * Special case: if fd refers to /dev/zero, map as MAP_ANON. (XXX)
353 */
354 fdp = p->p_fd;
355 if ((unsigned)SCARG(&ouap, fd) < fdp->fd_nfiles && /*XXX*/
356 (fp = fdp->fd_ofiles[SCARG(&ouap, fd)]) != NULL && /*XXX*/
357 fp->f_type == DTYPE_VNODE && /*XXX*/
358 (vp = (struct vnode *)fp->f_data)->v_type == VCHR && /*XXX*/
359 iszerodev(vp->v_rdev)) { /*XXX*/
360 SCARG(&ouap, flags) |= MAP_ANON;
361 SCARG(&ouap, fd) = -1;
362 }
363
364 return (sys_mmap(p, &ouap, retval));
365 }
366
367 int
368 ultrix_sys_setsockopt(p, v, retval)
369 struct proc *p;
370 void *v;
371 register_t *retval;
372 {
373 register struct ultrix_sys_setsockopt_args *uap = v;
374 struct file *fp;
375 struct mbuf *m = NULL;
376 int error;
377
378 if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
379 return (error);
380 #define SO_DONTLINGER (~SO_LINGER)
381 if (SCARG(uap, name) == SO_DONTLINGER) {
382 m = m_get(M_WAIT, MT_SOOPTS);
383 mtod(m, struct linger *)->l_onoff = 0;
384 m->m_len = sizeof(struct linger);
385 return (sosetopt((struct socket *)fp->f_data, SCARG(uap, level),
386 SO_LINGER, m));
387 }
388 if (SCARG(uap, level) == IPPROTO_IP) {
389 #define EMUL_IP_MULTICAST_IF 2
390 #define EMUL_IP_MULTICAST_TTL 3
391 #define EMUL_IP_MULTICAST_LOOP 4
392 #define EMUL_IP_ADD_MEMBERSHIP 5
393 #define EMUL_IP_DROP_MEMBERSHIP 6
394 static int ipoptxlat[] = {
395 IP_MULTICAST_IF,
396 IP_MULTICAST_TTL,
397 IP_MULTICAST_LOOP,
398 IP_ADD_MEMBERSHIP,
399 IP_DROP_MEMBERSHIP
400 };
401 if (SCARG(uap, name) >= EMUL_IP_MULTICAST_IF &&
402 SCARG(uap, name) <= EMUL_IP_DROP_MEMBERSHIP) {
403 SCARG(uap, name) =
404 ipoptxlat[SCARG(uap, name) - EMUL_IP_MULTICAST_IF];
405 }
406 }
407 if (SCARG(uap, valsize) > MLEN)
408 return (EINVAL);
409 if (SCARG(uap, val)) {
410 m = m_get(M_WAIT, MT_SOOPTS);
411 error = copyin(SCARG(uap, val), mtod(m, caddr_t),
412 (u_int)SCARG(uap, valsize));
413 if (error) {
414 (void) m_free(m);
415 return (error);
416 }
417 m->m_len = SCARG(uap, valsize);
418 }
419 return (sosetopt((struct socket *)fp->f_data, SCARG(uap, level),
420 SCARG(uap, name), m));
421 }
422
423 struct ultrix_utsname {
424 char sysname[9];
425 char nodename[9];
426 char nodeext[65-9];
427 char release[9];
428 char version[9];
429 char machine[9];
430 };
431
432 int
433 ultrix_sys_uname(p, v, retval)
434 struct proc *p;
435 void *v;
436 register_t *retval;
437 {
438 struct ultrix_sys_uname_args *uap = v;
439 struct ultrix_utsname sut;
440 extern char ostype[], machine[], osrelease[];
441
442 memset(&sut, 0, sizeof(sut));
443
444 memcpy(sut.sysname, ostype, sizeof(sut.sysname) - 1);
445 memcpy(sut.nodename, hostname, sizeof(sut.nodename));
446 sut.nodename[sizeof(sut.nodename)-1] = '\0';
447 memcpy(sut.release, osrelease, sizeof(sut.release) - 1);
448 memcpy(sut.version, "1", sizeof(sut.version) - 1);
449 memcpy(sut.machine, machine, sizeof(sut.machine) - 1);
450
451 return copyout((caddr_t)&sut, (caddr_t)SCARG(uap, name),
452 sizeof(struct ultrix_utsname));
453 }
454
455 int
456 ultrix_sys_setpgrp(p, v, retval)
457 struct proc *p;
458 void *v;
459 register_t *retval;
460 {
461 struct ultrix_sys_setpgrp_args *uap = v;
462
463 /*
464 * difference to our setpgid call is to include backwards
465 * compatibility to pre-setsid() binaries. Do setsid()
466 * instead of setpgid() in those cases where the process
467 * tries to create a new session the old way.
468 */
469 if (!SCARG(uap, pgid) &&
470 (!SCARG(uap, pid) || SCARG(uap, pid) == p->p_pid))
471 return sys_setsid(p, uap, retval);
472 else
473 return sys_setpgid(p, uap, retval);
474 }
475
476 #if defined (NFSSERVER)
477 int
478 ultrix_sys_nfssvc(p, v, retval)
479 struct proc *p;
480 void *v;
481 register_t *retval;
482 {
483
484 #if 0 /* XXX */
485 struct ultrix_sys_nfssvc_args *uap = v;
486 struct emul *e = p->p_emul;
487 struct sys_nfssvc_args outuap;
488 struct sockaddr sa;
489 int error;
490
491 memset(&outuap, 0, sizeof outuap);
492 SCARG(&outuap, fd) = SCARG(uap, fd);
493 SCARG(&outuap, mskval) = STACKGAPBASE;
494 SCARG(&outuap, msklen) = sizeof sa;
495 SCARG(&outuap, mtchval) = outuap.mskval + sizeof sa;
496 SCARG(&outuap, mtchlen) = sizeof sa;
497
498 memset(&sa, 0, sizeof sa);
499 if (error = copyout(&sa, SCARG(&outuap, mskval), SCARG(&outuap, msklen)))
500 return (error);
501 if (error = copyout(&sa, SCARG(&outuap, mtchval), SCARG(&outuap, mtchlen)))
502 return (error);
503
504 return nfssvc(p, &outuap, retval);
505 #else
506 return (ENOSYS);
507 #endif
508 }
509 #endif /* NFSSERVER */
510
511 struct ultrix_ustat {
512 daddr_t f_tfree; /* total free */
513 ino_t f_tinode; /* total inodes free */
514 char f_fname[6]; /* filsys name */
515 char f_fpack[6]; /* filsys pack name */
516 };
517
518 int
519 ultrix_sys_ustat(p, v, retval)
520 struct proc *p;
521 void *v;
522 register_t *retval;
523 {
524 struct ultrix_sys_ustat_args *uap = v;
525 struct ultrix_ustat us;
526 int error;
527
528 memset(&us, 0, sizeof us);
529
530 /*
531 * XXX: should set f_tfree and f_tinode at least
532 * How do we translate dev -> fstat? (and then to ultrix_ustat)
533 */
534
535 if ((error = copyout(&us, SCARG(uap, buf), sizeof us)) != 0)
536 return (error);
537 return 0;
538 }
539
540 int
541 ultrix_sys_quotactl(p, v, retval)
542 struct proc *p;
543 void *v;
544 register_t *retval;
545 {
546
547 #ifdef notyet
548 struct ultrix_sys_quotactl_args *uap = v;
549 #endif
550
551 return EINVAL;
552 }
553
554 int
555 ultrix_sys_vhangup(p, v, retval)
556 struct proc *p;
557 void *v;
558 register_t *retval;
559 {
560
561 return 0;
562 }
563
564
565 /*
566 * RISC Ultrix cache control syscalls
567 */
568 #ifdef __mips
569 int
570 ultrix_sys_cacheflush(p, v, retval)
571 register struct proc *p;
572 void *v;
573 register_t *retval;
574 {
575 register struct ultrix_sys_cacheflush_args /* {
576 syscallarg(void *) addr;
577 syscallarg(int) nbytes;
578 syscallarg(int) flag;
579 } */ *uap = v;
580 register vaddr_t va = (vaddr_t)SCARG(uap, addr);
581 register int nbytes = SCARG(uap, nbytes);
582 register int whichcache = SCARG(uap, whichcache);
583
584 return (mips_user_cacheflush(p, va, nbytes, whichcache));
585 }
586
587
588 int
589 ultrix_sys_cachectl(p, v, retval)
590 register struct proc *p;
591 void *v;
592 register_t *retval;
593 {
594 register struct ultrix_sys_cachectl_args /* {
595 syscallarg(void *) addr;
596 syscallarg(int) nbytes;
597 syscallarg(int) cacheop;
598 } */ *uap = v;
599 register vaddr_t va = (vaddr_t)SCARG(uap, addr);
600 register int nbytes = SCARG(uap, nbytes);
601 register int cacheop = SCARG(uap, cacheop);
602
603 return mips_user_cachectl(p, va, nbytes, cacheop);
604 }
605
606 #endif /* __mips */
607
608
609 int
610 ultrix_sys_exportfs(p, v, retval)
611 struct proc *p;
612 void *v;
613 register_t *retval;
614 {
615 #ifdef notyet
616 struct ultrix_sys_exportfs_args *uap = v;
617 #endif
618
619 /*
620 * XXX: should perhaps translate into a mount(2)
621 * with MOUNT_EXPORT?
622 */
623 return 0;
624 }
625
626 int
627 ultrix_sys_sigpending(p, v, retval)
628 struct proc *p;
629 void *v;
630 register_t *retval;
631 {
632 struct ultrix_sys_sigpending_args *uap = v;
633 sigset_t ss;
634 int mask;
635
636 sigpending1(p, &ss);
637 mask = ss.__bits[0];
638
639 return (copyout((caddr_t)&mask, (caddr_t)SCARG(uap, mask), sizeof(int)));
640 }
641
642 int
643 ultrix_sys_sigreturn(p, v, retval)
644 struct proc *p;
645 void *v;
646 register_t *retval;
647 {
648 struct ultrix_sys_sigreturn_args *uap = v;
649
650 /*
651 * XXX That's broken; the Ultrix sigcontext differs
652 * XXX from NetBSD's.
653 */
654 return (sys___sigreturn14(p, uap, retval));
655 }
656
657 int
658 ultrix_sys_sigcleanup(p, v, retval)
659 struct proc *p;
660 void *v;
661 register_t *retval;
662 {
663 struct ultrix_sys_sigcleanup_args *uap = v;
664
665 /*
666 * XXX That's broken; the Ultrix sigcontext differs
667 * XXX from NetBSD's.
668 */
669 return (sys___sigreturn14(p, uap, retval));
670 }
671
672 int
673 ultrix_sys_sigsuspend(p, v, retval)
674 struct proc *p;
675 void *v;
676 register_t *retval;
677 {
678 struct ultrix_sys_sigsuspend_args *uap = v;
679 int mask = SCARG(uap, mask);
680 sigset_t ss;
681
682 ss.__bits[0] = mask;
683 ss.__bits[1] = 0;
684 ss.__bits[2] = 0;
685 ss.__bits[3] = 0;
686
687 return (sigsuspend1(p, &ss));
688 }
689
690
691 int
692 ultrix_sys_shmsys(p, v, retval)
693 struct proc *p;
694 void *v;
695 register_t *retval;
696 {
697
698 #ifdef SYSVSHM
699
700 /* Ultrix SVSHM weirndess: */
701 struct ultrix_sys_shmsys_args *uap = v;
702 struct sys_shmat_args shmat_args;
703 struct sys_shmctl_args shmctl_args;
704 struct sys_shmdt_args shmdt_args;
705 struct sys_shmget_args shmget_args;
706
707
708 switch (SCARG(uap, shmop)) {
709 case 0: /* Ultrix shmat() */
710 SCARG(&shmat_args, shmid) = SCARG(uap, a2);
711 SCARG(&shmat_args, shmaddr) = (void *)SCARG(uap, a3);
712 SCARG(&shmat_args, shmflg) = SCARG(uap, a4);
713 return (sys_shmat(p, &shmat_args, retval));
714
715 case 1: /* Ultrix shmctl() */
716 SCARG(&shmctl_args, shmid) = SCARG(uap, a2);
717 SCARG(&shmctl_args, cmd) = SCARG(uap, a3);
718 SCARG(&shmctl_args, buf) = (struct shmid_ds *)SCARG(uap, a4);
719 return (sys_shmctl(p, &shmctl_args, retval));
720
721 case 2: /* Ultrix shmdt() */
722 SCARG(&shmat_args, shmaddr) = (void *)SCARG(uap, a2);
723 return (sys_shmdt(p, &shmdt_args, retval));
724
725 case 3: /* Ultrix shmget() */
726 SCARG(&shmget_args, key) = SCARG(uap, a2);
727 SCARG(&shmget_args, size) = SCARG(uap, a3);
728 SCARG(&shmget_args, shmflg) = SCARG(uap, a4)
729 & (IPC_CREAT|IPC_EXCL|IPC_NOWAIT);
730 return (sys_shmget(p, &shmget_args, retval));
731
732 default:
733 return (EINVAL);
734 }
735 #else
736 return (EOPNOTSUPP);
737 #endif /* SYSVSHM */
738 }
739