1 /* $NetBSD: svr4_misc.c,v 1.147 2009/11/04 21:23:03 rmind Exp $ */
4 * Copyright (c) 1994, 2008 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * SVR4 compatibility module.
35 * SVR4 system calls that are implemented differently in BSD are
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: svr4_misc.c,v 1.147 2009/11/04 21:23:03 rmind Exp $");
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/namei.h>
45 #include <sys/dirent.h>
50 #include <sys/filedesc.h>
51 #include <sys/ioctl.h>
52 #include <sys/kernel.h>
53 #include <sys/malloc.h>
57 #include <sys/mount.h>
58 #include <sys/resource.h>
59 #include <sys/resourcevar.h>
60 #include <sys/socket.h>
61 #include <sys/vnode.h>
64 #include <sys/utsname.h>
65 #include <sys/unistd.h>
66 #include <sys/vfs_syscalls.h>
67 #include <sys/times.h>
70 #include <sys/ptrace.h>
71 #include <sys/signalvar.h>
73 #include <netinet/in.h>
74 #include <sys/syscallargs.h>
76 #include <miscfs/specfs/specdev.h>
78 #include <compat/svr4/svr4_types.h>
79 #include <compat/svr4/svr4_signal.h>
80 #include <compat/svr4/svr4_lwp.h>
81 #include <compat/svr4/svr4_ucontext.h>
82 #include <compat/svr4/svr4_syscallargs.h>
83 #include <compat/svr4/svr4_util.h>
84 #include <compat/svr4/svr4_time.h>
85 #include <compat/svr4/svr4_dirent.h>
86 #include <compat/svr4/svr4_ulimit.h>
87 #include <compat/svr4/svr4_hrt.h>
88 #include <compat/svr4/svr4_wait.h>
89 #include <compat/svr4/svr4_statvfs.h>
90 #include <compat/svr4/svr4_sysconfig.h>
91 #include <compat/svr4/svr4_acl.h>
92 #include <compat/svr4/svr4_mman.h>
96 #include <uvm/uvm_extern.h>
98 static int svr4_to_bsd_mmap_flags(int);
100 static inline clock_t timeval_to_clock_t(struct timeval
*);
101 static void svr4_setinfo(int, struct rusage
*, int, svr4_siginfo_t
*);
103 struct svr4_hrtcntl_args
;
104 static int svr4_hrtcntl(struct lwp
*, const struct svr4_hrtcntl_args
*,
106 #define svr4_pfind(pid) p_find((pid), PFIND_UNLOCK | PFIND_ZOMBIE)
108 static int svr4_mknod(struct lwp
*, register_t
*, const char *,
109 svr4_mode_t
, svr4_dev_t
);
112 svr4_sys_wait(struct lwp
*l
, const struct svr4_sys_wait_args
*uap
,
115 int error
, st
, sig
, pid
= WAIT_ANY
;
117 error
= do_sys_wait(&pid
, &st
, 0, NULL
);
123 if (WIFSIGNALED(st
)) {
125 if (sig
>= 0 && sig
< NSIG
)
126 st
= (st
& ~0177) | native_to_svr4_signo
[sig
];
127 } else if (WIFSTOPPED(st
)) {
129 if (sig
>= 0 && sig
< NSIG
)
130 st
= (st
& ~0xff00) | (native_to_svr4_signo
[sig
] << 8);
134 * It looks like wait(2) on svr4/solaris/2.4 returns
135 * the status in retval[1], and the pid on retval[0].
139 if (SCARG(uap
, status
))
140 error
= copyout(&st
, SCARG(uap
, status
), sizeof(st
));
147 svr4_sys_execv(struct lwp
*l
, const struct svr4_sys_execv_args
*uap
, register_t
*retval
)
150 syscallarg(char *) path;
151 syscallarg(char **) argv;
153 struct sys_execve_args ap
;
155 SCARG(&ap
, path
) = SCARG(uap
, path
);
156 SCARG(&ap
, argp
) = SCARG(uap
, argp
);
157 SCARG(&ap
, envp
) = NULL
;
159 return sys_execve(l
, &ap
, retval
);
164 svr4_sys_execve(struct lwp
*l
, const struct svr4_sys_execve_args
*uap
, register_t
*retval
)
167 syscallarg(const char *) path;
168 syscallarg(char **) argv;
169 syscallarg(char **) envp;
171 struct sys_execve_args ap
;
173 SCARG(&ap
, path
) = SCARG(uap
, path
);
174 SCARG(&ap
, argp
) = SCARG(uap
, argp
);
175 SCARG(&ap
, envp
) = SCARG(uap
, envp
);
177 return sys_execve(l
, &ap
, retval
);
182 svr4_sys_time(struct lwp
*l
, const struct svr4_sys_time_args
*uap
, register_t
*retval
)
189 error
= copyout(&tv
.tv_sec
, SCARG(uap
, t
),
190 sizeof(*(SCARG(uap
, t
))));
191 *retval
= (int) tv
.tv_sec
;
198 * Read SVR4-style directory entries. We suck them into kernel space so
199 * that they can be massaged before being copied out to user code. Like
200 * SunOS, we squish out `empty' entries.
202 * This is quite ugly, but what do you expect from compatibility code?
205 svr4_sys_getdents64(struct lwp
*l
, const struct svr4_sys_getdents64_args
*uap
, register_t
*retval
)
209 char *inp
, *tbuf
; /* BSD-format */
210 int len
, reclen
; /* BSD-format */
211 char *outp
; /* SVR4-format */
212 int resid
, svr4_reclen
; /* SVR4-format */
216 struct svr4_dirent64 idb
;
217 off_t off
; /* true file offset */
218 int buflen
, error
, eofflag
;
219 off_t
*cookiebuf
= NULL
, *cookie
;
222 /* fd_getvnode() will use the descriptor for us */
223 if ((error
= fd_getvnode(SCARG(uap
, fd
), &fp
)) != 0)
226 if ((fp
->f_flag
& FREAD
) == 0) {
231 vp
= (struct vnode
*)fp
->f_data
;
232 if (vp
->v_type
!= VDIR
) {
237 buflen
= min(MAXBSIZE
, SCARG(uap
, nbytes
));
238 tbuf
= malloc(buflen
, M_TEMP
, M_WAITOK
);
239 vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
);
242 aiov
.iov_base
= tbuf
;
243 aiov
.iov_len
= buflen
;
244 auio
.uio_iov
= &aiov
;
246 auio
.uio_rw
= UIO_READ
;
247 auio
.uio_resid
= buflen
;
248 auio
.uio_offset
= off
;
249 UIO_SETUP_SYSSPACE(&auio
);
251 * First we read into the malloc'ed buffer, then
252 * we massage it into user space, one record at a time.
254 error
= VOP_READDIR(vp
, &auio
, fp
->f_cred
, &eofflag
, &cookiebuf
,
260 outp
= (char *) SCARG(uap
, dp
);
261 resid
= SCARG(uap
, nbytes
);
262 if ((len
= buflen
- auio
.uio_resid
) == 0)
265 for (cookie
= cookiebuf
; len
> 0; len
-= reclen
) {
266 bdp
= (struct dirent
*)inp
;
267 reclen
= bdp
->d_reclen
;
269 panic("svr4_getdents64: bad reclen");
270 if (bdp
->d_fileno
== 0) {
271 inp
+= reclen
; /* it is a hole; squish it out */
278 svr4_reclen
= SVR4_RECLEN(&idb
, bdp
->d_namlen
);
279 if (reclen
> len
|| resid
< svr4_reclen
) {
280 /* entry too big for buffer, so just stop */
285 off
= *cookie
++; /* each entry points to the next */
289 * Massage in place to make a SVR4-shaped dirent (otherwise
290 * we have to worry about touching user memory outside of
291 * the copyout() call).
293 idb
.d_ino
= (svr4_ino64_t
)bdp
->d_fileno
;
294 idb
.d_off
= (svr4_off64_t
)off
;
295 idb
.d_reclen
= (u_short
)svr4_reclen
;
296 strlcpy(idb
.d_name
, bdp
->d_name
, sizeof(idb
.d_name
));
297 if ((error
= copyout((void *)&idb
, outp
, svr4_reclen
)))
299 /* advance past this real entry */
301 /* advance output past SVR4-shaped entry */
303 resid
-= svr4_reclen
;
306 /* if we squished out the whole block, try again */
307 if (outp
== (char *) SCARG(uap
, dp
))
309 fp
->f_offset
= off
; /* update the vnode offset */
312 *retval
= SCARG(uap
, nbytes
) - resid
;
316 free(cookiebuf
, M_TEMP
);
319 fd_putfile(SCARG(uap
, fd
));
325 svr4_sys_getdents(struct lwp
*l
, const struct svr4_sys_getdents_args
*uap
, register_t
*retval
)
329 char *inp
, *tbuf
; /* BSD-format */
330 int len
, reclen
; /* BSD-format */
331 char *outp
; /* SVR4-format */
332 int resid
, svr4_reclen
; /* SVR4-format */
336 struct svr4_dirent idb
;
337 off_t off
; /* true file offset */
338 int buflen
, error
, eofflag
;
339 off_t
*cookiebuf
= NULL
, *cookie
;
342 /* fd_getvnode() will use the descriptor for us */
343 if ((error
= fd_getvnode(SCARG(uap
, fd
), &fp
)) != 0)
346 if ((fp
->f_flag
& FREAD
) == 0) {
351 vp
= (struct vnode
*)fp
->f_data
;
352 if (vp
->v_type
!= VDIR
) {
357 buflen
= min(MAXBSIZE
, SCARG(uap
, nbytes
));
358 tbuf
= malloc(buflen
, M_TEMP
, M_WAITOK
);
359 vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
);
362 aiov
.iov_base
= tbuf
;
363 aiov
.iov_len
= buflen
;
364 auio
.uio_iov
= &aiov
;
366 auio
.uio_rw
= UIO_READ
;
367 auio
.uio_resid
= buflen
;
368 auio
.uio_offset
= off
;
369 UIO_SETUP_SYSSPACE(&auio
);
371 * First we read into the malloc'ed buffer, then
372 * we massage it into user space, one record at a time.
374 error
= VOP_READDIR(vp
, &auio
, fp
->f_cred
, &eofflag
, &cookiebuf
,
380 outp
= SCARG(uap
, buf
);
381 resid
= SCARG(uap
, nbytes
);
382 if ((len
= buflen
- auio
.uio_resid
) == 0)
385 for (cookie
= cookiebuf
; len
> 0; len
-= reclen
) {
386 bdp
= (struct dirent
*)inp
;
387 reclen
= bdp
->d_reclen
;
389 panic("svr4_getdents: bad reclen");
391 off
= *cookie
++; /* each entry points to the next */
394 if ((off
>> 32) != 0) {
395 compat_offseterr(vp
, "svr4_getdents");
399 if (bdp
->d_fileno
== 0) {
400 inp
+= reclen
; /* it is a hole; squish it out */
403 svr4_reclen
= SVR4_RECLEN(&idb
, bdp
->d_namlen
);
404 if (reclen
> len
|| resid
< svr4_reclen
) {
405 /* entry too big for buffer, so just stop */
410 * Massage in place to make a SVR4-shaped dirent (otherwise
411 * we have to worry about touching user memory outside of
412 * the copyout() call).
414 idb
.d_ino
= (svr4_ino_t
)bdp
->d_fileno
;
415 idb
.d_off
= (svr4_off_t
)off
;
416 idb
.d_reclen
= (u_short
)svr4_reclen
;
417 strlcpy(idb
.d_name
, bdp
->d_name
, sizeof(idb
.d_name
));
418 if ((error
= copyout((void *)&idb
, outp
, svr4_reclen
)))
420 /* advance past this real entry */
422 /* advance output past SVR4-shaped entry */
424 resid
-= svr4_reclen
;
427 /* if we squished out the whole block, try again */
428 if (outp
== SCARG(uap
, buf
))
430 fp
->f_offset
= off
; /* update the vnode offset */
433 *retval
= SCARG(uap
, nbytes
) - resid
;
437 free(cookiebuf
, M_TEMP
);
440 fd_putfile(SCARG(uap
, fd
));
446 svr4_to_bsd_mmap_flags(int f
)
448 int type
= f
& SVR4_MAP_TYPE
;
451 if (type
!= MAP_PRIVATE
&& type
!= MAP_SHARED
)
454 nf
= f
& SVR4_MAP_COPYFLAGS
;
455 if (f
& SVR4_MAP_ANON
)
463 svr4_sys_mmap(struct lwp
*l
, const struct svr4_sys_mmap_args
*uap
, register_t
*retval
)
465 struct sys_mmap_args mm
;
467 * Verify the arguments.
469 if (SCARG(uap
, prot
) & ~(PROT_READ
| PROT_WRITE
| PROT_EXEC
))
470 return EINVAL
; /* XXX still needed? */
472 if (SCARG(uap
, len
) == 0)
475 if ((SCARG(&mm
, flags
) = svr4_to_bsd_mmap_flags(SCARG(uap
, flags
))) == -1)
478 SCARG(&mm
, prot
) = SCARG(uap
, prot
);
479 SCARG(&mm
, len
) = SCARG(uap
, len
);
480 SCARG(&mm
, fd
) = SCARG(uap
, fd
);
481 SCARG(&mm
, addr
) = SCARG(uap
, addr
);
482 SCARG(&mm
, pos
) = SCARG(uap
, pos
);
484 return sys_mmap(l
, &mm
, retval
);
489 svr4_sys_mmap64(struct lwp
*l
, const struct svr4_sys_mmap64_args
*uap
, register_t
*retval
)
491 struct sys_mmap_args mm
;
493 * Verify the arguments.
495 if (SCARG(uap
, prot
) & ~(PROT_READ
| PROT_WRITE
| PROT_EXEC
))
496 return EINVAL
; /* XXX still needed? */
498 if (SCARG(uap
, len
) == 0)
501 if ((SCARG(&mm
, flags
) = svr4_to_bsd_mmap_flags(SCARG(uap
, flags
))) == -1)
504 SCARG(&mm
, prot
) = SCARG(uap
, prot
);
505 SCARG(&mm
, len
) = SCARG(uap
, len
);
506 SCARG(&mm
, fd
) = SCARG(uap
, fd
);
507 SCARG(&mm
, addr
) = SCARG(uap
, addr
);
508 SCARG(&mm
, pos
) = SCARG(uap
, pos
);
510 return sys_mmap(l
, &mm
, retval
);
515 svr4_mknod(struct lwp
*l
, register_t
*retval
, const char *path
, svr4_mode_t mode
, svr4_dev_t dev
)
517 if (S_ISFIFO(mode
)) {
518 struct sys_mkfifo_args ap
;
519 SCARG(&ap
, path
) = path
;
520 SCARG(&ap
, mode
) = mode
;
521 return sys_mkfifo(l
, &ap
, retval
);
523 return do_sys_mknod(l
, path
, mode
, dev
, retval
, UIO_USERSPACE
);
529 svr4_sys_mknod(struct lwp
*l
, const struct svr4_sys_mknod_args
*uap
, register_t
*retval
)
531 return svr4_mknod(l
, retval
,
532 SCARG(uap
, path
), SCARG(uap
, mode
),
533 svr4_to_bsd_odev_t(SCARG(uap
, dev
)));
538 svr4_sys_xmknod(struct lwp
*l
, const struct svr4_sys_xmknod_args
*uap
, register_t
*retval
)
540 return svr4_mknod(l
, retval
,
541 SCARG(uap
, path
), SCARG(uap
, mode
),
542 svr4_to_bsd_dev_t(SCARG(uap
, dev
)));
547 svr4_sys_vhangup(struct lwp
*l
, const void *v
, register_t
*retval
)
554 svr4_sys_sysconfig(struct lwp
*l
, const struct svr4_sys_sysconfig_args
*uap
, register_t
*retval
)
558 switch (SCARG(uap
, name
)) {
559 case SVR4_CONFIG_NGROUPS
:
560 *retval
= NGROUPS_MAX
;
562 case SVR4_CONFIG_CHILD_MAX
:
565 case SVR4_CONFIG_OPEN_FILES
:
568 case SVR4_CONFIG_POSIX_VER
:
571 case SVR4_CONFIG_PAGESIZE
:
574 case SVR4_CONFIG_CLK_TCK
:
575 *retval
= 60; /* should this be `hz', ie. 100? */
577 case SVR4_CONFIG_XOPEN_VER
:
578 *retval
= 2; /* XXX: What should that be? */
580 case SVR4_CONFIG_PROF_TCK
:
581 *retval
= 60; /* XXX: What should that be? */
583 case SVR4_CONFIG_NPROC_CONF
:
584 *retval
= 1; /* Only one processor for now */
586 case SVR4_CONFIG_NPROC_ONLN
:
587 *retval
= 1; /* And it better be online */
589 case SVR4_CONFIG_AIO_LISTIO_MAX
:
590 case SVR4_CONFIG_AIO_MAX
:
591 case SVR4_CONFIG_AIO_PRIO_DELTA_MAX
:
592 *retval
= 0; /* No aio support */
594 case SVR4_CONFIG_DELAYTIMER_MAX
:
595 *retval
= 0; /* No delaytimer support */
597 case SVR4_CONFIG_MQ_OPEN_MAX
:
599 *retval
= msginfo
.msgmni
;
604 case SVR4_CONFIG_MQ_PRIO_MAX
:
605 *retval
= 0; /* XXX: Don't know */
607 case SVR4_CONFIG_RTSIG_MAX
:
610 case SVR4_CONFIG_SEM_NSEMS_MAX
:
612 *retval
= seminfo
.semmni
;
617 case SVR4_CONFIG_SEM_VALUE_MAX
:
619 *retval
= seminfo
.semvmx
;
624 case SVR4_CONFIG_SIGQUEUE_MAX
:
625 *retval
= 0; /* XXX: Don't know */
627 case SVR4_CONFIG_SIGRT_MIN
:
628 case SVR4_CONFIG_SIGRT_MAX
:
629 *retval
= 0; /* No real time signals */
631 case SVR4_CONFIG_TIMER_MAX
:
632 *retval
= 3; /* XXX: real, virtual, profiling */
634 case SVR4_CONFIG_PHYS_PAGES
:
635 *retval
= uvmexp
.free
; /* XXX: free instead of total */
637 case SVR4_CONFIG_AVPHYS_PAGES
:
638 uvm_estimatepageable(&active
, NULL
);
639 *retval
= active
; /* XXX: active instead of avg */
641 case SVR4_CONFIG_COHERENCY
:
642 *retval
= 0; /* XXX */
644 case SVR4_CONFIG_SPLIT_CACHE
:
645 *retval
= 0; /* XXX */
647 case SVR4_CONFIG_ICACHESZ
:
648 *retval
= 256; /* XXX */
650 case SVR4_CONFIG_DCACHESZ
:
651 *retval
= 256; /* XXX */
653 case SVR4_CONFIG_ICACHELINESZ
:
654 *retval
= 64; /* XXX */
656 case SVR4_CONFIG_DCACHELINESZ
:
657 *retval
= 64; /* XXX */
659 case SVR4_CONFIG_ICACHEBLKSZ
:
660 *retval
= 64; /* XXX */
662 case SVR4_CONFIG_DCACHEBLKSZ
:
663 *retval
= 64; /* XXX */
665 case SVR4_CONFIG_DCACHETBLKSZ
:
666 *retval
= 64; /* XXX */
668 case SVR4_CONFIG_ICACHE_ASSOC
:
669 *retval
= 1; /* XXX */
671 case SVR4_CONFIG_DCACHE_ASSOC
:
672 *retval
= 1; /* XXX */
674 case SVR4_CONFIG_MAXPID
:
677 case SVR4_CONFIG_STACK_PROT
:
678 *retval
= PROT_READ
|PROT_WRITE
|PROT_EXEC
;
688 svr4_sys_break(struct lwp
*l
, const struct svr4_sys_break_args
*uap
, register_t
*retval
)
690 struct proc
*p
= l
->l_proc
;
691 struct vmspace
*vm
= p
->p_vmspace
;
695 old
= (vaddr_t
) vm
->vm_daddr
;
696 new = round_page((vaddr_t
)SCARG(uap
, nsize
));
698 if (new - old
> p
->p_rlimit
[RLIMIT_DATA
].rlim_cur
&& new > old
)
701 old
= round_page(old
+ ctob(vm
->vm_dsize
));
702 DPRINTF(("break(2): dsize = %x ctob %x\n",
703 vm
->vm_dsize
, ctob(vm
->vm_dsize
)));
706 error
= uvm_map(&vm
->vm_map
, &old
, new - old
, NULL
,
707 UVM_UNKNOWN_OFFSET
, 0,
708 UVM_MAPFLAG(UVM_PROT_ALL
, UVM_PROT_ALL
, UVM_INH_COPY
,
710 UVM_FLAG_AMAPPAD
|UVM_FLAG_FIXED
|
711 UVM_FLAG_OVERLAY
|UVM_FLAG_COPYONW
));
713 uprintf("sbrk: grow failed, error = %d\n", error
);
716 vm
->vm_dsize
+= btoc(new - old
);
717 } else if (new < old
) {
718 uvm_deallocate(&vm
->vm_map
, new, old
- new);
719 vm
->vm_dsize
-= btoc(old
- new);
725 static inline clock_t
726 timeval_to_clock_t(struct timeval
*tv
)
728 return tv
->tv_sec
* hz
+ tv
->tv_usec
/ (1000000 / hz
);
733 svr4_sys_times(struct lwp
*l
, const struct svr4_sys_times_args
*uap
, register_t
*retval
)
737 struct rusage ru
, *rup
;
738 struct proc
*p
= l
->l_proc
;
740 ru
= p
->p_stats
->p_ru
;
741 mutex_enter(p
->p_lock
);
742 calcru(p
, &ru
.ru_utime
, &ru
.ru_stime
, NULL
, NULL
);
744 mutex_exit(p
->p_lock
);
746 tms
.tms_utime
= timeval_to_clock_t(&ru
.ru_utime
);
747 tms
.tms_stime
= timeval_to_clock_t(&ru
.ru_stime
);
749 rup
= &p
->p_stats
->p_cru
;
750 tms
.tms_cutime
= timeval_to_clock_t(&rup
->ru_utime
);
751 tms
.tms_cstime
= timeval_to_clock_t(&rup
->ru_stime
);
754 *retval
= timeval_to_clock_t(&t
);
756 return copyout(&tms
, SCARG(uap
, tp
), sizeof(tms
));
761 svr4_sys_ulimit(struct lwp
*l
, const struct svr4_sys_ulimit_args
*uap
, register_t
*retval
)
763 struct proc
*p
= l
->l_proc
;
768 switch (SCARG(uap
, cmd
)) {
770 r
= p
->p_rlimit
[RLIMIT_FSIZE
].rlim_cur
/ 512;
774 krl
.rlim_cur
= SCARG(uap
, newlimit
) * 512;
775 krl
.rlim_max
= p
->p_rlimit
[RLIMIT_FSIZE
].rlim_max
;
777 error
= dosetrlimit(l
, l
->l_proc
, RLIMIT_FSIZE
, &krl
);
781 r
= p
->p_rlimit
[RLIMIT_FSIZE
].rlim_cur
;
785 r
= p
->p_rlimit
[RLIMIT_DATA
].rlim_cur
;
788 r
+= (long)p
->p_vmspace
->vm_daddr
;
792 r
= p
->p_rlimit
[RLIMIT_NOFILE
].rlim_cur
;
799 *retval
= r
> 0x7fffffff ? 0x7fffffff : r
;
805 svr4_sys_pgrpsys(struct lwp
*l
, const struct svr4_sys_pgrpsys_args
*uap
, register_t
*retval
)
807 struct proc
*p
= l
->l_proc
;
809 switch (SCARG(uap
, cmd
)) {
810 case 1: /* setpgrp() */
812 * SVR4 setpgrp() (which takes no arguments) has the
813 * semantics that the session ID is also created anew, so
814 * in almost every sense, setpgrp() is identical to
815 * setsid() for SVR4. (Under BSD, the difference is that
816 * a setpgid(0,0) will not create a new session.)
818 sys_setsid(l
, NULL
, retval
);
821 case 0: /* getpgrp() */
822 mutex_enter(proc_lock
);
823 *retval
= p
->p_pgrp
->pg_id
;
824 mutex_exit(proc_lock
);
827 case 2: /* getsid(pid) */
828 mutex_enter(proc_lock
);
829 if (SCARG(uap
, pid
) != 0 &&
830 (p
= p_find(SCARG(uap
, pid
), PFIND_LOCKED
| PFIND_ZOMBIE
)) == NULL
) {
831 mutex_exit(proc_lock
);
835 * This has already been initialized to the pid of
836 * the session leader.
838 *retval
= (register_t
) p
->p_session
->s_sid
;
839 mutex_exit(proc_lock
);
842 case 3: /* setsid() */
843 return sys_setsid(l
, NULL
, retval
);
845 case 4: /* getpgid(pid) */
846 mutex_enter(proc_lock
);
847 if (SCARG(uap
, pid
) != 0 &&
848 (p
= p_find(SCARG(uap
, pid
), PFIND_LOCKED
| PFIND_ZOMBIE
)) == NULL
) {
849 mutex_exit(proc_lock
);
853 *retval
= (int) p
->p_pgrp
->pg_id
;
854 mutex_exit(proc_lock
);
857 case 5: /* setpgid(pid, pgid); */
859 struct sys_setpgid_args sa
;
861 SCARG(&sa
, pid
) = SCARG(uap
, pid
);
862 SCARG(&sa
, pgid
) = SCARG(uap
, pgid
);
863 return sys_setpgid(l
, &sa
, retval
);
871 struct svr4_hrtcntl_args
{
875 syscallarg(svr4_hrt_interval_t
*) iv
;
876 syscallarg(svr4_hrt_time_t
*) ti
;
881 svr4_hrtcntl(struct lwp
*l
, const struct svr4_hrtcntl_args
*uap
,
884 switch (SCARG(uap
, fun
)) {
885 case SVR4_HRT_CNTL_RES
:
886 DPRINTF(("htrcntl(RES)\n"));
887 *retval
= SVR4_HRT_USEC
;
890 case SVR4_HRT_CNTL_TOFD
:
891 DPRINTF(("htrcntl(TOFD)\n"));
895 if (SCARG(uap
, clk
) != SVR4_HRT_CLK_STD
) {
896 DPRINTF(("clk == %d\n", SCARG(uap
, clk
)));
899 if (SCARG(uap
, ti
) == NULL
) {
900 DPRINTF(("ti NULL\n"));
905 t
.h_rem
= tv
.tv_usec
;
906 t
.h_res
= SVR4_HRT_USEC
;
907 return copyout(&t
, SCARG(uap
, ti
), sizeof(t
));
910 case SVR4_HRT_CNTL_START
:
911 DPRINTF(("htrcntl(START)\n"));
914 case SVR4_HRT_CNTL_GET
:
915 DPRINTF(("htrcntl(GET)\n"));
918 DPRINTF(("Bad htrcntl command %d\n", SCARG(uap
, fun
)));
925 svr4_sys_hrtsys(struct lwp
*l
, const struct svr4_sys_hrtsys_args
*uap
, register_t
*retval
)
928 switch (SCARG(uap
, cmd
)) {
930 return svr4_hrtcntl(l
, (const struct svr4_hrtcntl_args
*) uap
,
934 DPRINTF(("hrtalarm\n"));
938 DPRINTF(("hrtsleep\n"));
942 DPRINTF(("hrtcancel\n"));
946 DPRINTF(("Bad hrtsys command %d\n", SCARG(uap
, cmd
)));
953 svr4_setinfo(int pid
, struct rusage
*ru
, int st
, svr4_siginfo_t
*s
)
957 memset(s
, 0, sizeof(*s
));
959 s
->si_signo
= SVR4_SIGCHLD
;
960 s
->si_errno
= 0; /* XXX? */
964 s
->si_stime
= ru
->ru_stime
.tv_sec
;
965 s
->si_utime
= ru
->ru_utime
.tv_sec
;
969 s
->si_status
= WEXITSTATUS(st
);
970 s
->si_code
= SVR4_CLD_EXITED
;
971 } else if (WIFSTOPPED(st
)) {
973 if (sig
>= 0 && sig
< NSIG
)
974 s
->si_status
= native_to_svr4_signo
[sig
];
976 if (s
->si_status
== SVR4_SIGCONT
)
977 s
->si_code
= SVR4_CLD_CONTINUED
;
979 s
->si_code
= SVR4_CLD_STOPPED
;
982 if (sig
>= 0 && sig
< NSIG
)
983 s
->si_status
= native_to_svr4_signo
[sig
];
986 s
->si_code
= SVR4_CLD_DUMPED
;
988 s
->si_code
= SVR4_CLD_KILLED
;
991 DPRINTF(("siginfo [pid %ld signo %d code %d errno %d status %d]\n",
993 s
->si_signo
, s
->si_code
, s
->si_errno
, s
->si_status
));
998 svr4_sys_waitsys(struct lwp
*l
, const struct svr4_sys_waitsys_args
*uap
, register_t
*retval
)
1000 int options
, status
;
1004 int id
= SCARG(uap
, id
);
1006 switch (SCARG(uap
, grp
)) {
1011 mutex_enter(proc_lock
);
1012 id
= -l
->l_proc
->p_pgid
;
1013 mutex_exit(proc_lock
);
1024 /* Translate options */
1025 options
= WOPTSCHECKED
;
1026 if (SCARG(uap
, options
) & SVR4_WNOWAIT
)
1028 if (SCARG(uap
, options
) & SVR4_WNOHANG
)
1030 if ((SCARG(uap
, options
) & (SVR4_WEXITED
|SVR4_WTRAPPED
)) == 0)
1031 options
|= WNOZOMBIE
;
1032 if (SCARG(uap
, options
) & (SVR4_WSTOPPED
|SVR4_WCONTINUED
))
1033 options
|= WUNTRACED
;
1035 DPRINTF(("waitsys(%d, %d, %p, %x)\n",
1036 SCARG(uap
, grp
), id
,
1037 SCARG(uap
, info
), SCARG(uap
, options
)));
1039 error
= do_sys_wait(&id
, &status
, options
, &ru
);
1045 svr4_setinfo(id
, &ru
, status
, &i
);
1046 return copyout(&i
, SCARG(uap
, info
), sizeof(i
));
1051 svr4_copyout_statvfs(const struct statvfs
*bfs
, struct svr4_statvfs
*sufs
)
1053 struct svr4_statvfs
*sfs
= malloc(sizeof(*sfs
), M_TEMP
, M_WAITOK
);
1056 sfs
->f_bsize
= bfs
->f_bsize
;
1057 sfs
->f_frsize
= bfs
->f_frsize
;
1058 sfs
->f_blocks
= bfs
->f_blocks
;
1059 sfs
->f_bfree
= bfs
->f_bfree
;
1060 sfs
->f_bavail
= bfs
->f_bavail
;
1061 sfs
->f_files
= bfs
->f_files
;
1062 sfs
->f_ffree
= bfs
->f_ffree
;
1063 sfs
->f_favail
= bfs
->f_favail
;
1064 sfs
->f_fsid
= bfs
->f_fsidx
.__fsid_val
[0];
1065 memcpy(sfs
->f_basetype
, bfs
->f_fstypename
, sizeof(sfs
->f_basetype
));
1067 if (bfs
->f_flag
& MNT_RDONLY
)
1068 sfs
->f_flag
|= SVR4_ST_RDONLY
;
1069 if (bfs
->f_flag
& MNT_NOSUID
)
1070 sfs
->f_flag
|= SVR4_ST_NOSUID
;
1071 sfs
->f_namemax
= MAXNAMLEN
;
1072 memcpy(sfs
->f_fstr
, bfs
->f_fstypename
, sizeof(sfs
->f_fstr
)); /* XXX */
1073 memset(sfs
->f_filler
, 0, sizeof(sfs
->f_filler
));
1075 error
= copyout(sfs
, sufs
, sizeof(*sfs
));
1083 svr4_copyout_statvfs64(const struct statvfs
*bfs
, struct svr4_statvfs64
*sufs
)
1085 struct svr4_statvfs64
*sfs
= malloc(sizeof(*sfs
), M_TEMP
, M_WAITOK
);
1088 sfs
->f_bsize
= bfs
->f_bsize
;
1089 sfs
->f_frsize
= bfs
->f_frsize
;
1090 sfs
->f_blocks
= bfs
->f_blocks
;
1091 sfs
->f_bfree
= bfs
->f_bfree
;
1092 sfs
->f_bavail
= bfs
->f_bavail
;
1093 sfs
->f_files
= bfs
->f_files
;
1094 sfs
->f_ffree
= bfs
->f_ffree
;
1095 sfs
->f_favail
= bfs
->f_ffree
;
1096 sfs
->f_fsid
= bfs
->f_fsidx
.__fsid_val
[0];
1097 memcpy(sfs
->f_basetype
, bfs
->f_fstypename
, sizeof(sfs
->f_basetype
));
1099 if (bfs
->f_flag
& MNT_RDONLY
)
1100 sfs
->f_flag
|= SVR4_ST_RDONLY
;
1101 if (bfs
->f_flag
& MNT_NOSUID
)
1102 sfs
->f_flag
|= SVR4_ST_NOSUID
;
1103 sfs
->f_namemax
= MAXNAMLEN
;
1104 memcpy(sfs
->f_fstr
, bfs
->f_fstypename
, sizeof(sfs
->f_fstr
)); /* XXX */
1105 memset(sfs
->f_filler
, 0, sizeof(sfs
->f_filler
));
1107 error
= copyout(sfs
, sufs
, sizeof(*sfs
));
1115 svr4_sys_statvfs(struct lwp
*l
, const struct svr4_sys_statvfs_args
*uap
, register_t
*retval
)
1120 sb
= STATVFSBUF_GET();
1121 error
= do_sys_pstatvfs(l
, SCARG(uap
, path
), ST_WAIT
, sb
);
1123 error
= svr4_copyout_statvfs(sb
, SCARG(uap
, fs
));
1130 svr4_sys_fstatvfs(struct lwp
*l
, const struct svr4_sys_fstatvfs_args
*uap
, register_t
*retval
)
1135 sb
= STATVFSBUF_GET();
1136 error
= do_sys_fstatvfs(l
, SCARG(uap
, fd
), ST_WAIT
, sb
);
1138 error
= svr4_copyout_statvfs(sb
, SCARG(uap
, fs
));
1145 svr4_sys_statvfs64(struct lwp
*l
, const struct svr4_sys_statvfs64_args
*uap
, register_t
*retval
)
1150 sb
= STATVFSBUF_GET();
1151 error
= do_sys_pstatvfs(l
, SCARG(uap
, path
), ST_WAIT
, sb
);
1153 error
= svr4_copyout_statvfs64(sb
, SCARG(uap
, fs
));
1160 svr4_sys_fstatvfs64(struct lwp
*l
, const struct svr4_sys_fstatvfs64_args
*uap
, register_t
*retval
)
1165 sb
= STATVFSBUF_GET();
1166 error
= do_sys_fstatvfs(l
, SCARG(uap
, fd
), ST_WAIT
, sb
);
1168 error
= svr4_copyout_statvfs64(sb
, SCARG(uap
, fs
));
1174 svr4_sys_alarm(struct lwp
*l
, const struct svr4_sys_alarm_args
*uap
, register_t
*retval
)
1176 struct itimerval tp
;
1178 dogetitimer(l
->l_proc
, ITIMER_REAL
, &tp
);
1179 if (tp
.it_value
.tv_usec
)
1180 tp
.it_value
.tv_sec
++;
1181 *retval
= (register_t
)tp
.it_value
.tv_sec
;
1183 timerclear(&tp
.it_interval
);
1184 tp
.it_value
.tv_sec
= SCARG(uap
, sec
);
1185 tp
.it_value
.tv_usec
= 0;
1187 return dosetitimer(l
->l_proc
, ITIMER_REAL
, &tp
);
1192 svr4_sys_gettimeofday(struct lwp
*l
, const struct svr4_sys_gettimeofday_args
*uap
, register_t
*retval
)
1195 if (SCARG(uap
, tp
)) {
1199 return copyout(&atv
, SCARG(uap
, tp
), sizeof (atv
));
1207 svr4_sys_facl(struct lwp
*l
, const struct svr4_sys_facl_args
*uap
, register_t
*retval
)
1212 switch (SCARG(uap
, cmd
)) {
1213 case SVR4_SYS_SETACL
:
1214 /* We don't support acls on any filesystem */
1217 case SVR4_SYS_GETACL
:
1222 * XXX This code is completly borked, no idea what it was
1225 return copyout(retval
, &SCARG(uap
, num
),
1226 sizeof(SCARG(uap
, num
)));
1229 case SVR4_SYS_GETACLCNT
:
1239 svr4_sys_acl(struct lwp
*l
, const struct svr4_sys_acl_args
*uap
, register_t
*retval
)
1241 return svr4_sys_facl(l
, (const void *)uap
, retval
); /* XXX: for now the same */
1246 svr4_sys_auditsys(struct lwp
*l
, const struct svr4_sys_auditsys_args
*uap
, register_t
*retval
)
1249 * XXX: Big brother is *not* watching.
1256 svr4_sys_memcntl(struct lwp
*l
, const struct svr4_sys_memcntl_args
*uap
, register_t
*retval
)
1258 switch (SCARG(uap
, cmd
)) {
1261 struct sys___msync13_args msa
;
1263 SCARG(&msa
, addr
) = SCARG(uap
, addr
);
1264 SCARG(&msa
, len
) = SCARG(uap
, len
);
1265 SCARG(&msa
, flags
) = (int)(u_long
)SCARG(uap
, arg
);
1267 return sys___msync13(l
, &msa
, retval
);
1269 case SVR4_MC_ADVISE
:
1271 struct sys_madvise_args maa
;
1273 SCARG(&maa
, addr
) = SCARG(uap
, addr
);
1274 SCARG(&maa
, len
) = SCARG(uap
, len
);
1275 SCARG(&maa
, behav
) = (int)(u_long
)SCARG(uap
, arg
);
1277 return sys_madvise(l
, &maa
, retval
);
1280 case SVR4_MC_UNLOCK
:
1281 case SVR4_MC_LOCKAS
:
1282 case SVR4_MC_UNLOCKAS
:
1291 svr4_sys_nice(struct lwp
*l
, const struct svr4_sys_nice_args
*uap
, register_t
*retval
)
1293 struct sys_setpriority_args ap
;
1296 SCARG(&ap
, which
) = PRIO_PROCESS
;
1297 SCARG(&ap
, who
) = 0;
1298 SCARG(&ap
, prio
) = SCARG(uap
, prio
);
1300 if ((error
= sys_setpriority(l
, &ap
, retval
)) != 0)
1303 if ((error
= sys_getpriority(l
, (const void *)&ap
, retval
)) != 0)
1311 svr4_sys_resolvepath(struct lwp
*l
, const struct svr4_sys_resolvepath_args
*uap
, register_t
*retval
)
1313 struct nameidata nd
;
1317 NDINIT(&nd
, LOOKUP
, NOFOLLOW
| SAVENAME
| TRYEMULROOT
, UIO_USERSPACE
,
1320 if ((error
= namei(&nd
)) != 0)
1323 if ((error
= copyoutstr(nd
.ni_cnd
.cn_pnbuf
, SCARG(uap
, buf
),
1324 SCARG(uap
, bufsiz
), &len
)) != 0)
1330 PNBUF_PUT(nd
.ni_cnd
.cn_pnbuf
);