1 /* $NetBSD: ultrix_misc.c,v 1.117 2008/11/19 18:36:06 ad Exp $ */
4 * Copyright (c) 1995, 1997 Jonathan Stone (hereinafter referred to as the author)
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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
36 * Copyright (c) 1992, 1993
37 * The Regents of the University of California. All rights reserved.
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.
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.
48 * Redistribution and use in source and binary forms, with or without
49 * modification, are permitted provided that the following conditions
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. Neither the name of the University nor the names of its contributors
57 * may be used to endorse or promote products derived from this software
58 * without specific prior written permission.
60 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
61 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
62 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
63 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
64 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
65 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
66 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
67 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
68 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
69 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
73 * @(#)sun_misc.c 8.1 (Berkeley) 6/18/93
75 * from: Header: sun_misc.c,v 1.16 93/04/07 02:46:27 torek Exp
78 #include <sys/cdefs.h>
79 __KERNEL_RCSID(0, "$NetBSD: ultrix_misc.c,v 1.117 2008/11/19 18:36:06 ad Exp $");
81 #if defined(_KERNEL_OPT)
85 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
88 * Ultrix compatibility module.
90 * Ultrix system calls that are implemented differently in BSD are
94 #if defined(_KERNEL_OPT)
98 #include <sys/param.h>
99 #include <sys/systm.h>
100 #include <sys/namei.h>
101 #include <sys/dirent.h>
102 #include <sys/proc.h>
103 #include <sys/file.h>
104 #include <sys/filedesc.h>
105 #include <sys/kernel.h>
106 #include <sys/exec.h>
107 #include <sys/malloc.h>
108 #include <sys/mbuf.h>
109 #include <sys/mman.h>
110 #include <sys/mount.h>
111 #include <sys/resource.h>
112 #include <sys/resourcevar.h>
113 #include <sys/signal.h>
114 #include <sys/signalvar.h>
115 #include <sys/socket.h>
116 #include <sys/vnode.h>
118 #include <sys/wait.h>
119 #include <sys/utsname.h>
120 #include <sys/unistd.h>
123 #include <sys/syscallargs.h>
125 #include <uvm/uvm_extern.h>
127 #include <compat/ultrix/ultrix_syscall.h>
128 #include <compat/ultrix/ultrix_syscallargs.h>
129 #include <compat/common/compat_util.h>
130 #include <compat/sys/time.h>
132 #include <netinet/in.h>
134 #include <miscfs/specfs/specdev.h>
136 #include <nfs/rpcv2.h>
137 #include <nfs/nfsproto.h>
140 #include <sys/socketvar.h> /* sosetopt() */
142 #include <compat/ultrix/ultrix_flock.h>
144 #include <compat/sys/signal.h>
145 #include <compat/sys/signalvar.h>
148 #include <mips/cachectl.h>
149 #include <mips/frame.h>
152 static int ultrix_to_bsd_flock(struct ultrix_flock
*, struct flock
*);
153 static void bsd_to_ultrix_flock(struct flock
*, struct ultrix_flock
*);
155 extern struct sysent ultrix_sysent
[];
156 extern const char * const ultrix_syscallnames
[];
157 extern char ultrix_sigcode
[], ultrix_esigcode
[];
159 struct uvm_object
*emul_ultrix_object
;
161 #ifndef __HAVE_SYSCALL_INTERN
165 struct emul emul_ultrix
= {
168 #ifndef __HAVE_MINIMAL_EMUL
192 #ifdef __HAVE_SYSCALL_INTERN
207 #define GSI_PROG_ENV 1
210 ultrix_sys_getsysinfo(struct lwp
*l
, const struct ultrix_sys_getsysinfo_args
*uap
, register_t
*retval
)
212 static short progenv
= 0;
214 switch (SCARG(uap
, op
)) {
215 /* operations implemented: */
217 if (SCARG(uap
, nbytes
) < sizeof(short))
220 return copyout(&progenv
, SCARG(uap
, buffer
), sizeof(progenv
));
222 *retval
= 0; /* info unavail */
228 ultrix_sys_setsysinfo(struct lwp
*l
, const struct ultrix_sys_setsysinfo_args
*uap
, register_t
*retval
)
236 ultrix_sys_waitpid(struct lwp
*l
, const struct ultrix_sys_waitpid_args
*uap
, register_t
*retval
)
238 struct compat_50_sys_wait4_args ap
;
240 SCARG(&ap
, pid
) = SCARG(uap
, pid
);
241 SCARG(&ap
, status
) = SCARG(uap
, status
);
242 SCARG(&ap
, options
) = SCARG(uap
, options
);
243 SCARG(&ap
, rusage
) = 0;
245 return compat_50_sys_wait4(l
, &ap
, retval
);
249 ultrix_sys_wait3(struct lwp
*l
, const struct ultrix_sys_wait3_args
*uap
, register_t
*retval
)
251 struct compat_50_sys_wait4_args ap
;
253 SCARG(&ap
, pid
) = -1;
254 SCARG(&ap
, status
) = SCARG(uap
, status
);
255 SCARG(&ap
, options
) = SCARG(uap
, options
);
256 SCARG(&ap
, rusage
) = SCARG(uap
, rusage
);
258 return compat_50_sys_wait4(l
, &ap
, retval
);
262 * Ultrix binaries pass in FD_MAX as the first arg to select().
263 * On Ultrix, FD_MAX is 4096, which is more than the NetBSD sys_select()
265 * Since we can't have more than the (native) FD_MAX descriptors open,
266 * limit nfds to at most FD_MAX.
269 ultrix_sys_select(struct lwp
*l
, const struct ultrix_sys_select_args
*uap
, register_t
*retval
)
271 struct timeval50 atv
;
273 struct compat_50_sys_select_args ap
;
275 /* Limit number of FDs selected on to the native maximum */
277 if (SCARG(uap
, nd
) > FD_SETSIZE
)
278 SCARG(&ap
, nd
) = FD_SETSIZE
;
280 SCARG(&ap
, nd
) = SCARG(uap
, nd
);
282 SCARG(&ap
, in
) = SCARG(uap
, in
);
283 SCARG(&ap
, ou
) = SCARG(uap
, ou
);
284 SCARG(&ap
, ex
) = SCARG(uap
, ex
);
285 SCARG(&ap
, tv
) = SCARG(uap
, tv
);
286 /* Check for negative timeval */
287 if (SCARG(&ap
, tv
)) {
288 error
= copyin(SCARG(uap
, tv
), &atv
, sizeof(atv
));
292 /* Ultrix clients sometimes give negative timeouts? */
293 if (atv
.tv_sec
< 0 || atv
.tv_usec
< 0)
294 printf("ultrix select( %ld, %ld): negative timeout\n",
295 atv
.tv_sec
, atv
.tv_usec
);
299 error
= compat_50_sys_select(l
, &ap
, retval
);
301 printf("ultrix select: bad args?\n");
309 async_daemon(struct lwp
*l
, const void *v
, register_t
*retval
)
311 struct sys_nfssvc_args ouap
;
313 SCARG(&ouap
, flag
) = NFSSVC_BIOD
;
314 SCARG(&ouap
, argp
) = NULL
;
316 return sys_nfssvc(l
, &ouap
, retval
);
321 #define SUN__MAP_NEW 0x80000000 /* if not, old mmap & cannot handle */
324 ultrix_sys_mmap(struct lwp
*l
, const struct ultrix_sys_mmap_args
*uap
, register_t
*retval
)
326 struct sys_mmap_args ouap
;
329 * Verify the arguments.
331 if (SCARG(uap
, prot
) & ~(PROT_READ
|PROT_WRITE
|PROT_EXEC
))
332 return EINVAL
; /* XXX still needed? */
334 if ((SCARG(uap
, flags
) & SUN__MAP_NEW
) == 0)
337 SCARG(&ouap
, flags
) = SCARG(uap
, flags
) & ~SUN__MAP_NEW
;
338 SCARG(&ouap
, addr
) = SCARG(uap
, addr
);
339 SCARG(&ouap
, len
) = SCARG(uap
, len
);
340 SCARG(&ouap
, prot
) = SCARG(uap
, prot
);
341 SCARG(&ouap
, fd
) = SCARG(uap
, fd
);
342 SCARG(&ouap
, pos
) = SCARG(uap
, pos
);
344 return sys_mmap(l
, &ouap
, retval
);
348 ultrix_sys_setsockopt(struct lwp
*l
, const struct ultrix_sys_setsockopt_args
*uap
, register_t
*retval
)
353 struct sys_setsockopt_args ap
;
355 SCARG(&ap
, s
) = SCARG(uap
, s
);
356 SCARG(&ap
, level
) = SCARG(uap
, level
);
357 SCARG(&ap
, name
) = SCARG(uap
, name
);
358 SCARG(&ap
, val
) = SCARG(uap
, val
);
359 SCARG(&ap
, valsize
) = SCARG(uap
, valsize
);
361 /* fd_getsock() will use the descriptor for us */
362 if ((error
= fd_getsock(SCARG(&ap
, s
), &so
)) != 0)
364 #define SO_DONTLINGER (~SO_LINGER)
365 if (SCARG(&ap
, name
) == SO_DONTLINGER
) {
369 error
= so_setsockopt(l
, so
, SCARG(&ap
, level
), SO_LINGER
,
373 if (SCARG(&ap
, level
) == IPPROTO_IP
) {
374 #define EMUL_IP_MULTICAST_IF 2
375 #define EMUL_IP_MULTICAST_TTL 3
376 #define EMUL_IP_MULTICAST_LOOP 4
377 #define EMUL_IP_ADD_MEMBERSHIP 5
378 #define EMUL_IP_DROP_MEMBERSHIP 6
379 static const int ipoptxlat
[] = {
386 if (SCARG(&ap
, name
) >= EMUL_IP_MULTICAST_IF
&&
387 SCARG(&ap
, name
) <= EMUL_IP_DROP_MEMBERSHIP
) {
389 ipoptxlat
[SCARG(&ap
, name
) - EMUL_IP_MULTICAST_IF
];
392 if (SCARG(&ap
, valsize
) > MLEN
) {
396 sockopt_init(&sopt
, SCARG(&ap
, level
), SCARG(&ap
, name
),
397 SCARG(&ap
, valsize
));
398 if (SCARG(&ap
, val
)) {
399 error
= copyin(SCARG(&ap
, val
), sopt
.sopt_data
,
400 (u_int
)SCARG(&ap
, valsize
));
403 error
= sosetopt(so
, &sopt
);
404 sockopt_destroy(&sopt
);
406 fd_putfile(SCARG(uap
, s
));
410 #define ULTRIX__SYS_NMLN 32
412 struct ultrix_utsname
{
413 char sysname
[ULTRIX__SYS_NMLN
];
414 char nodename
[ULTRIX__SYS_NMLN
];
415 char release
[ULTRIX__SYS_NMLN
];
416 char version
[ULTRIX__SYS_NMLN
];
417 char machine
[ULTRIX__SYS_NMLN
];
421 ultrix_sys_uname(struct lwp
*l
, const struct ultrix_sys_uname_args
*uap
, register_t
*retval
)
423 struct ultrix_utsname sut
;
427 memset(&sut
, 0, sizeof(sut
));
429 strncpy(sut
.sysname
, ostype
, sizeof(sut
.sysname
) - 1);
430 strncpy(sut
.nodename
, hostname
, sizeof(sut
.nodename
) - 1);
431 strncpy(sut
.release
, osrelease
, sizeof(sut
.release
) - 1);
433 ep
= &sut
.version
[sizeof(sut
.version
) - 1];
434 for (cp
= version
; *cp
&& *cp
!= '('; cp
++)
436 for (cp
++; *cp
&& *cp
!= ')' && dp
< ep
; cp
++)
438 for (; *cp
&& *cp
!= '#'; cp
++)
440 for (; *cp
&& *cp
!= ':' && dp
< ep
; cp
++)
443 strncpy(sut
.machine
, machine
, sizeof(sut
.machine
) - 1);
445 return copyout(&sut
, SCARG(uap
, name
), sizeof(sut
));
449 ultrix_sys_setpgrp(struct lwp
*l
, const struct ultrix_sys_setpgrp_args
*uap
, register_t
*retval
)
451 struct proc
*p
= l
->l_proc
;
452 struct sys_setpgid_args ap
;
454 SCARG(&ap
, pid
) = SCARG(uap
, pid
);
455 SCARG(&ap
, pgid
) = SCARG(uap
, pgid
);
457 * difference to our setpgid call is to include backwards
458 * compatibility to pre-setsid() binaries. Do setsid()
459 * instead of setpgid() in those cases where the process
460 * tries to create a new session the old way.
462 if (!SCARG(&ap
, pgid
) &&
463 (!SCARG(&ap
, pid
) || SCARG(&ap
, pid
) == p
->p_pid
))
464 return sys_setsid(l
, &ap
, retval
);
466 return sys_setpgid(l
, &ap
, retval
);
470 ultrix_sys_nfssvc(struct lwp
*l
, const struct ultrix_sys_nfssvc_args
*uap
,
475 struct emul
*e
= p
->p_emul
;
476 struct sys_nfssvc_args outuap
;
479 void *sg
= stackgap_init(p
, 0);
481 memset(&outuap
, 0, sizeof outuap
);
482 SCARG(&outuap
, fd
) = SCARG(uap
, fd
);
483 SCARG(&outuap
, mskval
) = stackgap_alloc(p
, &sg
, sizeof sa
);
484 SCARG(&outuap
, msklen
) = sizeof sa
;
485 SCARG(&outuap
, mtchval
) = stackgap_alloc(p
, &sg
, sizeof sa
);
486 SCARG(&outuap
, mtchlen
) = sizeof sa
;
488 memset(&sa
, 0, sizeof sa
);
489 if (error
= copyout(&sa
, SCARG(&outuap
, mskval
), SCARG(&outuap
, msklen
)))
491 if (error
= copyout(&sa
, SCARG(&outuap
, mtchval
), SCARG(&outuap
, mtchlen
)))
494 return nfssvc(l
, &outuap
, retval
);
500 struct ultrix_ustat
{
501 daddr_t f_tfree
; /* total free */
502 uint32_t f_tinode
; /* total inodes free */
503 char f_fname
[6]; /* filsys name */
504 char f_fpack
[6]; /* filsys pack name */
508 ultrix_sys_ustat(struct lwp
*l
, const struct ultrix_sys_ustat_args
*uap
, register_t
*retval
)
510 struct ultrix_ustat us
;
513 memset(&us
, 0, sizeof us
);
516 * XXX: should set f_tfree and f_tinode at least
517 * How do we translate dev -> fstat? (and then to ultrix_ustat)
520 if ((error
= copyout(&us
, SCARG(uap
, buf
), sizeof us
)) != 0)
526 ultrix_sys_quotactl(struct lwp
*l
, const struct ultrix_sys_quotactl_args
*uap
, register_t
*retval
)
533 ultrix_sys_vhangup(struct lwp
*l
, const void *uap
, register_t
*retval
)
541 * RISC Ultrix cache control syscalls
545 ultrix_sys_cacheflush(struct lwp
*l
, const struct ultrix_sys_cacheflush_args
*uap
, register_t
*retval
)
548 syscallarg(void *) addr;
549 syscallarg(unsigned) nbytes;
550 syscallarg(int) flag;
552 struct proc
*p
= l
->l_proc
;
553 vaddr_t va
= (vaddr_t
)SCARG(uap
, addr
);
554 int nbytes
= SCARG(uap
, nbytes
);
555 int whichcache
= SCARG(uap
, whichcache
);
557 return mips_user_cacheflush(p
, va
, nbytes
, whichcache
);
562 ultrix_sys_cachectl(struct lwp
*l
, const struct ultrix_sys_cachectl_args
*uap
, register_t
*retval
)
565 syscallarg(void *) addr;
566 syscallarg(int) nbytes;
567 syscallarg(int) cacheop;
569 struct proc
*p
= l
->l_proc
;
570 vaddr_t va
= (vaddr_t
)SCARG(uap
, addr
);
571 int nbytes
= SCARG(uap
, nbytes
);
572 int cacheop
= SCARG(uap
, cacheop
);
574 return mips_user_cachectl(p
, va
, nbytes
, cacheop
);
581 ultrix_sys_exportfs(struct lwp
*l
, const struct ultrix_sys_exportfs_args
*uap
, register_t
*retval
)
585 * XXX: should perhaps translate into a mount(2)
592 ultrix_sys_sigpending(struct lwp
*l
, const struct ultrix_sys_sigpending_args
*uap
, register_t
*retval
)
600 return copyout(&mask
, SCARG(uap
, mask
), sizeof(int));
604 ultrix_sys_sigreturn(struct lwp
*l
, const struct ultrix_sys_sigreturn_args
*uap
, register_t
*retval
)
606 /* struct sigcontext13 is close enough to Ultrix */
607 struct compat_13_sys_sigreturn_args ap
;
609 SCARG(&ap
, sigcntxp
) = (void *)SCARG(uap
, sigcntxp
);
611 return compat_13_sys_sigreturn(l
, &ap
, retval
);
615 ultrix_sys_sigcleanup(struct lwp
*l
, const struct ultrix_sys_sigcleanup_args
*uap
, register_t
*retval
)
618 /* struct sigcontext13 is close enough to Ultrix */
619 struct compat_13_sys_sigreturn_args ap
;
621 SCARG(&ap
, sigcntxp
) = (void *)SCARG(uap
, sigcntxp
);
623 return compat_13_sys_sigreturn(l
, &ap
, retval
);
627 ultrix_sys_sigsuspend(struct lwp
*l
, const struct ultrix_sys_sigsuspend_args
*uap
, register_t
*retval
)
629 int mask
= SCARG(uap
, mask
);
637 return sigsuspend1(l
, &ss
);
640 #define ULTRIX_SV_ONSTACK 0x0001 /* take signal on signal stack */
641 #define ULTRIX_SV_INTERRUPT 0x0002 /* do not restart system on signal return */
642 #define ULTRIX_SV_OLDSIG 0x1000 /* Emulate old signal() for POSIX */
645 ultrix_sys_sigvec(struct lwp
*l
, const struct ultrix_sys_sigvec_args
*uap
, register_t
*retval
)
647 struct sigvec nsv
, osv
;
648 struct sigaction nsa
, osa
;
651 if (SCARG(uap
, nsv
)) {
652 error
= copyin(SCARG(uap
, nsv
), &nsv
, sizeof(nsv
));
655 nsa
.sa_handler
= nsv
.sv_handler
;
656 #if 0 /* documentation */
657 /* ONSTACK is identical */
658 nsa
.sa_flags
= nsv
.sv_flags
& ULTRIX_SV_ONSTACK
;
659 if ((nsv
.sv_flags
& ULTRIX_SV_OLDSIG
)
660 /* old signal() - always restart */
661 || (!(nsv
.sv_flags
& ULTRIX_SV_INTERRUPT
))
662 /* inverted meaning (same bit) */
664 nsa
.sa_flags
|= SA_RESTART
;
665 #else /* optimized - assuming ULTRIX_SV_OLDSIG=>!ULTRIX_SV_INTERRUPT */
666 nsa
.sa_flags
= nsv
.sv_flags
& ~ULTRIX_SV_OLDSIG
;
667 nsa
.sa_flags
^= SA_RESTART
;
669 native_sigset13_to_sigset(&nsv
.sv_mask
, &nsa
.sa_mask
);
671 error
= sigaction1(l
, SCARG(uap
, signum
),
672 SCARG(uap
, nsv
) ? &nsa
: 0, SCARG(uap
, osv
) ? &osa
: 0,
676 if (SCARG(uap
, osv
)) {
677 osv
.sv_handler
= osa
.sa_handler
;
678 osv
.sv_flags
= osa
.sa_flags
^ SA_RESTART
;
679 osv
.sv_flags
&= (ULTRIX_SV_ONSTACK
| ULTRIX_SV_INTERRUPT
);
680 native_sigset_to_sigset13(&osa
.sa_mask
, &osv
.sv_mask
);
681 error
= copyout(&osv
, SCARG(uap
, osv
), sizeof(osv
));
689 ultrix_sys_shmsys(struct lwp
*l
, const struct ultrix_sys_shmsys_args
*uap
, register_t
*retval
)
693 /* Ultrix SVSHM weirndess: */
694 struct sys_shmat_args shmat_args
;
695 struct compat_14_sys_shmctl_args shmctl_args
;
696 struct sys_shmdt_args shmdt_args
;
697 struct sys_shmget_args shmget_args
;
700 switch (SCARG(uap
, shmop
)) {
701 case 0: /* Ultrix shmat() */
702 SCARG(&shmat_args
, shmid
) = SCARG(uap
, a2
);
703 SCARG(&shmat_args
, shmaddr
) = (void *)SCARG(uap
, a3
);
704 SCARG(&shmat_args
, shmflg
) = SCARG(uap
, a4
);
705 return sys_shmat(l
, &shmat_args
, retval
);
707 case 1: /* Ultrix shmctl() */
708 SCARG(&shmctl_args
, shmid
) = SCARG(uap
, a2
);
709 SCARG(&shmctl_args
, cmd
) = SCARG(uap
, a3
);
710 SCARG(&shmctl_args
, buf
) = (struct shmid_ds14
*)SCARG(uap
, a4
);
711 return compat_14_sys_shmctl(l
, &shmctl_args
, retval
);
713 case 2: /* Ultrix shmdt() */
714 SCARG(&shmat_args
, shmaddr
) = (void *)SCARG(uap
, a2
);
715 return sys_shmdt(l
, &shmdt_args
, retval
);
717 case 3: /* Ultrix shmget() */
718 SCARG(&shmget_args
, key
) = SCARG(uap
, a2
);
719 SCARG(&shmget_args
, size
) = SCARG(uap
, a3
);
720 SCARG(&shmget_args
, shmflg
) = SCARG(uap
, a4
)
721 & (IPC_CREAT
|IPC_EXCL
|IPC_NOWAIT
);
722 return sys_shmget(l
, &shmget_args
, retval
);
733 ultrix_to_bsd_flock(struct ultrix_flock
*ufl
, struct flock
*fl
)
736 fl
->l_start
= ufl
->l_start
;
737 fl
->l_len
= ufl
->l_len
;
738 fl
->l_pid
= ufl
->l_pid
;
739 fl
->l_whence
= ufl
->l_whence
;
741 switch (ufl
->l_type
) {
743 fl
->l_type
= F_RDLCK
;
746 fl
->l_type
= F_WRLCK
;
749 fl
->l_type
= F_UNLCK
;
759 bsd_to_ultrix_flock(struct flock
*fl
, struct ultrix_flock
*ufl
)
762 ufl
->l_start
= fl
->l_start
;
763 ufl
->l_len
= fl
->l_len
;
764 ufl
->l_pid
= fl
->l_pid
;
765 ufl
->l_whence
= fl
->l_whence
;
767 switch (fl
->l_type
) {
769 ufl
->l_type
= ULTRIX_F_RDLCK
;
772 ufl
->l_type
= ULTRIX_F_WRLCK
;
775 ufl
->l_type
= ULTRIX_F_UNLCK
;
781 ultrix_sys_fcntl(struct lwp
*l
, const struct ultrix_sys_fcntl_args
*uap
, register_t
*retval
)
784 struct ultrix_flock ufl
;
787 switch (SCARG(uap
, cmd
)) {
791 error
= copyin(SCARG(uap
, arg
), &ufl
, sizeof(ufl
));
794 error
= ultrix_to_bsd_flock(&ufl
, &fl
);
797 error
= do_fcntl_lock(SCARG(uap
, fd
), SCARG(uap
, cmd
), &fl
);
798 if (SCARG(uap
, cmd
) != F_GETLK
|| error
!= 0)
800 bsd_to_ultrix_flock(&fl
, &ufl
);
801 return copyout(&ufl
, SCARG(uap
, arg
), sizeof(ufl
));
807 return sys_fcntl(l
, (const void *)uap
, retval
);