]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/svr4/svr4_misc.c
Add $Id$ tags
[FreeBSD/FreeBSD.git] / sys / svr4 / svr4_misc.c
1 /*
2  * Copyright (c) 1998 Mark Newton
3  * Copyright (c) 1994 Christos Zoulas
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  * 
28  * $Id$
29  */
30
31 /*
32  * SVR4 compatibility module.
33  *
34  * SVR4 system calls that are implemented differently in BSD are
35  * handled here.
36  */
37
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/namei.h>
41 #include <sys/dirent.h>
42 #include <sys/malloc.h>
43 #include <sys/proc.h>
44 #include <sys/file.h>
45 #include <sys/stat.h>
46 #include <sys/time.h>
47 #include <sys/file.h>
48 #include <sys/filedesc.h>
49 #include <sys/kernel.h>
50 #include <sys/mbuf.h>
51 #include <sys/mman.h>
52 #include <sys/mount.h>
53 #include <sys/resource.h>
54 #include <sys/resourcevar.h>
55 #include <sys/socket.h>
56 #include <sys/vnode.h>
57 #include <sys/uio.h>
58 #include <sys/wait.h>
59 #include <sys/utsname.h>
60 #include <sys/unistd.h>
61 #include <sys/times.h>
62 #include <sys/fcntl.h>
63 #include <sys/sem.h>
64 #include <sys/msg.h>
65 #include <sys/ptrace.h>
66 #include <sys/signalvar.h>
67 #include <ufs/ufs/dir.h>
68 #include <vm/vm_zone.h>
69
70 #include <sys/sysproto.h>
71
72 #include <netinet/in.h>
73
74 #include <svr4/svr4.h>
75 #include <svr4/svr4_types.h>
76 #include <svr4/svr4_signal.h>
77 #include <svr4/svr4_proto.h>
78 #include <svr4/svr4_util.h>
79 #include <svr4/svr4_sysconfig.h>
80 #include <svr4/svr4_dirent.h>
81 #include <svr4/svr4_acl.h>
82 #include <svr4/svr4_time.h>
83 #include <svr4/svr4_ulimit.h>
84 #include <svr4/svr4_statvfs.h>
85 #include <svr4/svr4_hrt.h>
86 #include <svr4/svr4_mman.h>
87 #include <svr4/svr4_wait.h>
88
89 #include <machine/vmparam.h>
90 #include <vm/vm.h>
91 #include <vm/vm_param.h>
92 #include <vm/vm_map.h>
93 #include <vm/vm_prot.h>
94
95 #if defined(NetBSD)
96 # if defined(UVM)
97 #  include <uvm/uvm_extern.h>
98 # endif
99 #endif
100
101 #define BSD_DIRENT(cp)          ((struct dirent *)(cp))
102
103 extern int bsd_to_svr4_sig[];
104 static int svr4_mknod __P((struct proc *, register_t *, char *,
105     svr4_mode_t, svr4_dev_t));
106
107 static __inline clock_t timeval_to_clock_t __P((struct timeval *));
108 static int svr4_setinfo __P((struct proc *, int, svr4_siginfo_t *));
109
110 struct svr4_hrtcntl_args;
111 static int svr4_hrtcntl __P((struct proc *, struct svr4_hrtcntl_args *,
112     register_t *));
113 static void bsd_statfs_to_svr4_statvfs __P((const struct statfs *,
114     struct svr4_statvfs *));
115 static void bsd_statfs_to_svr4_statvfs64 __P((const struct statfs *,
116     struct svr4_statvfs64 *));
117 static struct proc *svr4_pfind __P((pid_t pid));
118
119 /* BOGUS noop */
120 #if defined(BOGUS)
121 int
122 svr4_sys_setitimer(p, uap)
123         register struct proc *p;
124         struct svr4_sys_setitimer_args *uap;
125 {
126         p->p_retval[0] = 0;
127         return 0;
128 }
129 #endif
130
131 int
132 svr4_sys_wait(p, uap)
133         struct proc *p;
134         struct svr4_sys_wait_args *uap;
135 {
136         struct wait_args w4;
137         int error, *retval = p->p_retval, st, sig;
138         size_t sz = sizeof(*SCARG(&w4, status));
139
140         SCARG(&w4, rusage) = NULL;
141         SCARG(&w4, options) = 0;
142
143         if (SCARG(uap, status) == NULL) {
144                 caddr_t sg = stackgap_init();
145
146                 SCARG(&w4, status) = stackgap_alloc(&sg, sz);
147         }
148         else
149                 SCARG(&w4, status) = SCARG(uap, status);
150
151         SCARG(&w4, pid) = WAIT_ANY;
152
153         if ((error = wait4(p, &w4)) != 0)
154                 return error;
155       
156         if ((error = copyin(SCARG(&w4, status), &st, sizeof(st))) != 0)
157                 return error;
158
159         if (WIFSIGNALED(st)) {
160                 sig = WTERMSIG(st);
161                 if (sig >= 0 && sig < NSIG)
162                         st = (st & ~0177) | bsd_to_svr4_sig[sig];
163         } else if (WIFSTOPPED(st)) {
164                 sig = WSTOPSIG(st);
165                 if (sig >= 0 && sig < NSIG)
166                         st = (st & ~0xff00) | (bsd_to_svr4_sig[sig] << 8);
167         }
168
169         /*
170          * It looks like wait(2) on svr4/solaris/2.4 returns
171          * the status in retval[1], and the pid on retval[0].
172          */
173         retval[1] = st;
174
175         if (SCARG(uap, status))
176                 if ((error = copyout(&st, SCARG(uap, status), sizeof(st))) != 0)
177                         return error;
178
179         return 0;
180 }
181
182 int
183 svr4_sys_execv(p, uap)
184         struct proc *p;
185         struct svr4_sys_execv_args *uap;
186 {
187         struct execve_args ap;
188         caddr_t sg;
189
190         sg = stackgap_init();
191         CHECKALTEXIST(p, &sg, SCARG(uap, path));
192
193         SCARG(&ap, fname) = SCARG(uap, path);
194         SCARG(&ap, argv) = SCARG(uap, argp);
195         SCARG(&ap, envv) = NULL;
196
197         return execve(p, &ap);
198 }
199
200 int
201 svr4_sys_execve(p, uap)
202         struct proc *p;
203         struct svr4_sys_execve_args *uap;
204 {
205         struct execve_args ap;
206         caddr_t sg;
207
208         sg = stackgap_init();
209         CHECKALTEXIST(p, &sg, uap->path);
210
211         SCARG(&ap, fname) = SCARG(uap, path);
212         SCARG(&ap, argv) = SCARG(uap, argp);
213         SCARG(&ap, envv) = SCARG(uap, envp);
214
215         return execve(p, &ap);
216 }
217
218 int
219 svr4_sys_time(p, v)
220         struct proc *p;
221         struct svr4_sys_time_args *v;
222 {
223         struct svr4_sys_time_args *uap = v;
224         int error = 0;
225         struct timeval tv;
226
227         microtime(&tv);
228         if (SCARG(uap, t))
229                 error = copyout(&tv.tv_sec, SCARG(uap, t),
230                                 sizeof(*(SCARG(uap, t))));
231         p->p_retval[0] = (int) tv.tv_sec;
232
233         return error;
234 }
235
236
237 /*
238  * Read SVR4-style directory entries.  We suck them into kernel space so
239  * that they can be massaged before being copied out to user code.  Like
240  * SunOS, we squish out `empty' entries.
241  *
242  * This is quite ugly, but what do you expect from compatibility code?
243  */
244
245 int
246 svr4_sys_getdents64(p, uap)
247         struct proc *p;
248         struct svr4_sys_getdents64_args *uap;
249 {
250         struct dirent *bdp;
251         struct vnode *vp;
252         caddr_t inp, buf;       /* BSD-format */
253         int len, reclen;        /* BSD-format */
254         caddr_t outp;           /* SVR4-format */
255         int resid, svr4_reclen; /* SVR4-format */
256         struct file *fp;
257         struct uio auio;
258         struct iovec aiov;
259         struct svr4_dirent64 idb;
260         off_t off;              /* true file offset */
261         int buflen, error, eofflag;
262         u_long *cookiebuf = NULL, *cookie;
263         int ncookies = 0, retval = 0, offcnt = 0;
264
265         if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
266                 return (error);
267
268         if ((fp->f_flag & FREAD) == 0)
269                 return (EBADF);
270
271         vp = (struct vnode *)fp->f_data;
272         if (vp->v_type != VDIR)
273                 return (EINVAL);
274
275         buflen = min(MAXBSIZE, SCARG(uap, nbytes));
276         DPRINTF(("buflen = %d, spec = %d\n", buflen, SCARG(uap, nbytes)));
277         buf = malloc(buflen, M_TEMP, M_WAITOK);
278         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
279         off = fp->f_offset;
280 again:
281         aiov.iov_base = buf;
282         aiov.iov_len = buflen;
283         auio.uio_iov = &aiov;
284         auio.uio_iovcnt = 1;
285         auio.uio_rw = UIO_READ;
286         auio.uio_segflg = UIO_SYSSPACE;
287         auio.uio_procp = p;
288         auio.uio_resid = buflen;
289         auio.uio_offset = off;
290         DPRINTF((">>> off = %d\n", off));
291
292         /*
293          * First we read into the malloc'ed buffer, then
294          * we massage it into user space, one record at a time.
295          */
296         error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies,
297             &cookiebuf);
298         if (error)
299                 goto out;
300
301         inp = buf;
302         outp = (caddr_t)SCARG(uap, dp);
303         resid = SCARG(uap, nbytes);
304         if ((len = buflen - auio.uio_resid) == 0)
305                 goto eof;
306
307         for (cookie = cookiebuf; len > 0; len -= reclen) {
308                 bdp = (struct dirent *)inp;
309                 reclen = bdp->d_reclen;
310                 if (reclen & 3)
311                         panic("svr4_getdents64: bad reclen");
312                 if (bdp->d_fileno == 0) {
313                         inp += reclen;  /* it is a hole; squish it out */
314 #if 0
315                         off = *cookie++;
316 #else
317                         off += reclen;
318 #endif
319                         DPRINTF(("+++ off = %d\n", off));
320                         continue;
321                 }
322                 svr4_reclen = SVR4_RECLEN(&idb, (bdp->d_namlen));
323
324                 if (reclen > len || resid < svr4_reclen) {
325                         /* entry too big for buffer, so just stop */
326                         outp++;
327                         DPRINTF(("+++ off = %d\n", off));
328                         break;
329                 }
330 #if 0
331                 off = *cookie++;       /* each entry points to the next */
332 #else
333                 off += reclen;
334 #endif
335                 DPRINTF(("+++ off = %d\n", off));
336
337                 /*
338                  * Massage in place to make a SVR4-shaped dirent (otherwise
339                  * we have to worry about touching user memory outside of
340                  * the copyout() call).
341                  */
342                 idb.d_ino = (svr4_ino64_t)bdp->d_fileno;
343                 idb.d_off = (svr4_off64_t)off;
344                 idb.d_reclen = (u_short)svr4_reclen;
345                 strcpy(idb.d_name, bdp->d_name);
346                 if ((error = copyout((caddr_t)&idb, outp, svr4_reclen)))
347                         goto out;
348                 DPRINTF(("d_ino = %d\nd_off = %d\nd_reclen = %d\n",
349                          idb.d_ino, idb.d_off, (u_short)idb.d_reclen));
350                 DPRINTF(("d_name = %s\n", idb.d_name));
351                 DPRINTF(("(bdp->d_type = %d, reclen = %d, bdp->d_namelen = %d)\n", bdp->d_type, svr4_reclen, bdp->d_namlen));
352                 /* advance past this real entry */
353                 inp += reclen;
354                 /* advance output past SVR4-shaped entry */
355                 outp += svr4_reclen;
356                 resid -= svr4_reclen;
357                 offcnt += svr4_reclen;
358         }
359         DPRINTF(("block finished\n"));
360         /* if we squished out the whole block, try again */
361         fp->f_offset = off;     /* update the vnode offset */
362         if (outp == (caddr_t)SCARG(uap, dp))
363                 goto again;
364
365 eof:
366         retval = offcnt; /* SCARG(uap, nbytes) - resid;*/
367 out:
368         VOP_UNLOCK(vp, 0, p);
369         if (cookiebuf)
370                 free(cookiebuf, M_TEMP);
371         free(buf, M_TEMP);
372         DPRINTF(("\t\treturning %d\n", retval));
373         p->p_retval[0] = retval;
374         return error;
375 }
376
377
378 int
379 svr4_sys_getdents(p, uap)
380         struct proc *p;
381         struct svr4_sys_getdents_args *uap;
382 {
383         struct dirent *bdp;
384         struct vnode *vp;
385         caddr_t inp, buf;       /* BSD-format */
386         int len, reclen;        /* BSD-format */
387         caddr_t outp;           /* SVR4-format */
388         int resid, svr4_reclen; /* SVR4-format */
389         struct file *fp;
390         struct uio auio;
391         struct iovec aiov;
392         struct svr4_dirent idb;
393         off_t off;              /* true file offset */
394         int buflen, error, eofflag;
395         u_long *cookiebuf = NULL, *cookie;
396         int ncookies = 0, *retval = p->p_retval;
397
398         if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
399                 return (error);
400
401         if ((fp->f_flag & FREAD) == 0)
402                 return (EBADF);
403
404         vp = (struct vnode *)fp->f_data;
405         if (vp->v_type != VDIR)
406                 return (EINVAL);
407
408         buflen = min(MAXBSIZE, SCARG(uap, nbytes));
409         buf = malloc(buflen, M_TEMP, M_WAITOK);
410         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
411         off = fp->f_offset;
412 again:
413         aiov.iov_base = buf;
414         aiov.iov_len = buflen;
415         auio.uio_iov = &aiov;
416         auio.uio_iovcnt = 1;
417         auio.uio_rw = UIO_READ;
418         auio.uio_segflg = UIO_SYSSPACE;
419         auio.uio_procp = p;
420         auio.uio_resid = buflen;
421         auio.uio_offset = off;
422         /*
423          * First we read into the malloc'ed buffer, then
424          * we massage it into user space, one record at a time.
425          */
426         error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies,
427             &cookiebuf);
428         if (error)
429                 goto out;
430
431         inp = buf;
432         outp = SCARG(uap, buf);
433         resid = SCARG(uap, nbytes);
434         if ((len = buflen - auio.uio_resid) == 0)
435                 goto eof;
436
437         for (cookie = cookiebuf; len > 0; len -= reclen) {
438                 bdp = (struct dirent *)inp;
439                 reclen = bdp->d_reclen;
440                 if (reclen & 3)
441                         panic("svr4_getdents: bad reclen");
442                 off = *cookie++;        /* each entry points to the next */
443                 if ((off >> 32) != 0) {
444                         uprintf("svr4_getdents: dir offset too large for emulated program");
445                         error = EINVAL;
446                         goto out;
447                 }
448                 if (bdp->d_fileno == 0) {
449                         inp += reclen;  /* it is a hole; squish it out */
450                         continue;
451                 }
452                 svr4_reclen = SVR4_RECLEN(&idb, bdp->d_namlen);
453                 if (reclen > len || resid < svr4_reclen) {
454                         /* entry too big for buffer, so just stop */
455                         outp++;
456                         break;
457                 }
458                 /*
459                  * Massage in place to make a SVR4-shaped dirent (otherwise
460                  * we have to worry about touching user memory outside of
461                  * the copyout() call).
462                  */
463                 idb.d_ino = (svr4_ino_t)bdp->d_fileno;
464                 idb.d_off = (svr4_off_t)off;
465                 idb.d_reclen = (u_short)svr4_reclen;
466                 strcpy(idb.d_name, bdp->d_name);
467                 if ((error = copyout((caddr_t)&idb, outp, svr4_reclen)))
468                         goto out;
469                 /* advance past this real entry */
470                 inp += reclen;
471                 /* advance output past SVR4-shaped entry */
472                 outp += svr4_reclen;
473                 resid -= svr4_reclen;
474         }
475
476         /* if we squished out the whole block, try again */
477         if (outp == SCARG(uap, buf))
478                 goto again;
479         fp->f_offset = off;     /* update the vnode offset */
480
481 eof:
482         *retval = SCARG(uap, nbytes) - resid;
483 out:
484         VOP_UNLOCK(vp, 0, p);
485         if (cookiebuf)
486                 free(cookiebuf, M_TEMP);
487         free(buf, M_TEMP);
488         return error;
489 }
490
491
492 int
493 svr4_sys_mmap(p, uap)
494         struct proc *p;
495         struct svr4_sys_mmap_args *uap;
496 {
497         struct mmap_args         mm;
498         int             *retval;
499
500         retval = p->p_retval;
501 #define _MAP_NEW        0x80000000
502         /*
503          * Verify the arguments.
504          */
505         if (SCARG(uap, prot) & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
506                 return EINVAL;  /* XXX still needed? */
507
508         if (SCARG(uap, len) == 0)
509                 return EINVAL;
510
511         SCARG(&mm, prot) = SCARG(uap, prot);
512         SCARG(&mm, len) = SCARG(uap, len);
513         SCARG(&mm, flags) = SCARG(uap, flags) & ~_MAP_NEW;
514         SCARG(&mm, fd) = SCARG(uap, fd);
515         SCARG(&mm, addr) = SCARG(uap, addr);
516         SCARG(&mm, pos) = SCARG(uap, pos);
517
518         return mmap(p, &mm);
519 }
520
521 int
522 svr4_sys_mmap64(p, uap)
523         struct proc *p;
524         struct svr4_sys_mmap64_args *uap;
525 {
526         struct mmap_args         mm;
527         void            *rp;
528
529 #define _MAP_NEW        0x80000000
530         /*
531          * Verify the arguments.
532          */
533         if (SCARG(uap, prot) & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
534                 return EINVAL;  /* XXX still needed? */
535
536         if (SCARG(uap, len) == 0)
537                 return EINVAL;
538
539         SCARG(&mm, prot) = SCARG(uap, prot);
540         SCARG(&mm, len) = SCARG(uap, len);
541         SCARG(&mm, flags) = SCARG(uap, flags) & ~_MAP_NEW;
542         SCARG(&mm, fd) = SCARG(uap, fd);
543         SCARG(&mm, addr) = SCARG(uap, addr);
544         SCARG(&mm, pos) = SCARG(uap, pos);
545
546         rp = (void *) round_page((vm_offset_t)(p->p_vmspace->vm_daddr + MAXDSIZ));
547         if ((SCARG(&mm, flags) & MAP_FIXED) == 0 &&
548             SCARG(&mm, addr) != 0 && (void *)SCARG(&mm, addr) < rp)
549                 SCARG(&mm, addr) = rp;
550
551         return mmap(p, &mm);
552 }
553
554
555 int
556 svr4_sys_fchroot(p, uap)
557         struct proc *p;
558         struct svr4_sys_fchroot_args *uap;
559 {
560         struct filedesc *fdp = p->p_fd;
561         struct vnode    *vp;
562         struct file     *fp;
563         int              error;
564
565         if ((error = suser(p)) != 0)
566                 return error;
567         if ((error = getvnode(fdp, SCARG(uap, fd), &fp)) != 0)
568                 return error;
569         vp = (struct vnode *) fp->f_data;
570         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
571         if (vp->v_type != VDIR)
572                 error = ENOTDIR;
573         else
574                 error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
575         VOP_UNLOCK(vp, 0, p);
576         if (error)
577                 return error;
578         VREF(vp);
579         if (fdp->fd_rdir != NULL)
580                 vrele(fdp->fd_rdir);
581         fdp->fd_rdir = vp;
582         return 0;
583 }
584
585
586 static int
587 svr4_mknod(p, retval, path, mode, dev)
588         struct proc *p;
589         register_t *retval;
590         char *path;
591         svr4_mode_t mode;
592         svr4_dev_t dev;
593 {
594         caddr_t sg = stackgap_init();
595
596         CHECKALTEXIST(p, &sg, path);
597
598         if (S_ISFIFO(mode)) {
599                 struct mkfifo_args ap;
600                 SCARG(&ap, path) = path;
601                 SCARG(&ap, mode) = mode;
602                 return mkfifo(p, &ap);
603         } else {
604                 struct mknod_args ap;
605                 SCARG(&ap, path) = path;
606                 SCARG(&ap, mode) = mode;
607                 SCARG(&ap, dev) = dev;
608                 return mknod(p, &ap);
609         }
610 }
611
612
613 int
614 svr4_sys_mknod(p, uap)
615         register struct proc *p;
616         struct svr4_sys_mknod_args *uap;
617 {
618         int *retval = p->p_retval;
619         return svr4_mknod(p, retval,
620                           SCARG(uap, path), SCARG(uap, mode),
621                           (svr4_dev_t)svr4_to_bsd_odev_t(SCARG(uap, dev)));
622 }
623
624
625 int
626 svr4_sys_xmknod(p, uap)
627         struct proc *p;
628         struct svr4_sys_xmknod_args *uap;
629 {
630         int *retval = p->p_retval;
631         return svr4_mknod(p, retval,
632                           SCARG(uap, path), SCARG(uap, mode),
633                           (svr4_dev_t)svr4_to_bsd_dev_t(SCARG(uap, dev)));
634 }
635
636
637 int
638 svr4_sys_vhangup(p, uap)
639         struct proc *p;
640         struct svr4_sys_vhangup_args *uap;
641 {
642         return 0;
643 }
644
645
646 int
647 svr4_sys_sysconfig(p, uap)
648         struct proc *p;
649         struct svr4_sys_sysconfig_args *uap;
650 {
651         int *retval;
652
653         retval = &(p->p_retval[0]);
654
655         switch (SCARG(uap, name)) {
656         case SVR4_CONFIG_UNUSED:
657                 *retval = 0;
658                 break;
659         case SVR4_CONFIG_NGROUPS:
660                 *retval = NGROUPS_MAX;
661                 break;
662         case SVR4_CONFIG_CHILD_MAX:
663                 *retval = maxproc;
664                 break;
665         case SVR4_CONFIG_OPEN_FILES:
666                 *retval = maxfiles;
667                 break;
668         case SVR4_CONFIG_POSIX_VER:
669                 *retval = 198808;
670                 break;
671         case SVR4_CONFIG_PAGESIZE:
672                 *retval = PAGE_SIZE;
673                 break;
674         case SVR4_CONFIG_CLK_TCK:
675                 *retval = 60;   /* should this be `hz', ie. 100? */
676                 break;
677         case SVR4_CONFIG_XOPEN_VER:
678                 *retval = 2;    /* XXX: What should that be? */
679                 break;
680         case SVR4_CONFIG_PROF_TCK:
681                 *retval = 60;   /* XXX: What should that be? */
682                 break;
683         case SVR4_CONFIG_NPROC_CONF:
684                 *retval = 1;    /* Only one processor for now */
685                 break;
686         case SVR4_CONFIG_NPROC_ONLN:
687                 *retval = 1;    /* And it better be online */
688                 break;
689         case SVR4_CONFIG_AIO_LISTIO_MAX:
690         case SVR4_CONFIG_AIO_MAX:
691         case SVR4_CONFIG_AIO_PRIO_DELTA_MAX:
692                 *retval = 0;    /* No aio support */
693                 break;
694         case SVR4_CONFIG_DELAYTIMER_MAX:
695                 *retval = 0;    /* No delaytimer support */
696                 break;
697         case SVR4_CONFIG_MQ_OPEN_MAX:
698                 *retval = msginfo.msgmni;
699                 break;
700         case SVR4_CONFIG_MQ_PRIO_MAX:
701                 *retval = 0;    /* XXX: Don't know */
702                 break;
703         case SVR4_CONFIG_RTSIG_MAX:
704                 *retval = 0;
705                 break;
706         case SVR4_CONFIG_SEM_NSEMS_MAX:
707                 *retval = seminfo.semmni;
708                 break;
709         case SVR4_CONFIG_SEM_VALUE_MAX:
710                 *retval = seminfo.semvmx;
711                 break;
712         case SVR4_CONFIG_SIGQUEUE_MAX:
713                 *retval = 0;    /* XXX: Don't know */
714                 break;
715         case SVR4_CONFIG_SIGRT_MIN:
716         case SVR4_CONFIG_SIGRT_MAX:
717                 *retval = 0;    /* No real time signals */
718                 break;
719         case SVR4_CONFIG_TIMER_MAX:
720                 *retval = 3;    /* XXX: real, virtual, profiling */
721                 break;
722 #if defined(NOTYET)
723         case SVR4_CONFIG_PHYS_PAGES:
724 #if defined(UVM)
725                 *retval = uvmexp.free;  /* XXX: free instead of total */
726 #else
727                 *retval = cnt.v_free_count;     /* XXX: free instead of total */
728 #endif
729                 break;
730         case SVR4_CONFIG_AVPHYS_PAGES:
731 #if defined(UVM)
732                 *retval = uvmexp.active;        /* XXX: active instead of avg */
733 #else
734                 *retval = cnt.v_active_count;   /* XXX: active instead of avg */
735 #endif
736                 break;
737 #endif /* NOTYET */
738
739         default:
740                 return EINVAL;
741         }
742         return 0;
743 }
744
745 extern int swap_pager_full;
746
747 /* ARGSUSED */
748 int
749 svr4_sys_break(p, uap)
750         struct proc *p;
751         struct svr4_sys_break_args *uap;
752 {
753         struct vmspace *vm = p->p_vmspace;
754         vm_offset_t new, old, base, ns;
755         int rv;
756
757         base = round_page((vm_offset_t) vm->vm_daddr);
758         ns = (vm_offset_t)SCARG(uap, nsize);
759         new = round_page(ns);
760         if (new > base) {
761           if ((new - base) > (unsigned) p->p_rlimit[RLIMIT_DATA].rlim_cur) {
762                         return ENOMEM;
763           }
764           if (new >= VM_MAXUSER_ADDRESS) {
765             return (ENOMEM);
766           }
767         } else if (new < base) {
768                 /*
769                  * This is simply an invalid value.  If someone wants to
770                  * do fancy address space manipulations, mmap and munmap
771                  * can do most of what the user would want.
772                  */
773                 return EINVAL;
774         }
775
776         old = base + ctob(vm->vm_dsize);
777
778         if (new > old) {
779                 vm_size_t diff;
780                 if (swap_pager_full) {
781                         return (ENOMEM);
782                 }
783                 diff = new - old;
784                 rv = vm_map_find(&vm->vm_map, NULL, 0, &old, diff, FALSE,
785                         VM_PROT_ALL, VM_PROT_ALL, 0);
786                 if (rv != KERN_SUCCESS) {
787                         return (ENOMEM);
788                 }
789                 vm->vm_dsize += btoc(diff);
790         } else if (new < old) {
791                 rv = vm_map_remove(&vm->vm_map, new, old);
792                 if (rv != KERN_SUCCESS) {
793                         return (ENOMEM);
794                 }
795                 vm->vm_dsize -= btoc(old - new);
796         }
797
798         return (0);
799 }
800
801 static __inline clock_t
802 timeval_to_clock_t(tv)
803         struct timeval *tv;
804 {
805         return tv->tv_sec * hz + tv->tv_usec / (1000000 / hz);
806 }
807
808
809 int
810 svr4_sys_times(p, uap)
811         struct proc *p;
812         struct svr4_sys_times_args *uap;
813 {
814         int                      error, *retval = p->p_retval;
815         struct tms               tms;
816         struct timeval           t;
817         struct rusage           *ru;
818         struct rusage            r;
819         struct getrusage_args    ga;
820
821         caddr_t sg = stackgap_init();
822         ru = stackgap_alloc(&sg, sizeof(struct rusage));
823
824         SCARG(&ga, who) = RUSAGE_SELF;
825         SCARG(&ga, rusage) = ru;
826
827         error = getrusage(p, &ga);
828         if (error)
829                 return error;
830
831         if ((error = copyin(ru, &r, sizeof r)) != 0)
832                 return error;
833
834         tms.tms_utime = timeval_to_clock_t(&r.ru_utime);
835         tms.tms_stime = timeval_to_clock_t(&r.ru_stime);
836
837         SCARG(&ga, who) = RUSAGE_CHILDREN;
838         error = getrusage(p, &ga);
839         if (error)
840                 return error;
841
842         if ((error = copyin(ru, &r, sizeof r)) != 0)
843                 return error;
844
845         tms.tms_cutime = timeval_to_clock_t(&r.ru_utime);
846         tms.tms_cstime = timeval_to_clock_t(&r.ru_stime);
847
848         microtime(&t);
849         *retval = timeval_to_clock_t(&t);
850
851         return copyout(&tms, SCARG(uap, tp), sizeof(tms));
852 }
853
854
855 int
856 svr4_sys_ulimit(p, uap)
857         struct proc *p;
858         struct svr4_sys_ulimit_args *uap;
859 {
860         int *retval = p->p_retval;
861
862         switch (SCARG(uap, cmd)) {
863         case SVR4_GFILLIM:
864                 *retval = p->p_rlimit[RLIMIT_FSIZE].rlim_cur / 512;
865                 if (*retval == -1)
866                         *retval = 0x7fffffff;
867                 return 0;
868
869         case SVR4_SFILLIM:
870                 {
871                         int error;
872                         struct __setrlimit_args srl;
873                         struct rlimit krl;
874                         caddr_t sg = stackgap_init();
875                         struct rlimit *url = (struct rlimit *) 
876                                 stackgap_alloc(&sg, sizeof *url);
877
878                         krl.rlim_cur = SCARG(uap, newlimit) * 512;
879                         krl.rlim_max = p->p_rlimit[RLIMIT_FSIZE].rlim_max;
880
881                         error = copyout(&krl, url, sizeof(*url));
882                         if (error)
883                                 return error;
884
885                         SCARG(&srl, which) = RLIMIT_FSIZE;
886                         SCARG(&srl, rlp) = (struct orlimit *)url;
887
888                         error = setrlimit(p, &srl);
889                         if (error)
890                                 return error;
891
892                         *retval = p->p_rlimit[RLIMIT_FSIZE].rlim_cur;
893                         if (*retval == -1)
894                                 *retval = 0x7fffffff;
895                         return 0;
896                 }
897
898         case SVR4_GMEMLIM:
899                 {
900                         struct vmspace *vm = p->p_vmspace;
901                         register_t r = p->p_rlimit[RLIMIT_DATA].rlim_cur;
902
903                         if (r == -1)
904                                 r = 0x7fffffff;
905                         r += (long) vm->vm_daddr;
906                         if (r < 0)
907                                 r = 0x7fffffff;
908                         *retval = r;
909                         return 0;
910                 }
911
912         case SVR4_GDESLIM:
913                 *retval = p->p_rlimit[RLIMIT_NOFILE].rlim_cur;
914                 if (*retval == -1)
915                         *retval = 0x7fffffff;
916                 return 0;
917
918         default:
919                 return EINVAL;
920         }
921 }
922
923 static struct proc *
924 svr4_pfind(pid)
925         pid_t pid;
926 {
927         struct proc *p;
928
929         /* look in the live processes */
930         if ((p = pfind(pid)) != NULL)
931                 return p;
932
933         /* look in the zombies */
934         for (p = zombproc.lh_first; p != 0; p = p->p_list.le_next)
935                 if (p->p_pid == pid)
936                         return p;
937
938         return NULL;
939 }
940
941
942 int
943 svr4_sys_pgrpsys(p, uap)
944         struct proc *p;
945         struct svr4_sys_pgrpsys_args *uap;
946 {
947         int *retval = p->p_retval;
948
949         switch (SCARG(uap, cmd)) {
950         case 1:                 /* setpgrp() */
951                 /*
952                  * SVR4 setpgrp() (which takes no arguments) has the
953                  * semantics that the session ID is also created anew, so
954                  * in almost every sense, setpgrp() is identical to
955                  * setsid() for SVR4.  (Under BSD, the difference is that
956                  * a setpgid(0,0) will not create a new session.)
957                  */
958                 setsid(p, NULL);
959                 /*FALLTHROUGH*/
960
961         case 0:                 /* getpgrp() */
962                 *retval = p->p_pgrp->pg_id;
963                 return 0;
964
965         case 2:                 /* getsid(pid) */
966                 if (SCARG(uap, pid) != 0 &&
967                     (p = svr4_pfind(SCARG(uap, pid))) == NULL)
968                         return ESRCH;
969                 /*
970                  * This has already been initialized to the pid of
971                  * the session leader.
972                  */
973                 *retval = (register_t) p->p_session->s_leader->p_pid;
974                 return 0;
975
976         case 3:                 /* setsid() */
977                 return setsid(p, NULL);
978
979         case 4:                 /* getpgid(pid) */
980
981                 if (SCARG(uap, pid) != 0 &&
982                     (p = svr4_pfind(SCARG(uap, pid))) == NULL)
983                         return ESRCH;
984
985                 *retval = (int) p->p_pgrp->pg_id;
986                 return 0;
987
988         case 5:                 /* setpgid(pid, pgid); */
989                 {
990                         struct setpgid_args sa;
991
992                         SCARG(&sa, pid) = SCARG(uap, pid);
993                         SCARG(&sa, pgid) = SCARG(uap, pgid);
994                         return setpgid(p, &sa);
995                 }
996
997         default:
998                 return EINVAL;
999         }
1000 }
1001
1002 #define syscallarg(x)   union { x datum; register_t pad; }
1003
1004 struct svr4_hrtcntl_args {
1005         int                     cmd;
1006         int                     fun;
1007         int                     clk;
1008         svr4_hrt_interval_t *   iv;
1009         svr4_hrt_time_t *       ti;
1010 };
1011
1012
1013 static int
1014 svr4_hrtcntl(p, uap, retval)
1015         struct proc *p;
1016         struct svr4_hrtcntl_args *uap;
1017         register_t *retval;
1018 {
1019         switch (SCARG(uap, fun)) {
1020         case SVR4_HRT_CNTL_RES:
1021                 DPRINTF(("htrcntl(RES)\n"));
1022                 *retval = SVR4_HRT_USEC;
1023                 return 0;
1024
1025         case SVR4_HRT_CNTL_TOFD:
1026                 DPRINTF(("htrcntl(TOFD)\n"));
1027                 {
1028                         struct timeval tv;
1029                         svr4_hrt_time_t t;
1030                         if (SCARG(uap, clk) != SVR4_HRT_CLK_STD) {
1031                                 DPRINTF(("clk == %d\n", SCARG(uap, clk)));
1032                                 return EINVAL;
1033                         }
1034                         if (SCARG(uap, ti) == NULL) {
1035                                 DPRINTF(("ti NULL\n"));
1036                                 return EINVAL;
1037                         }
1038                         microtime(&tv);
1039                         t.h_sec = tv.tv_sec;
1040                         t.h_rem = tv.tv_usec;
1041                         t.h_res = SVR4_HRT_USEC;
1042                         return copyout(&t, SCARG(uap, ti), sizeof(t));
1043                 }
1044
1045         case SVR4_HRT_CNTL_START:
1046                 DPRINTF(("htrcntl(START)\n"));
1047                 return ENOSYS;
1048
1049         case SVR4_HRT_CNTL_GET:
1050                 DPRINTF(("htrcntl(GET)\n"));
1051                 return ENOSYS;
1052         default:
1053                 DPRINTF(("Bad htrcntl command %d\n", SCARG(uap, fun)));
1054                 return ENOSYS;
1055         }
1056 }
1057
1058
1059 int
1060 svr4_sys_hrtsys(p, uap) 
1061         struct proc *p;
1062         struct svr4_sys_hrtsys_args *uap;
1063 {
1064         int *retval = p->p_retval;
1065
1066         switch (SCARG(uap, cmd)) {
1067         case SVR4_HRT_CNTL:
1068                 return svr4_hrtcntl(p, (struct svr4_hrtcntl_args *) uap,
1069                                     retval);
1070
1071         case SVR4_HRT_ALRM:
1072                 DPRINTF(("hrtalarm\n"));
1073                 return ENOSYS;
1074
1075         case SVR4_HRT_SLP:
1076                 DPRINTF(("hrtsleep\n"));
1077                 return ENOSYS;
1078
1079         case SVR4_HRT_CAN:
1080                 DPRINTF(("hrtcancel\n"));
1081                 return ENOSYS;
1082
1083         default:
1084                 DPRINTF(("Bad hrtsys command %d\n", SCARG(uap, cmd)));
1085                 return EINVAL;
1086         }
1087 }
1088
1089
1090 static int
1091 svr4_setinfo(p, st, s)
1092         struct proc *p;
1093         int st;
1094         svr4_siginfo_t *s;
1095 {
1096         svr4_siginfo_t i;
1097         int sig;
1098
1099         memset(&i, 0, sizeof(i));
1100
1101         i.si_signo = SVR4_SIGCHLD;
1102         i.si_errno = 0; /* XXX? */
1103
1104         if (p) {
1105                 i.si_pid = p->p_pid;
1106                 if (p->p_stat == SZOMB) {
1107                         i.si_stime = p->p_ru->ru_stime.tv_sec;
1108                         i.si_utime = p->p_ru->ru_utime.tv_sec;
1109                 }
1110                 else {
1111                         i.si_stime = p->p_stats->p_ru.ru_stime.tv_sec;
1112                         i.si_utime = p->p_stats->p_ru.ru_utime.tv_sec;
1113                 }
1114         }
1115
1116         if (WIFEXITED(st)) {
1117                 i.si_status = WEXITSTATUS(st);
1118                 i.si_code = SVR4_CLD_EXITED;
1119         } else if (WIFSTOPPED(st)) {
1120                 sig = WSTOPSIG(st);
1121                 if (sig >= 0 && sig < NSIG)
1122                         i.si_status = bsd_to_svr4_sig[sig];
1123
1124                 if (i.si_status == SVR4_SIGCONT)
1125                         i.si_code = SVR4_CLD_CONTINUED;
1126                 else
1127                         i.si_code = SVR4_CLD_STOPPED;
1128         } else {
1129                 sig = WTERMSIG(st);
1130                 if (sig >= 0 && sig < NSIG)
1131                         i.si_status = bsd_to_svr4_sig[sig];
1132
1133                 if (WCOREDUMP(st))
1134                         i.si_code = SVR4_CLD_DUMPED;
1135                 else
1136                         i.si_code = SVR4_CLD_KILLED;
1137         }
1138
1139         DPRINTF(("siginfo [pid %ld signo %d code %d errno %d status %d]\n",
1140                  i.si_pid, i.si_signo, i.si_code, i.si_errno, i.si_status));
1141
1142         return copyout(&i, s, sizeof(i));
1143 }
1144
1145
1146 int
1147 svr4_sys_waitsys(p, uap)
1148         struct proc *p;
1149         struct svr4_sys_waitsys_args *uap;
1150 {
1151         int nfound;
1152         int error, *retval = p->p_retval;
1153         struct proc *q, *t;
1154
1155
1156         switch (SCARG(uap, grp)) {
1157         case SVR4_P_PID:        
1158                 break;
1159
1160         case SVR4_P_PGID:
1161                 SCARG(uap, id) = -p->p_pgid;
1162                 break;
1163
1164         case SVR4_P_ALL:
1165                 SCARG(uap, id) = WAIT_ANY;
1166                 break;
1167
1168         default:
1169                 return EINVAL;
1170         }
1171
1172         DPRINTF(("waitsys(%d, %d, %p, %x)\n", 
1173                  SCARG(uap, grp), SCARG(uap, id),
1174                  SCARG(uap, info), SCARG(uap, options)));
1175
1176 loop:
1177         nfound = 0;
1178         for (q = p->p_children.lh_first; q != 0; q = q->p_sibling.le_next) {
1179                 if (SCARG(uap, id) != WAIT_ANY &&
1180                     q->p_pid != SCARG(uap, id) &&
1181                     q->p_pgid != -SCARG(uap, id)) {
1182                         DPRINTF(("pid %d pgid %d != %d\n", q->p_pid,
1183                                  q->p_pgid, SCARG(uap, id)));
1184                         continue;
1185                 }
1186                 nfound++;
1187                 if (q->p_stat == SZOMB && 
1188                     ((SCARG(uap, options) & (SVR4_WEXITED|SVR4_WTRAPPED)))) {
1189                         *retval = 0;
1190                         DPRINTF(("found %d\n", q->p_pid));
1191                         if ((error = svr4_setinfo(q, q->p_xstat,
1192                                                   SCARG(uap, info))) != 0)
1193                                 return error;
1194
1195
1196                         if ((SCARG(uap, options) & SVR4_WNOWAIT)) {
1197                                 DPRINTF(("Don't wait\n"));
1198                                 return 0;
1199                         }
1200
1201                         /*
1202                          * If we got the child via ptrace(2) or procfs, and
1203                          * the parent is different (meaning the process was
1204                          * attached, rather than run as a child), then we need
1205                          * to give it back to the ol dparent, and send the
1206                          * parent a SIGCHLD.  The rest of the cleanup will be
1207                          * done when the old parent waits on the child.
1208                          */
1209                         if ((q->p_flag & P_TRACED) &&
1210                             q->p_oppid != q->p_pptr->p_pid) {
1211                                 t = pfind(q->p_oppid);
1212                                 proc_reparent(q, t ? t : initproc);
1213                                 q->p_oppid = 0;
1214                                 q->p_flag &= ~(P_TRACED | P_WAITED);
1215                                 wakeup((caddr_t)q->p_pptr);
1216                                 return 0;
1217                         }
1218                         q->p_xstat = 0;
1219                         ruadd(&p->p_stats->p_cru, q->p_ru);
1220
1221                         FREE(q->p_ru, M_ZOMBIE);
1222
1223                         /*
1224                          * Finally finished with old proc entry.
1225                          * Unlink it from its process group and free it.
1226                          */
1227                         leavepgrp(q);
1228
1229                         LIST_REMOVE(q, p_list); /* off zombproc */
1230
1231                         LIST_REMOVE(q, p_sibling);
1232
1233                         /*
1234                          * Decrement the count of procs running with this uid.
1235                          */
1236                         (void)chgproccnt(q->p_cred->p_ruid, -1);
1237
1238                         /*
1239                          * Free up credentials.
1240                          */
1241                         if (--q->p_cred->p_refcnt == 0) {
1242                                 crfree(q->p_cred->pc_ucred);
1243                                 FREE(q->p_cred, M_SUBPROC);
1244                         }
1245
1246                         /*
1247                          * Release reference to text vnode
1248                          */
1249                         if (q->p_textvp)
1250                                 vrele(q->p_textvp);
1251
1252                         /*
1253                          * Give machine-dependent layer a chance
1254                          * to free anything that cpu_exit couldn't
1255                          * release while still running in process context.
1256                          */
1257                         cpu_wait(q);
1258 #if defined(__NetBSD__)
1259                         pool_put(&proc_pool, q);
1260 #endif
1261                         nprocs--;
1262                         return 0;
1263                 }
1264                 if (q->p_stat == SSTOP && (q->p_flag & P_WAITED) == 0 &&
1265                     (q->p_flag & P_TRACED ||
1266                      (SCARG(uap, options) & (SVR4_WSTOPPED|SVR4_WCONTINUED)))) {
1267                         DPRINTF(("jobcontrol %d\n", q->p_pid));
1268                         if (((SCARG(uap, options) & SVR4_WNOWAIT)) == 0)
1269                                 q->p_flag |= P_WAITED;
1270                         *retval = 0;
1271                         return svr4_setinfo(q, W_STOPCODE(q->p_xstat),
1272                                             SCARG(uap, info));
1273                 }
1274         }
1275
1276         if (nfound == 0)
1277                 return ECHILD;
1278
1279         if (SCARG(uap, options) & SVR4_WNOHANG) {
1280                 *retval = 0;
1281                 if ((error = svr4_setinfo(NULL, 0, SCARG(uap, info))) != 0)
1282                         return error;
1283                 return 0;
1284         }
1285
1286         if ((error = tsleep((caddr_t)p, PWAIT | PCATCH, "svr4_wait", 0)) != 0)
1287                 return error;
1288         goto loop;
1289 }
1290
1291
1292 static void
1293 bsd_statfs_to_svr4_statvfs(bfs, sfs)
1294         const struct statfs *bfs;
1295         struct svr4_statvfs *sfs;
1296 {
1297         sfs->f_bsize = bfs->f_iosize; /* XXX */
1298         sfs->f_frsize = bfs->f_bsize;
1299         sfs->f_blocks = bfs->f_blocks;
1300         sfs->f_bfree = bfs->f_bfree;
1301         sfs->f_bavail = bfs->f_bavail;
1302         sfs->f_files = bfs->f_files;
1303         sfs->f_ffree = bfs->f_ffree;
1304         sfs->f_favail = bfs->f_ffree;
1305         sfs->f_fsid = bfs->f_fsid.val[0];
1306         memcpy(sfs->f_basetype, bfs->f_fstypename, sizeof(sfs->f_basetype));
1307         sfs->f_flag = 0;
1308         if (bfs->f_flags & MNT_RDONLY)
1309                 sfs->f_flag |= SVR4_ST_RDONLY;
1310         if (bfs->f_flags & MNT_NOSUID)
1311                 sfs->f_flag |= SVR4_ST_NOSUID;
1312         sfs->f_namemax = MAXNAMLEN;
1313         memcpy(sfs->f_fstr, bfs->f_fstypename, sizeof(sfs->f_fstr)); /* XXX */
1314         memset(sfs->f_filler, 0, sizeof(sfs->f_filler));
1315 }
1316
1317
1318 static void
1319 bsd_statfs_to_svr4_statvfs64(bfs, sfs)
1320         const struct statfs *bfs;
1321         struct svr4_statvfs64 *sfs;
1322 {
1323         sfs->f_bsize = bfs->f_iosize; /* XXX */
1324         sfs->f_frsize = bfs->f_bsize;
1325         sfs->f_blocks = bfs->f_blocks;
1326         sfs->f_bfree = bfs->f_bfree;
1327         sfs->f_bavail = bfs->f_bavail;
1328         sfs->f_files = bfs->f_files;
1329         sfs->f_ffree = bfs->f_ffree;
1330         sfs->f_favail = bfs->f_ffree;
1331         sfs->f_fsid = bfs->f_fsid.val[0];
1332         memcpy(sfs->f_basetype, bfs->f_fstypename, sizeof(sfs->f_basetype));
1333         sfs->f_flag = 0;
1334         if (bfs->f_flags & MNT_RDONLY)
1335                 sfs->f_flag |= SVR4_ST_RDONLY;
1336         if (bfs->f_flags & MNT_NOSUID)
1337                 sfs->f_flag |= SVR4_ST_NOSUID;
1338         sfs->f_namemax = MAXNAMLEN;
1339         memcpy(sfs->f_fstr, bfs->f_fstypename, sizeof(sfs->f_fstr)); /* XXX */
1340         memset(sfs->f_filler, 0, sizeof(sfs->f_filler));
1341 }
1342
1343
1344 int
1345 svr4_sys_statvfs(p, uap)
1346         struct proc *p;
1347         struct svr4_sys_statvfs_args *uap;
1348 {
1349         struct statfs_args      fs_args;
1350         caddr_t sg = stackgap_init();
1351         struct statfs *fs = stackgap_alloc(&sg, sizeof(struct statfs));
1352         struct statfs bfs;
1353         struct svr4_statvfs sfs;
1354         int error;
1355
1356         CHECKALTEXIST(p, &sg, SCARG(uap, path));
1357         SCARG(&fs_args, path) = SCARG(uap, path);
1358         SCARG(&fs_args, buf) = fs;
1359
1360         if ((error = statfs(p, &fs_args)) != 0)
1361                 return error;
1362
1363         if ((error = copyin(fs, &bfs, sizeof(bfs))) != 0)
1364                 return error;
1365
1366         bsd_statfs_to_svr4_statvfs(&bfs, &sfs);
1367
1368         return copyout(&sfs, SCARG(uap, fs), sizeof(sfs));
1369 }
1370
1371
1372 int
1373 svr4_sys_fstatvfs(p, uap)
1374         struct proc *p;
1375         struct svr4_sys_fstatvfs_args *uap;
1376 {
1377         struct fstatfs_args     fs_args;
1378         caddr_t sg = stackgap_init();
1379         struct statfs *fs = stackgap_alloc(&sg, sizeof(struct statfs));
1380         struct statfs bfs;
1381         struct svr4_statvfs sfs;
1382         int error;
1383
1384         SCARG(&fs_args, fd) = SCARG(uap, fd);
1385         SCARG(&fs_args, buf) = fs;
1386
1387         if ((error = fstatfs(p, &fs_args)) != 0)
1388                 return error;
1389
1390         if ((error = copyin(fs, &bfs, sizeof(bfs))) != 0)
1391                 return error;
1392
1393         bsd_statfs_to_svr4_statvfs(&bfs, &sfs);
1394
1395         return copyout(&sfs, SCARG(uap, fs), sizeof(sfs));
1396 }
1397
1398
1399 int
1400 svr4_sys_statvfs64(p, uap)
1401         struct proc *p;
1402         struct svr4_sys_statvfs64_args *uap;
1403 {
1404         struct statfs_args      fs_args;
1405         caddr_t sg = stackgap_init();
1406         struct statfs *fs = stackgap_alloc(&sg, sizeof(struct statfs));
1407         struct statfs bfs;
1408         struct svr4_statvfs64 sfs;
1409         int error;
1410
1411         CHECKALTEXIST(p, &sg, SCARG(uap, path));
1412         SCARG(&fs_args, path) = SCARG(uap, path);
1413         SCARG(&fs_args, buf) = fs;
1414
1415         if ((error = statfs(p, &fs_args)) != 0)
1416                 return error;
1417
1418         if ((error = copyin(fs, &bfs, sizeof(bfs))) != 0)
1419                 return error;
1420
1421         bsd_statfs_to_svr4_statvfs64(&bfs, &sfs);
1422
1423         return copyout(&sfs, SCARG(uap, fs), sizeof(sfs));
1424 }
1425
1426
1427 int
1428 svr4_sys_fstatvfs64(p, uap) 
1429         struct proc *p;
1430         struct svr4_sys_fstatvfs64_args *uap;
1431 {
1432         struct fstatfs_args     fs_args;
1433         caddr_t sg = stackgap_init();
1434         struct statfs *fs = stackgap_alloc(&sg, sizeof(struct statfs));
1435         struct statfs bfs;
1436         struct svr4_statvfs64 sfs;
1437         int error;
1438
1439         SCARG(&fs_args, fd) = SCARG(uap, fd);
1440         SCARG(&fs_args, buf) = fs;
1441
1442         if ((error = fstatfs(p, &fs_args)) != 0)
1443                 return error;
1444
1445         if ((error = copyin(fs, &bfs, sizeof(bfs))) != 0)
1446                 return error;
1447
1448         bsd_statfs_to_svr4_statvfs64(&bfs, &sfs);
1449
1450         return copyout(&sfs, SCARG(uap, fs), sizeof(sfs));
1451 }
1452
1453 int
1454 svr4_sys_alarm(p, uap)
1455         struct proc *p;
1456         struct svr4_sys_alarm_args *uap;
1457 {
1458         int error;
1459         struct itimerval *itp, *oitp;
1460         struct setitimer_args sa;
1461         caddr_t sg = stackgap_init();
1462
1463         itp = stackgap_alloc(&sg, sizeof(*itp));
1464         oitp = stackgap_alloc(&sg, sizeof(*oitp));
1465         timevalclear(&itp->it_interval);
1466         itp->it_value.tv_sec = SCARG(uap, sec);
1467         itp->it_value.tv_usec = 0;
1468
1469         SCARG(&sa, which) = ITIMER_REAL;
1470         SCARG(&sa, itv) = itp;
1471         SCARG(&sa, oitv) = oitp;
1472         error = setitimer(p, &sa);
1473         if (error)
1474                 return error;
1475         if (oitp->it_value.tv_usec)
1476                 oitp->it_value.tv_sec++;
1477         p->p_retval[0] = oitp->it_value.tv_sec;
1478         return 0;
1479
1480 }
1481
1482 int
1483 svr4_sys_gettimeofday(p, uap)
1484         struct proc *p;
1485         struct svr4_sys_gettimeofday_args *uap;
1486 {
1487         if (SCARG(uap, tp)) {
1488                 struct timeval atv;
1489
1490                 microtime(&atv);
1491                 return copyout(&atv, SCARG(uap, tp), sizeof (atv));
1492         }
1493
1494         return 0;
1495 }
1496
1497 int
1498 svr4_sys_facl(p, uap)
1499         struct proc *p;
1500         struct svr4_sys_facl_args *uap;
1501 {
1502         int *retval;
1503
1504         retval = p->p_retval;
1505         *retval = 0;
1506
1507         switch (SCARG(uap, cmd)) {
1508         case SVR4_SYS_SETACL:
1509                 /* We don't support acls on any filesystem */
1510                 return ENOSYS;
1511
1512         case SVR4_SYS_GETACL:
1513                 return copyout(retval, &SCARG(uap, num),
1514                     sizeof(SCARG(uap, num)));
1515
1516         case SVR4_SYS_GETACLCNT:
1517                 return 0;
1518
1519         default:
1520                 return EINVAL;
1521         }
1522 }
1523
1524
1525 int
1526 svr4_sys_acl(p, uap)
1527         struct proc *p;
1528         struct svr4_sys_acl_args *uap;
1529 {
1530         /* XXX: for now the same */
1531         return svr4_sys_facl(p, (struct svr4_sys_facl_args *)uap);
1532 }
1533
1534 int
1535 svr4_sys_auditsys(p, uap)
1536         struct proc *p;
1537         struct svr4_sys_auditsys_args *uap;
1538 {
1539         /*
1540          * XXX: Big brother is *not* watching.
1541          */
1542         return 0;
1543 }
1544
1545 int
1546 svr4_sys_memcntl(p, uap)
1547         struct proc *p;
1548         struct svr4_sys_memcntl_args *uap;
1549 {
1550         switch (SCARG(uap, cmd)) {
1551         case SVR4_MC_SYNC:
1552                 {
1553                         struct msync_args msa;
1554
1555                         SCARG(&msa, addr) = SCARG(uap, addr);
1556                         SCARG(&msa, len) = SCARG(uap, len);
1557                         SCARG(&msa, flags) = (int)SCARG(uap, arg);
1558
1559                         return msync(p, &msa);
1560                 }
1561         case SVR4_MC_ADVISE:
1562                 {
1563                         struct madvise_args maa;
1564
1565                         SCARG(&maa, addr) = SCARG(uap, addr);
1566                         SCARG(&maa, len) = SCARG(uap, len);
1567                         SCARG(&maa, behav) = (int)SCARG(uap, arg);
1568
1569                         return madvise(p, &maa);
1570                 }
1571         case SVR4_MC_LOCK:
1572         case SVR4_MC_UNLOCK:
1573         case SVR4_MC_LOCKAS:
1574         case SVR4_MC_UNLOCKAS:
1575                 return EOPNOTSUPP;
1576         default:
1577                 return ENOSYS;
1578         }
1579 }
1580
1581
1582 int
1583 svr4_sys_nice(p, uap)
1584         struct proc *p;
1585         struct svr4_sys_nice_args *uap;
1586 {
1587         struct setpriority_args ap;
1588         int error;
1589
1590         SCARG(&ap, which) = PRIO_PROCESS;
1591         SCARG(&ap, who) = 0;
1592         SCARG(&ap, prio) = SCARG(uap, prio);
1593
1594         if ((error = setpriority(p, &ap)) != 0)
1595                 return error;
1596
1597         /* the cast is stupid, but the structures are the same */
1598         if ((error = getpriority(p, (struct getpriority_args *)&ap)) != 0)
1599                 return error;
1600
1601         return 0;
1602 }
1603
1604 int
1605 svr4_sys_resolvepath(p, uap)
1606         struct proc *p;
1607         struct svr4_sys_resolvepath_args *uap;
1608 {
1609         struct nameidata nd;
1610         int error, *retval = p->p_retval;
1611
1612         NDINIT(&nd, LOOKUP, NOFOLLOW | SAVENAME, UIO_USERSPACE,
1613             SCARG(uap, path), p);
1614
1615         if ((error = namei(&nd)) != 0)
1616                 return error;
1617
1618         if ((error = copyout(nd.ni_cnd.cn_pnbuf, SCARG(uap, buf),
1619             SCARG(uap, bufsiz))) != 0)
1620                 goto bad;
1621
1622         *retval = strlen(nd.ni_cnd.cn_pnbuf) < SCARG(uap, bufsiz) ? 
1623           strlen(nd.ni_cnd.cn_pnbuf) + 1 : SCARG(uap, bufsiz);
1624 bad:
1625         vput(nd.ni_vp);
1626         zfree(namei_zone, nd.ni_cnd.cn_pnbuf);
1627         return error;
1628 }