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