1 /* $NetBSD: ibcs2_misc.c,v 1.108 2009/08/09 22:49:00 haad Exp $ */
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This software was developed by the Computer Systems Engineering group
8 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
9 * contributed to Berkeley.
11 * All advertising materials mentioning features or use of this software
12 * must display the following acknowledgement:
13 * This product includes software developed by the University of
14 * California, Lawrence Berkeley Laboratory.
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 * from: Header: sun_misc.c,v 1.16 93/04/07 02:46:27 torek Exp
42 * @(#)sun_misc.c 8.1 (Berkeley) 6/18/93
46 * Copyright (c) 1994, 1995, 1998 Scott Bartram
48 * This software was developed by the Computer Systems Engineering group
49 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
50 * contributed to Berkeley.
52 * All advertising materials mentioning features or use of this software
53 * must display the following acknowledgement:
54 * This product includes software developed by the University of
55 * California, Lawrence Berkeley Laboratory.
57 * Redistribution and use in source and binary forms, with or without
58 * modification, are permitted provided that the following conditions
60 * 1. Redistributions of source code must retain the above copyright
61 * notice, this list of conditions and the following disclaimer.
62 * 2. Redistributions in binary form must reproduce the above copyright
63 * notice, this list of conditions and the following disclaimer in the
64 * documentation and/or other materials provided with the distribution.
65 * 3. All advertising materials mentioning features or use of this software
66 * must display the following acknowledgement:
67 * This product includes software developed by the University of
68 * California, Berkeley and its contributors.
69 * 4. Neither the name of the University nor the names of its contributors
70 * may be used to endorse or promote products derived from this software
71 * without specific prior written permission.
73 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
74 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
75 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
76 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
77 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
78 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
79 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
80 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
81 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
82 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
85 * from: Header: sun_misc.c,v 1.16 93/04/07 02:46:27 torek Exp
87 * @(#)sun_misc.c 8.1 (Berkeley) 6/18/93
91 * IBCS2 compatibility module.
93 * IBCS2 system calls that are implemented differently in BSD are
97 #include <sys/cdefs.h>
98 __KERNEL_RCSID(0, "$NetBSD: ibcs2_misc.c,v 1.108 2009/08/09 22:49:00 haad Exp $");
100 #include <sys/param.h>
101 #include <sys/systm.h>
102 #include <sys/namei.h>
103 #include <sys/dirent.h>
104 #include <sys/proc.h>
105 #include <sys/file.h>
106 #include <sys/filedesc.h>
107 #include <sys/ioctl.h>
108 #include <sys/kernel.h>
109 #include <sys/malloc.h>
110 #include <sys/mbuf.h>
111 #include <sys/mman.h>
112 #include <sys/mount.h>
113 #include <sys/prot.h>
114 #include <sys/reboot.h>
115 #include <sys/resource.h>
116 #include <sys/resourcevar.h>
117 #include <sys/socket.h>
118 #include <sys/stat.h>
119 #include <sys/syslog.h>
120 #include <sys/time.h>
121 #include <sys/times.h>
122 #include <sys/vnode.h>
124 #include <sys/wait.h>
125 #include <sys/utsname.h>
126 #include <sys/unistd.h>
127 #include <sys/kauth.h>
128 #include <sys/vfs_syscalls.h>
130 #include <netinet/in.h>
131 #include <sys/syscallargs.h>
133 #include <miscfs/specfs/specdev.h>
135 #include <uvm/uvm_extern.h>
136 #include <sys/sysctl.h>
138 #if defined(__i386__)
139 #include <i386/include/reg.h>
142 #include <compat/ibcs2/ibcs2_types.h>
143 #include <compat/ibcs2/ibcs2_dirent.h>
144 #include <compat/ibcs2/ibcs2_fcntl.h>
145 #include <compat/ibcs2/ibcs2_mman.h>
146 #include <compat/ibcs2/ibcs2_time.h>
147 #include <compat/ibcs2/ibcs2_signal.h>
148 #include <compat/ibcs2/ibcs2_timeb.h>
149 #include <compat/ibcs2/ibcs2_unistd.h>
150 #include <compat/ibcs2/ibcs2_utsname.h>
151 #include <compat/ibcs2/ibcs2_util.h>
152 #include <compat/ibcs2/ibcs2_utime.h>
153 #include <compat/ibcs2/ibcs2_syscallargs.h>
154 #include <compat/ibcs2/ibcs2_sysi86.h>
155 #include <compat/ibcs2/ibcs2_exec.h>
157 #include <compat/sys/mount.h>
160 ibcs2_sys_ulimit(struct lwp
*l
, const struct ibcs2_sys_ulimit_args
*uap
, register_t
*retval
)
164 syscallarg(int) newlimit;
166 struct proc
*p
= l
->l_proc
;
167 struct ibcs2_sys_sysconf_args sysconf_ua
;
171 struct sys_setrlimit_args sra
;
173 #define IBCS2_GETFSIZE 1
174 #define IBCS2_SETFSIZE 2
175 #define IBCS2_GETPSIZE 3
176 #define IBCS2_GETDTABLESIZE 4
178 switch (SCARG(uap
, cmd
)) {
180 *retval
= p
->p_rlimit
[RLIMIT_FSIZE
].rlim_cur
;
182 case IBCS2_SETFSIZE
: /* XXX - fix this */
184 rl
.rlim_cur
= SCARG(uap
, newlimit
);
185 SCARG(&sra
, which
) = RLIMIT_FSIZE
;
186 SCARG(&sra
, rlp
) = &rl
;
187 error
= setrlimit(p
, &sra
, retval
);
189 *retval
= p
->p_rlimit
[RLIMIT_FSIZE
].rlim_cur
;
191 DPRINTF(("failed "));
194 *retval
= SCARG(uap
, newlimit
);
198 *retval
= p
->p_rlimit
[RLIMIT_RSS
].rlim_cur
; /* XXX */
200 case IBCS2_GETDTABLESIZE
:
201 SCARG(&sysconf_ua
, name
) = IBCS2_SC_OPEN_MAX
;
202 return ibcs2_sys_sysconf(l
, &sysconf_ua
, retval
);
209 ibcs2_sys_waitsys(struct lwp
*l
, const struct ibcs2_sys_waitsys_args
*uap
, register_t
*retval
)
211 #if defined(__i386__)
218 int error
, options
, status
, pid
;
220 #if defined(__i386__)
221 #define WAITPID_EFLAGS 0x8c4 /* OF, SF, ZF, PF */
222 if ((l
->l_md
.md_regs
->tf_eflags
& WAITPID_EFLAGS
) == WAITPID_EFLAGS
) {
224 pid
= SCARG(uap
, a1
);
225 options
= SCARG(uap
, a3
);
231 #if defined(__i386__)
235 error
= do_sys_wait(&pid
, &status
, options
, NULL
);
242 ibcs2_sys_execv(struct lwp
*l
, const struct ibcs2_sys_execv_args
*uap
, register_t
*retval
)
245 syscallarg(const char *) path;
246 syscallarg(char **) argp;
248 struct sys_execve_args ap
;
250 SCARG(&ap
, path
) = SCARG(uap
, path
);
251 SCARG(&ap
, argp
) = SCARG(uap
, argp
);
252 SCARG(&ap
, envp
) = NULL
;
254 return sys_execve(l
, &ap
, retval
);
258 ibcs2_sys_execve(struct lwp
*l
, const struct ibcs2_sys_execve_args
*uap
, register_t
*retval
)
261 syscallarg(const char *) path;
262 syscallarg(char **) argp;
263 syscallarg(char **) envp;
265 struct sys_execve_args ap
;
267 SCARG(&ap
, path
) = SCARG(uap
, path
);
268 SCARG(&ap
, argp
) = SCARG(uap
, argp
);
269 SCARG(&ap
, envp
) = SCARG(uap
, envp
);
271 return sys_execve(l
, &ap
, retval
);
275 ibcs2_sys_umount(struct lwp
*l
, const struct ibcs2_sys_umount_args
*uap
, register_t
*retval
)
278 syscallarg(char *) name;
280 struct sys_unmount_args um
;
282 SCARG(&um
, path
) = SCARG(uap
, name
);
283 SCARG(&um
, flags
) = 0;
284 return sys_unmount(l
, &um
, retval
);
288 ibcs2_sys_mount(struct lwp
*l
, const struct ibcs2_sys_mount_args
*uap
, register_t
*retval
)
292 syscallarg(char *) special;
293 syscallarg(char *) dir;
294 syscallarg(int) flags;
295 syscallarg(int) fstype;
296 syscallarg(char *) data;
299 int oflags
= SCARG(uap
, flags
), nflags
, error
;
300 char fsname
[MFSNAMELEN
];
302 if (oflags
& (IBCS2_MS_NOSUB
| IBCS2_MS_SYS5
))
304 if ((oflags
& IBCS2_MS_NEWTYPE
) == 0)
307 if (oflags
& IBCS2_MS_RDONLY
)
308 nflags
|= MNT_RDONLY
;
309 if (oflags
& IBCS2_MS_NOSUID
)
310 nflags
|= MNT_NOSUID
;
311 if (oflags
& IBCS2_MS_REMOUNT
)
312 nflags
|= MNT_UPDATE
;
313 SCARG(uap
, flags
) = nflags
;
315 if (error
= copyinstr(SCARG(uap
, type
), fsname
, sizeof fsname
, NULL
))
318 if (strncmp(fsname
, "4.2", sizeof fsname
) == 0) {
319 SCARG(uap
, type
) = (void *)STACK_ALLOC();
320 if (error
= copyout("ffs", SCARG(uap
, type
), sizeof("ffs")))
322 } else if (strncmp(fsname
, "nfs", sizeof fsname
) == 0) {
323 struct ibcs2_nfs_args sna
;
324 struct sockaddr_in sain
;
328 if (error
= copyin(SCARG(uap
, data
), &sna
, sizeof sna
))
330 if (error
= copyin(sna
.addr
, &sain
, sizeof sain
))
332 memcpy(&sa
, &sain
, sizeof sa
);
333 sa
.sa_len
= sizeof(sain
);
334 SCARG(uap
, data
) = STACK_ALLOC();
335 na
.addr
= (void *)((unsigned long)SCARG(uap
, data
) + sizeof na
);
336 na
.sotype
= SOCK_DGRAM
;
337 na
.proto
= IPPROTO_UDP
;
338 na
.fh
= (nfsv2fh_t
*)sna
.fh
;
339 na
.flags
= sna
.flags
;
340 na
.wsize
= sna
.wsize
;
341 na
.rsize
= sna
.rsize
;
342 na
.timeo
= sna
.timeo
;
343 na
.retrans
= sna
.retrans
;
344 na
.hostname
= sna
.hostname
;
346 if (error
= copyout(&sa
, na
.addr
, sizeof sa
))
348 if (error
= copyout(&na
, SCARG(uap
, data
), sizeof na
))
351 return sys_mount(p
, uap
, retval
);
358 * Read iBCS2-style directory entries. We suck them into kernel space so
359 * that they can be massaged before being copied out to user code. Like
360 * SunOS, we squish out `empty' entries.
362 * This is quite ugly, but what do you expect from compatibility code?
366 ibcs2_sys_getdents(struct lwp
*l
, const struct ibcs2_sys_getdents_args
*uap
, register_t
*retval
)
370 syscallarg(char *) buf;
371 syscallarg(int) nbytes;
375 char *inp
, *tbuf
; /* BSD-format */
376 int len
, reclen
; /* BSD-format */
377 char *outp
; /* iBCS2-format */
378 int resid
, ibcs2_reclen
;/* iBCS2-format */
382 struct ibcs2_dirent idb
;
383 off_t off
; /* true file offset */
386 off_t
*cookiebuf
= NULL
, *cookie
;
389 /* fd_getvnode() will use the descriptor for us */
390 if ((error
= fd_getvnode(SCARG(uap
, fd
), &fp
)) != 0)
392 if ((fp
->f_flag
& FREAD
) == 0) {
397 if (vp
->v_type
!= VDIR
) {
401 buflen
= min(MAXBSIZE
, (size_t)SCARG(uap
, nbytes
));
402 tbuf
= malloc(buflen
, M_TEMP
, M_WAITOK
);
403 vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
);
406 aiov
.iov_base
= tbuf
;
407 aiov
.iov_len
= buflen
;
408 auio
.uio_iov
= &aiov
;
410 auio
.uio_rw
= UIO_READ
;
411 auio
.uio_resid
= buflen
;
412 auio
.uio_offset
= off
;
413 UIO_SETUP_SYSSPACE(&auio
);
415 * First we read into the malloc'ed buffer, then
416 * we massage it into user space, one record at a time.
418 error
= VOP_READDIR(vp
, &auio
, fp
->f_cred
, &eofflag
, &cookiebuf
,
423 outp
= SCARG(uap
, buf
);
424 resid
= SCARG(uap
, nbytes
);
425 if ((len
= buflen
- auio
.uio_resid
) == 0)
427 for (cookie
= cookiebuf
; len
> 0; len
-= reclen
) {
428 bdp
= (struct dirent
*)inp
;
429 reclen
= bdp
->d_reclen
;
431 panic("ibcs2_getdents: bad reclen");
432 if (cookie
&& (*cookie
>> 32) != 0) {
433 compat_offseterr(vp
, "ibcs2_getdents");
437 if (bdp
->d_fileno
== 0) {
438 inp
+= reclen
; /* it is a hole; squish it out */
445 ibcs2_reclen
= IBCS2_RECLEN(&idb
, bdp
->d_namlen
);
446 if (reclen
> len
|| resid
< ibcs2_reclen
) {
447 /* entry too big for buffer, so just stop */
452 off
= *cookie
++; /* each entry points to the next */
456 * Massage in place to make a iBCS2-shaped dirent (otherwise
457 * we have to worry about touching user memory outside of
458 * the copyout() call).
460 idb
.d_ino
= (ibcs2_ino_t
)bdp
->d_fileno
;
461 idb
.d_off
= (ibcs2_off_t
)off
;
462 idb
.d_reclen
= (u_short
)ibcs2_reclen
;
463 strlcpy(idb
.d_name
, bdp
->d_name
, sizeof(idb
.d_name
));
464 error
= copyout(&idb
, outp
, ibcs2_reclen
);
467 /* advance past this real entry */
469 /* advance output past iBCS2-shaped entry */
470 outp
+= ibcs2_reclen
;
471 resid
-= ibcs2_reclen
;
474 /* if we squished out the whole block, try again */
475 if (outp
== SCARG(uap
, buf
))
477 fp
->f_offset
= off
; /* update the vnode offset */
480 *retval
= SCARG(uap
, nbytes
) - resid
;
484 free(cookiebuf
, M_TEMP
);
487 fd_putfile(SCARG(uap
, fd
));
492 ibcs2_sys_read(struct lwp
*l
, const struct ibcs2_sys_read_args
*uap
, register_t
*retval
)
496 syscallarg(char *) buf;
497 syscallarg(u_int) nbytes;
501 char *inp
, *tbuf
; /* BSD-format */
502 int len
, reclen
; /* BSD-format */
503 char *outp
; /* iBCS2-format */
504 int resid
, ibcs2_reclen
;/* iBCS2-format */
508 struct ibcs2_direct
{
515 off_t
*cookiebuf
= NULL
, *cookie
;
516 off_t off
; /* true file offset */
519 /* fd_getvnode() will use the descriptor for us */
520 if ((error
= fd_getvnode(SCARG(uap
, fd
), &fp
)) != 0) {
522 return sys_read(l
, (const void *)uap
, retval
);
526 if ((fp
->f_flag
& FREAD
) == 0) {
531 if (vp
->v_type
!= VDIR
) {
532 fd_putfile(SCARG(uap
, fd
));
533 return sys_read(l
, (const void *)uap
, retval
);
535 buflen
= min(MAXBSIZE
, max(DEV_BSIZE
, (size_t)SCARG(uap
, nbytes
)));
536 tbuf
= malloc(buflen
, M_TEMP
, M_WAITOK
);
537 vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
);
540 aiov
.iov_base
= tbuf
;
541 aiov
.iov_len
= buflen
;
542 auio
.uio_iov
= &aiov
;
544 auio
.uio_rw
= UIO_READ
;
545 auio
.uio_resid
= buflen
;
546 auio
.uio_offset
= off
;
547 UIO_SETUP_SYSSPACE(&auio
);
549 * First we read into the malloc'ed buffer, then
550 * we massage it into user space, one record at a time.
552 error
= VOP_READDIR(vp
, &auio
, fp
->f_cred
, &eofflag
, &cookiebuf
,
557 outp
= SCARG(uap
, buf
);
558 resid
= SCARG(uap
, nbytes
);
559 if ((len
= buflen
- auio
.uio_resid
) == 0)
561 for (cookie
= cookiebuf
; len
> 0 && resid
> 0; len
-= reclen
) {
562 bdp
= (struct dirent
*)inp
;
563 reclen
= bdp
->d_reclen
;
565 panic("ibcs2_sys_read");
567 off
= *cookie
++; /* each entry points to the next */
570 if ((off
>> 32) != 0) {
574 if (bdp
->d_fileno
== 0) {
575 inp
+= reclen
; /* it is a hole; squish it out */
579 if (reclen
> len
|| resid
< ibcs2_reclen
) {
580 /* entry too big for buffer, so just stop */
585 * Massage in place to make a iBCS2-shaped dirent (otherwise
586 * we have to worry about touching user memory outside of
587 * the copyout() call).
589 * TODO: if length(filename) > 14, then break filename into
590 * multiple entries and set inode = 0xffff except last
592 idb
.ino
= (bdp
->d_fileno
> 0xfffe) ? 0xfffe : bdp
->d_fileno
;
593 (void)copystr(bdp
->d_name
, idb
.name
, 14, &size
);
594 memset(idb
.name
+ size
, 0, 14 - size
);
595 error
= copyout(&idb
, outp
, ibcs2_reclen
);
598 /* advance past this real entry */
600 /* advance output past iBCS2-shaped entry */
601 outp
+= ibcs2_reclen
;
602 resid
-= ibcs2_reclen
;
604 /* if we squished out the whole block, try again */
605 if (outp
== SCARG(uap
, buf
))
607 fp
->f_offset
= off
; /* update the vnode offset */
609 *retval
= SCARG(uap
, nbytes
) - resid
;
613 free(cookiebuf
, M_TEMP
);
616 fd_putfile(SCARG(uap
, fd
));
621 ibcs2_sys_mknod(struct lwp
*l
, const struct ibcs2_sys_mknod_args
*uap
, register_t
*retval
)
624 syscallarg(const char *) path;
625 syscallarg(int) mode;
629 if (S_ISFIFO(SCARG(uap
, mode
))) {
630 struct sys_mkfifo_args ap
;
631 SCARG(&ap
, path
) = SCARG(uap
, path
);
632 SCARG(&ap
, mode
) = SCARG(uap
, mode
);
633 return sys_mkfifo(l
, &ap
, retval
);
635 return do_sys_mknod(l
, SCARG(uap
, path
), SCARG(uap
, mode
),
636 SCARG(uap
, dev
), retval
, UIO_USERSPACE
);
641 ibcs2_sys_getgroups(struct lwp
*l
, const struct ibcs2_sys_getgroups_args
*uap
, register_t
*retval
)
644 syscallarg(int) gidsetsize;
645 syscallarg(ibcs2_gid_t *) gidset;
647 ibcs2_gid_t iset
[16];
653 ngrps
= kauth_cred_ngroups(l
->l_cred
);
655 if (SCARG(uap
, gidsetsize
) == 0)
657 if (SCARG(uap
, gidsetsize
) < ngrps
)
660 gidset
= SCARG(uap
, gidset
);
661 for (i
= 0; i
< (n
= ngrps
); i
+= n
, gidset
+= n
) {
663 if (n
> __arraycount(iset
))
664 n
= __arraycount(iset
);
665 for (j
= 0; j
< n
; j
++)
666 iset
[j
] = kauth_cred_group(l
->l_cred
, i
+ j
);
667 error
= copyout(iset
, gidset
, n
* sizeof(iset
[0]));
676 * It is very unlikly that any problem using 16bit groups is written
677 * to allow for more than 16 of them, so don't bother trying to
680 #define COMPAT_NGROUPS16 16
683 ibcs2_sys_setgroups(struct lwp
*l
, const struct ibcs2_sys_setgroups_args
*uap
, register_t
*retval
)
686 syscallarg(int) gidsetsize;
687 syscallarg(ibcs2_gid_t *) gidset;
690 ibcs2_gid_t iset
[COMPAT_NGROUPS16
];
693 gid_t grbuf
[COMPAT_NGROUPS16
];
694 unsigned int i
, ngroups
= SCARG(uap
, gidsetsize
);
696 if (ngroups
> COMPAT_NGROUPS16
)
698 error
= copyin(SCARG(uap
, gidset
), iset
, ngroups
);
702 for (i
= 0; i
< ngroups
; i
++)
705 ncred
= kauth_cred_alloc();
706 error
= kauth_cred_setgroups(ncred
, grbuf
, SCARG(uap
, gidsetsize
),
709 kauth_cred_free(ncred
);
713 return kauth_proc_setgroups(l
, ncred
);
717 ibcs2_sys_setuid(struct lwp
*l
, const struct ibcs2_sys_setuid_args
*uap
, register_t
*retval
)
722 struct sys_setuid_args sa
;
724 SCARG(&sa
, uid
) = (uid_t
)SCARG(uap
, uid
);
725 return sys_setuid(l
, &sa
, retval
);
729 ibcs2_sys_setgid(struct lwp
*l
, const struct ibcs2_sys_setgid_args
*uap
, register_t
*retval
)
734 struct sys_setgid_args sa
;
736 SCARG(&sa
, gid
) = (gid_t
)SCARG(uap
, gid
);
737 return sys_setgid(l
, &sa
, retval
);
741 xenix_sys_ftime(struct lwp
*l
, const struct xenix_sys_ftime_args
*uap
, register_t
*retval
)
744 syscallarg(struct xenix_timeb *) tp;
747 struct xenix_timeb itb
;
750 itb
.time
= tv
.tv_sec
;
751 itb
.millitm
= (tv
.tv_usec
/ 1000);
752 /* NetBSD has no kernel notion of timezone -- fake it. */
755 return copyout(&itb
, SCARG(uap
, tp
), xenix_timeb_len
);
759 ibcs2_sys_time(struct lwp
*l
, const struct ibcs2_sys_time_args
*uap
, register_t
*retval
)
762 syscallarg(ibcs2_time_t *) tp;
764 struct proc
*p
= l
->l_proc
;
769 if (p
->p_emuldata
== IBCS2_EXEC_XENIX
&& SCARG(uap
, tp
))
770 return copyout(&tv
.tv_sec
, SCARG(uap
, tp
),
771 sizeof(ibcs2_time_t
));
777 ibcs2_sys_pathconf(struct lwp
*l
, const struct ibcs2_sys_pathconf_args
*uap
, register_t
*retval
)
780 syscallarg(char *) path;
781 syscallarg(int) name;
783 struct sys_pathconf_args bsd_ua
;
785 SCARG(&bsd_ua
, path
) = SCARG(uap
, path
);
786 /* iBCS2 _PC_* defines are offset by one */
787 SCARG(&bsd_ua
, name
) = SCARG(uap
, name
) + 1;
788 return sys_pathconf(l
, &bsd_ua
, retval
);
792 ibcs2_sys_fpathconf(struct lwp
*l
, const struct ibcs2_sys_fpathconf_args
*uap
, register_t
*retval
)
796 syscallarg(int) name;
798 struct sys_fpathconf_args bsd_ua
;
800 SCARG(&bsd_ua
, fd
) = SCARG(uap
, fd
);
801 /* iBCS2 _PC_* defines are offset by one */
802 SCARG(&bsd_ua
, name
) = SCARG(uap
, name
) + 1;
803 return sys_fpathconf(l
, &bsd_ua
, retval
);
807 ibcs2_sys_sysconf(struct lwp
*l
, const struct ibcs2_sys_sysconf_args
*uap
, register_t
*retval
)
810 syscallarg(int) name;
812 struct proc
*p
= l
->l_proc
;
813 int mib
[2], value
, error
;
816 switch(SCARG(uap
, name
)) {
817 case IBCS2_SC_ARG_MAX
:
818 mib
[1] = KERN_ARGMAX
;
821 case IBCS2_SC_CHILD_MAX
:
822 *retval
= p
->p_rlimit
[RLIMIT_NPROC
].rlim_cur
;
825 case IBCS2_SC_CLK_TCK
:
829 case IBCS2_SC_NGROUPS_MAX
:
830 mib
[1] = KERN_NGROUPS
;
833 case IBCS2_SC_OPEN_MAX
:
834 *retval
= p
->p_rlimit
[RLIMIT_NPROC
].rlim_cur
;
837 case IBCS2_SC_JOB_CONTROL
:
838 mib
[1] = KERN_JOB_CONTROL
;
841 case IBCS2_SC_SAVED_IDS
:
842 mib
[1] = KERN_SAVED_IDS
;
845 case IBCS2_SC_VERSION
:
846 mib
[1] = KERN_POSIX1
;
849 case IBCS2_SC_PASS_MAX
:
850 *retval
= 128; /* XXX - should we create PASS_MAX ? */
853 case IBCS2_SC_XOPEN_VERSION
:
854 *retval
= 2; /* XXX: What should that be? */
864 * calling into sysctl with superuser privs, but we don't mind,
865 * 'cause we're only querying a value.
867 error
= old_sysctl(&mib
[0], 2, &value
, &len
, NULL
, 0, NULL
);
875 ibcs2_sys_alarm(struct lwp
*l
, const struct ibcs2_sys_alarm_args
*uap
, register_t
*retval
)
878 syscallarg(unsigned) sec;
880 struct proc
*p
= l
->l_proc
;
881 struct itimerval it
, oit
;
884 error
= dogetitimer(p
, ITIMER_REAL
, &oit
);
888 timerclear(&it
.it_interval
);
889 it
.it_value
.tv_sec
= SCARG(uap
, sec
);
890 it
.it_value
.tv_usec
= 0;
892 error
= dosetitimer(p
, ITIMER_REAL
, &it
);
896 if (oit
.it_value
.tv_usec
)
897 oit
.it_value
.tv_sec
++;
898 *retval
= oit
.it_value
.tv_sec
;
903 ibcs2_sys_getmsg(struct lwp
*l
, const struct ibcs2_sys_getmsg_args
*uap
, register_t
*retval
)
908 syscallarg(struct ibcs2_stropts *) ctl;
909 syscallarg(struct ibcs2_stropts *) dat;
910 syscallarg(int *) flags;
918 ibcs2_sys_putmsg(struct lwp
*l
, const struct ibcs2_sys_putmsg_args
*uap
, register_t
*retval
)
923 syscallarg(struct ibcs2_stropts *) ctl;
924 syscallarg(struct ibcs2_stropts *) dat;
925 syscallarg(int) flags;
933 ibcs2_sys_times(struct lwp
*l
, const struct ibcs2_sys_times_args
*uap
, register_t
*retval
)
936 syscallarg(struct tms *) tp;
940 struct rusage ru
, *rup
;
941 #define CONVTCK(r) (r.tv_sec * hz + r.tv_usec / (1000000 / hz))
943 ru
= l
->l_proc
->p_stats
->p_ru
;
944 mutex_enter(l
->l_proc
->p_lock
);
945 calcru(l
->l_proc
, &ru
.ru_utime
, &ru
.ru_stime
, NULL
, NULL
);
946 rulwps(l
->l_proc
, &ru
);
947 mutex_exit(l
->l_proc
->p_lock
);
948 tms
.tms_utime
= CONVTCK(ru
.ru_utime
);
949 tms
.tms_stime
= CONVTCK(ru
.ru_stime
);
951 rup
= &l
->l_proc
->p_stats
->p_cru
;
952 tms
.tms_cutime
= CONVTCK(rup
->ru_utime
);
953 tms
.tms_cstime
= CONVTCK(rup
->ru_stime
);
956 *retval
= CONVTCK(t
);
958 return copyout(&tms
, SCARG(uap
, tp
), sizeof(tms
));
962 ibcs2_sys_stime(struct lwp
*l
, const struct ibcs2_sys_stime_args
*uap
, register_t
*retval
)
965 syscallarg(long *) timep;
970 error
= copyin(SCARG(uap
, timep
), &tv
.tv_sec
, sizeof(long));
974 return settimeofday1(&tv
, false, NULL
, l
, true);
978 ibcs2_sys_utime(struct lwp
*l
, const struct ibcs2_sys_utime_args
*uap
, register_t
*retval
)
981 syscallarg(const char *) path;
982 syscallarg(struct ibcs2_utimbuf *) buf;
985 struct timeval
*tptr
;
986 struct timeval tp
[2];
988 if (SCARG(uap
, buf
)) {
989 struct ibcs2_utimbuf ubuf
;
991 error
= copyin(SCARG(uap
, buf
), &ubuf
, sizeof(ubuf
));
994 tp
[0].tv_sec
= ubuf
.actime
;
996 tp
[1].tv_sec
= ubuf
.modtime
;
1002 return do_sys_utimes(l
, NULL
, SCARG(uap
, path
), FOLLOW
,
1003 tptr
, UIO_SYSSPACE
);
1007 ibcs2_sys_nice(struct lwp
*l
, const struct ibcs2_sys_nice_args
*uap
, register_t
*retval
)
1010 syscallarg(int) incr;
1012 struct proc
*p
= l
->l_proc
;
1013 struct sys_setpriority_args sa
;
1015 SCARG(&sa
, which
) = PRIO_PROCESS
;
1016 SCARG(&sa
, who
) = 0;
1017 SCARG(&sa
, prio
) = p
->p_nice
- NZERO
+ SCARG(uap
, incr
);
1018 if (sys_setpriority(l
, &sa
, retval
) != 0)
1020 *retval
= p
->p_nice
- NZERO
;
1025 * iBCS2 getpgrp, setpgrp, setsid, and setpgid
1029 ibcs2_sys_pgrpsys(struct lwp
*l
, const struct ibcs2_sys_pgrpsys_args
*uap
, register_t
*retval
)
1032 syscallarg(int) type;
1033 syscallarg(void *) dummy;
1034 syscallarg(int) pid;
1035 syscallarg(int) pgid;
1037 struct proc
*p
= l
->l_proc
;
1039 switch (SCARG(uap
, type
)) {
1040 case 0: /* getpgrp */
1041 mutex_enter(proc_lock
);
1042 *retval
= p
->p_pgrp
->pg_id
;
1043 mutex_exit(proc_lock
);
1046 case 1: /* setpgrp */
1048 struct sys_setpgid_args sa
;
1050 SCARG(&sa
, pid
) = 0;
1051 SCARG(&sa
, pgid
) = 0;
1052 sys_setpgid(l
, &sa
, retval
);
1053 mutex_enter(proc_lock
);
1054 *retval
= p
->p_pgrp
->pg_id
;
1055 mutex_exit(proc_lock
);
1059 case 2: /* setpgid */
1061 struct sys_setpgid_args sa
;
1063 SCARG(&sa
, pid
) = SCARG(uap
, pid
);
1064 SCARG(&sa
, pgid
) = SCARG(uap
, pgid
);
1065 return sys_setpgid(l
, &sa
, retval
);
1068 case 3: /* setsid */
1069 return sys_setsid(l
, NULL
, retval
);
1077 * See http://docsrv.sco.com:507/en/man/html.S/plock.S.html
1079 * XXX - need to check for nested calls
1083 ibcs2_sys_plock(struct lwp
*l
, const struct ibcs2_sys_plock_args
*uap
, register_t
*retval
)
1086 syscallarg(int) cmd;
1088 #define IBCS2_UNLOCK 0
1089 #define IBCS2_PROCLOCK 1
1090 #define IBCS2_TEXTLOCK 2
1091 #define IBCS2_DATALOCK 4
1094 * NOTE: This is a privileged operation. Normally it would require root
1095 * access. When implementing, please make sure to use an appropriate
1096 * kauth(9) request. See the man-page for more information.
1099 switch(SCARG(uap
, cmd
)) {
1101 case IBCS2_PROCLOCK
:
1102 case IBCS2_TEXTLOCK
:
1103 case IBCS2_DATALOCK
:
1104 return 0; /* XXX - TODO */
1110 * See http://docsrv.sco.com:507/en/man/html.S/uadmin.S.html
1113 ibcs2_sys_uadmin(struct lwp
*l
, const struct ibcs2_sys_uadmin_args
*uap
, register_t
*retval
)
1116 syscallarg(int) cmd;
1117 syscallarg(int) func;
1118 syscallarg(void *) data;
1122 #define SCO_A_REBOOT 1
1123 #define SCO_A_SHUTDOWN 2
1124 #define SCO_A_REMOUNT 4
1125 #define SCO_A_CLOCK 8
1126 #define SCO_A_SETCONFIG 128
1127 #define SCO_A_GETDEV 130
1129 #define SCO_AD_HALT 0
1130 #define SCO_AD_BOOT 1
1131 #define SCO_AD_IBOOT 2
1132 #define SCO_AD_PWRDOWN 3
1133 #define SCO_AD_PWRNAP 4
1135 #define SCO_AD_PANICBOOT 1
1137 #define SCO_AD_GETBMAJ 0
1138 #define SCO_AD_GETCMAJ 1
1141 switch(SCARG(uap
, cmd
)) {
1143 case SCO_A_SHUTDOWN
:
1144 error
= kauth_authorize_system(l
->l_cred
, KAUTH_SYSTEM_REBOOT
,
1145 0, NULL
, NULL
, NULL
);
1149 switch(SCARG(uap
, func
)) {
1151 case SCO_AD_PWRDOWN
:
1153 cpu_reboot(RB_HALT
, NULL
);
1156 cpu_reboot(RB_AUTOBOOT
, NULL
);
1161 case SCO_A_SETCONFIG
:
1164 * NOTE: These are all privileged operations, that otherwise
1165 * would require root access or similar. When implementing,
1166 * please use appropriate kauth(9) requests. See the man-page
1167 * for more information.
1170 if (SCARG(uap
, cmd
) != SCO_A_GETDEV
)
1173 return EINVAL
; /* XXX - TODO */
1179 ibcs2_sys_sysfs(struct lwp
*l
, const struct ibcs2_sys_sysfs_args
*uap
, register_t
*retval
)
1182 syscallarg(int) cmd;
1183 syscallarg(void *) d1;
1184 syscallarg(char *) buf;
1187 #define IBCS2_GETFSIND 1
1188 #define IBCS2_GETFSTYP 2
1189 #define IBCS2_GETNFSTYP 3
1191 switch(SCARG(uap
, cmd
)) {
1192 case IBCS2_GETFSIND
:
1193 case IBCS2_GETFSTYP
:
1194 case IBCS2_GETNFSTYP
:
1197 return EINVAL
; /* XXX - TODO */
1201 xenix_sys_rdchk(struct lwp
*l
, const struct xenix_sys_rdchk_args
*uap
, register_t
*retval
)
1210 if ((fp
= fd_getfile(SCARG(uap
, fd
))) == NULL
)
1212 error
= (*fp
->f_ops
->fo_ioctl
)(fp
, FIONREAD
, &nbytes
);
1213 fd_putfile(SCARG(uap
, fd
));
1218 *retval
= nbytes
? 1 : 0;
1223 xenix_sys_chsize(struct lwp
*l
, const struct xenix_sys_chsize_args
*uap
, register_t
*retval
)
1227 syscallarg(long) size;
1229 struct sys_ftruncate_args sa
;
1231 SCARG(&sa
, fd
) = SCARG(uap
, fd
);
1232 SCARG(&sa
, PAD
) = 0;
1233 SCARG(&sa
, length
) = SCARG(uap
, size
);
1234 return sys_ftruncate(l
, &sa
, retval
);
1238 xenix_sys_nap(struct lwp
*l
, const struct xenix_sys_nap_args
*uap
, register_t
*retval
)
1241 syscallarg(long) millisec;
1244 struct timespec rqt
;
1245 struct timespec rmt
;
1248 rqt
.tv_nsec
= SCARG(uap
, millisec
) * 1000;
1249 error
= nanosleep1(l
, &rqt
, &rmt
);
1250 /* If interrupted we can either report EINTR, or the time left */
1251 if (error
!= 0 && error
!= EINTR
)
1253 *retval
= rmt
.tv_nsec
/ 1000;
1258 * mmap compat code borrowed from svr4/svr4_misc.c
1262 ibcs2_sys_mmap(struct lwp
*l
, const struct ibcs2_sys_mmap_args
*uap
, register_t
*retval
)
1265 syscallarg(ibcs2_void *) addr;
1266 syscallarg(ibcs2_size_t) len;
1267 syscallarg(int) prot;
1268 syscallarg(int) flags;
1270 syscallarg(ibcs2_off_t) off;
1272 struct sys_mmap_args mm
;
1274 #define _MAP_NEW 0x80000000 /* XXX why? */
1276 if (SCARG(uap
, prot
) & ~(PROT_READ
| PROT_WRITE
| PROT_EXEC
))
1278 if (SCARG(uap
, len
) == 0)
1281 SCARG(&mm
, prot
) = SCARG(uap
, prot
);
1282 SCARG(&mm
, len
) = SCARG(uap
, len
);
1283 SCARG(&mm
, flags
) = SCARG(uap
, flags
) & ~_MAP_NEW
;
1284 SCARG(&mm
, fd
) = SCARG(uap
, fd
);
1285 SCARG(&mm
, addr
) = SCARG(uap
, addr
);
1286 SCARG(&mm
, pos
) = SCARG(uap
, off
);
1288 return sys_mmap(l
, &mm
, retval
);
1292 ibcs2_sys_memcntl(struct lwp
*l
, const struct ibcs2_sys_memcntl_args
*uap
, register_t
*retval
)
1295 syscallarg(ibcs2_void *) addr;
1296 syscallarg(ibcs2_size_t) len;
1297 syscallarg(int) cmd;
1298 syscallarg(ibcs2_void *) arg;
1299 syscallarg(int) attr;
1300 syscallarg(int) mask;
1303 switch (SCARG(uap
, cmd
)) {
1306 struct sys___msync13_args msa
;
1308 SCARG(&msa
, addr
) = SCARG(uap
, addr
);
1309 SCARG(&msa
, len
) = SCARG(uap
, len
);
1310 SCARG(&msa
, flags
) = (int)SCARG(uap
, arg
);
1312 return sys___msync13(l
, &msa
, retval
);
1314 #ifdef IBCS2_MC_ADVISE /* supported? */
1315 case IBCS2_MC_ADVISE
:
1317 struct sys_madvise_args maa
;
1319 SCARG(&maa
, addr
) = SCARG(uap
, addr
);
1320 SCARG(&maa
, len
) = SCARG(uap
, len
);
1321 SCARG(&maa
, behav
) = (int)SCARG(uap
, arg
);
1323 return sys_madvise(l
, &maa
, retval
);
1327 case IBCS2_MC_UNLOCK
:
1328 case IBCS2_MC_LOCKAS
:
1329 case IBCS2_MC_UNLOCKAS
:
1337 ibcs2_sys_gettimeofday(struct lwp
*l
, const struct ibcs2_sys_gettimeofday_args
*uap
, register_t
*retval
)
1340 syscallarg(struct timeval *) tp;
1343 if (SCARG(uap
, tp
)) {
1347 return copyout(&atv
, SCARG(uap
, tp
), sizeof (atv
));
1354 ibcs2_sys_settimeofday(struct lwp
*l
, const struct ibcs2_sys_settimeofday_args
*uap
, register_t
*retval
)
1357 syscallarg(struct timeval *) tp;
1359 struct compat_50_sys_settimeofday_args ap
;
1361 SCARG(&ap
, tv
) = SCARG(uap
, tp
);
1362 SCARG(&ap
, tzp
) = NULL
;
1363 return compat_50_sys_settimeofday(l
, &ap
, retval
);
1367 ibcs2_sys_scoinfo(struct lwp
*l
, const struct ibcs2_sys_scoinfo_args
*uap
, register_t
*retval
)
1370 syscallarg(struct scoutsname *) bp;
1371 syscallarg(int) len;
1373 struct scoutsname uts
;
1375 (void)memset(&uts
, 0, sizeof(uts
));
1376 (void)strncpy(uts
.sysname
, ostype
, 8);
1377 (void)strncpy(uts
.nodename
, hostname
, 8);
1378 (void)strncpy(uts
.release
, osrelease
, 15);
1379 (void)strncpy(uts
.kid
, "kernel id 1", 19);
1380 (void)strncpy(uts
.machine
, machine
, 8);
1381 (void)strncpy(uts
.bustype
, "pci", 8);
1382 (void)strncpy(uts
.serial
, "1234", 9);
1385 (void)strncpy(uts
.nusers
, "unlim", 8);
1388 return copyout(&uts
, SCARG(uap
, bp
), sizeof(uts
));
1391 #define X_LK_UNLCK 0
1393 #define X_LK_NBLCK 20
1395 #define X_LK_NBRLCK 4
1396 #define X_LK_GETLK 5
1397 #define X_LK_SETLK 6
1398 #define X_LK_SETLKW 7
1399 #define X_LK_TESTLK 8
1402 xenix_sys_locking(struct lwp
*l
, const struct xenix_sys_locking_args
*uap
, register_t
*retval
)
1406 syscallarg(int) blk;
1407 syscallarg(int) size;
1412 switch SCARG(uap
, blk
) {
1416 return ibcs2_sys_fcntl(l
, (const void *)uap
, retval
);
1419 switch SCARG(uap
, blk
) {
1422 fl
.l_type
= F_UNLCK
;
1426 fl
.l_type
= F_WRLCK
;
1430 fl
.l_type
= F_RDLCK
;
1434 fl
.l_type
= F_RDLCK
;
1438 fl
.l_type
= F_WRLCK
;
1443 fl
.l_len
= SCARG(uap
, size
);
1445 fl
.l_whence
= SEEK_CUR
;
1447 return do_fcntl_lock(SCARG(uap
, fd
), cmd
, &fl
);