1 /* $NetBSD: svr4_misc.c,v 1.156 2014/09/05 09:21:55 matt Exp $ */
2
3 /*-
4 * Copyright (c) 1994, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Christos Zoulas.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*
33 * SVR4 compatibility module.
34 *
35 * SVR4 system calls that are implemented differently in BSD are
36 * handled here.
37 */
38
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: svr4_misc.c,v 1.156 2014/09/05 09:21:55 matt Exp $");
41
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/namei.h>
45 #include <sys/dirent.h>
46 #include <sys/proc.h>
47 #include <sys/file.h>
48 #include <sys/stat.h>
49 #include <sys/time.h>
50 #include <sys/filedesc.h>
51 #include <sys/ioctl.h>
52 #include <sys/kernel.h>
53 #include <sys/malloc.h>
54 #include <sys/pool.h>
55 #include <sys/mbuf.h>
56 #include <sys/mman.h>
57 #include <sys/mount.h>
58 #include <sys/resource.h>
59 #include <sys/resourcevar.h>
60 #include <sys/socket.h>
61 #include <sys/vnode.h>
62 #include <sys/uio.h>
63 #include <sys/wait.h>
64 #include <sys/utsname.h>
65 #include <sys/unistd.h>
66 #include <sys/vfs_syscalls.h>
67 #include <sys/times.h>
68 #include <sys/sem.h>
69 #include <sys/msg.h>
70 #include <sys/ptrace.h>
71 #include <sys/signalvar.h>
72
73 #include <netinet/in.h>
74 #include <sys/syscallargs.h>
75
76 #include <miscfs/specfs/specdev.h>
77
78 #include <compat/svr4/svr4_types.h>
79 #include <compat/svr4/svr4_signal.h>
80 #include <compat/svr4/svr4_lwp.h>
81 #include <compat/svr4/svr4_ucontext.h>
82 #include <compat/svr4/svr4_syscallargs.h>
83 #include <compat/svr4/svr4_util.h>
84 #include <compat/svr4/svr4_time.h>
85 #include <compat/svr4/svr4_dirent.h>
86 #include <compat/svr4/svr4_ulimit.h>
87 #include <compat/svr4/svr4_hrt.h>
88 #include <compat/svr4/svr4_wait.h>
89 #include <compat/svr4/svr4_statvfs.h>
90 #include <compat/svr4/svr4_sysconfig.h>
91 #include <compat/svr4/svr4_acl.h>
92 #include <compat/svr4/svr4_mman.h>
93
94 #include <sys/cpu.h>
95
96 #include <uvm/uvm_extern.h>
97
98 static int svr4_to_bsd_mmap_flags(int);
99
100 static inline clock_t timeval_to_clock_t(struct timeval *);
101 static void svr4_setinfo(int, struct rusage *, int, svr4_siginfo_t *);
102
103 struct svr4_hrtcntl_args;
104 static int svr4_hrtcntl(struct lwp *, const struct svr4_hrtcntl_args *,
105 register_t *);
106
107 static int svr4_mknod(struct lwp *, register_t *, const char *,
108 svr4_mode_t, svr4_dev_t);
109
110 int
svr4_sys_wait(struct lwp * l,const struct svr4_sys_wait_args * uap,register_t * retval)111 svr4_sys_wait(struct lwp *l, const struct svr4_sys_wait_args *uap,
112 register_t *retval)
113 {
114 int error, st, sig, pid = WAIT_ANY;
115
116 error = do_sys_wait(&pid, &st, 0, NULL);
117
118 retval[0] = pid;
119 if (pid == 0)
120 return error;
121
122 if (WIFSIGNALED(st)) {
123 sig = WTERMSIG(st);
124 if (sig >= 0 && sig < NSIG)
125 st = (st & ~0177) | native_to_svr4_signo[sig];
126 } else if (WIFSTOPPED(st)) {
127 sig = WSTOPSIG(st);
128 if (sig >= 0 && sig < NSIG)
129 st = (st & ~0xff00) | (native_to_svr4_signo[sig] << 8);
130 }
131
132 /*
133 * It looks like wait(2) on svr4/solaris/2.4 returns
134 * the status in retval[1], and the pid on retval[0].
135 */
136 retval[1] = st;
137
138 if (SCARG(uap, status))
139 error = copyout(&st, SCARG(uap, status), sizeof(st));
140
141 return error;
142 }
143
144
145 int
svr4_sys_execv(struct lwp * l,const struct svr4_sys_execv_args * uap,register_t * retval)146 svr4_sys_execv(struct lwp *l, const struct svr4_sys_execv_args *uap, register_t *retval)
147 {
148 /* {
149 syscallarg(char *) path;
150 syscallarg(char **) argv;
151 } */
152 struct sys_execve_args ap;
153
154 SCARG(&ap, path) = SCARG(uap, path);
155 SCARG(&ap, argp) = SCARG(uap, argp);
156 SCARG(&ap, envp) = NULL;
157
158 return sys_execve(l, &ap, retval);
159 }
160
161
162 int
svr4_sys_execve(struct lwp * l,const struct svr4_sys_execve_args * uap,register_t * retval)163 svr4_sys_execve(struct lwp *l, const struct svr4_sys_execve_args *uap, register_t *retval)
164 {
165 /* {
166 syscallarg(const char *) path;
167 syscallarg(char **) argv;
168 syscallarg(char **) envp;
169 } */
170 struct sys_execve_args ap;
171
172 SCARG(&ap, path) = SCARG(uap, path);
173 SCARG(&ap, argp) = SCARG(uap, argp);
174 SCARG(&ap, envp) = SCARG(uap, envp);
175
176 return sys_execve(l, &ap, retval);
177 }
178
179
180 int
svr4_sys_time(struct lwp * l,const struct svr4_sys_time_args * uap,register_t * retval)181 svr4_sys_time(struct lwp *l, const struct svr4_sys_time_args *uap, register_t *retval)
182 {
183 int error = 0;
184 struct timeval tv;
185
186 microtime(&tv);
187 if (SCARG(uap, t))
188 error = copyout(&tv.tv_sec, SCARG(uap, t),
189 sizeof(*(SCARG(uap, t))));
190 *retval = (int) tv.tv_sec;
191
192 return error;
193 }
194
195
196 /*
197 * Read SVR4-style directory entries. We suck them into kernel space so
198 * that they can be massaged before being copied out to user code. Like
199 * SunOS, we squish out `empty' entries.
200 *
201 * This is quite ugly, but what do you expect from compatibility code?
202 */
203 int
svr4_sys_getdents64(struct lwp * l,const struct svr4_sys_getdents64_args * uap,register_t * retval)204 svr4_sys_getdents64(struct lwp *l, const struct svr4_sys_getdents64_args *uap, register_t *retval)
205 {
206 struct dirent *bdp;
207 struct vnode *vp;
208 char *inp, *tbuf; /* BSD-format */
209 int len, reclen; /* BSD-format */
210 char *outp; /* SVR4-format */
211 int resid, svr4_reclen; /* SVR4-format */
212 struct file *fp;
213 struct uio auio;
214 struct iovec aiov;
215 struct svr4_dirent64 idb;
216 off_t off; /* true file offset */
217 int buflen, error, eofflag;
218 off_t *cookiebuf = NULL, *cookie;
219 int ncookies;
220
221 /* fd_getvnode() will use the descriptor for us */
222 if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
223 return (error);
224
225 if ((fp->f_flag & FREAD) == 0) {
226 error = EBADF;
227 goto out1;
228 }
229
230 vp = fp->f_vnode;
231 if (vp->v_type != VDIR) {
232 error = EINVAL;
233 goto out1;
234 }
235
236 buflen = min(MAXBSIZE, SCARG(uap, nbytes));
237 tbuf = malloc(buflen, M_TEMP, M_WAITOK);
238 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
239 off = fp->f_offset;
240 again:
241 aiov.iov_base = tbuf;
242 aiov.iov_len = buflen;
243 auio.uio_iov = &aiov;
244 auio.uio_iovcnt = 1;
245 auio.uio_rw = UIO_READ;
246 auio.uio_resid = buflen;
247 auio.uio_offset = off;
248 UIO_SETUP_SYSSPACE(&auio);
249 /*
250 * First we read into the malloc'ed buffer, then
251 * we massage it into user space, one record at a time.
252 */
253 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &cookiebuf,
254 &ncookies);
255 if (error)
256 goto out;
257
258 inp = tbuf;
259 outp = (char *) SCARG(uap, dp);
260 resid = SCARG(uap, nbytes);
261 if ((len = buflen - auio.uio_resid) == 0)
262 goto eof;
263
264 for (cookie = cookiebuf; len > 0; len -= reclen) {
265 bdp = (struct dirent *)inp;
266 reclen = bdp->d_reclen;
267 if (reclen & 3)
268 panic("svr4_getdents64: bad reclen");
269 if (bdp->d_fileno == 0) {
270 inp += reclen; /* it is a hole; squish it out */
271 if (cookie)
272 off = *cookie++;
273 else
274 off += reclen;
275 continue;
276 }
277 svr4_reclen = SVR4_RECLEN(&idb, bdp->d_namlen);
278 if (reclen > len || resid < svr4_reclen) {
279 /* entry too big for buffer, so just stop */
280 outp++;
281 break;
282 }
283 if (cookie)
284 off = *cookie++; /* each entry points to the next */
285 else
286 off += reclen;
287 /*
288 * Massage in place to make a SVR4-shaped dirent (otherwise
289 * we have to worry about touching user memory outside of
290 * the copyout() call).
291 */
292 idb.d_ino = (svr4_ino64_t)bdp->d_fileno;
293 idb.d_off = (svr4_off64_t)off;
294 idb.d_reclen = (u_short)svr4_reclen;
295 strlcpy(idb.d_name, bdp->d_name, sizeof(idb.d_name));
296 if ((error = copyout((void *)&idb, outp, svr4_reclen)))
297 goto out;
298 /* advance past this real entry */
299 inp += reclen;
300 /* advance output past SVR4-shaped entry */
301 outp += svr4_reclen;
302 resid -= svr4_reclen;
303 }
304
305 /* if we squished out the whole block, try again */
306 if (outp == (char *) SCARG(uap, dp)) {
307 if (cookiebuf)
308 free(cookiebuf, M_TEMP);
309 cookiebuf = NULL;
310 goto again;
311 }
312 fp->f_offset = off; /* update the vnode offset */
313
314 eof:
315 *retval = SCARG(uap, nbytes) - resid;
316 out:
317 VOP_UNLOCK(vp);
318 if (cookiebuf)
319 free(cookiebuf, M_TEMP);
320 free(tbuf, M_TEMP);
321 out1:
322 fd_putfile(SCARG(uap, fd));
323 return error;
324 }
325
326
327 int
svr4_sys_getdents(struct lwp * l,const struct svr4_sys_getdents_args * uap,register_t * retval)328 svr4_sys_getdents(struct lwp *l, const struct svr4_sys_getdents_args *uap, register_t *retval)
329 {
330 struct dirent *bdp;
331 struct vnode *vp;
332 char *inp, *tbuf; /* BSD-format */
333 int len, reclen; /* BSD-format */
334 char *outp; /* SVR4-format */
335 int resid, svr4_reclen; /* SVR4-format */
336 struct file *fp;
337 struct uio auio;
338 struct iovec aiov;
339 struct svr4_dirent idb;
340 off_t off; /* true file offset */
341 int buflen, error, eofflag;
342 off_t *cookiebuf = NULL, *cookie;
343 int ncookies;
344
345 /* fd_getvnode() will use the descriptor for us */
346 if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
347 return (error);
348
349 if ((fp->f_flag & FREAD) == 0) {
350 error = EBADF;
351 goto out1;
352 }
353
354 vp = fp->f_vnode;
355 if (vp->v_type != VDIR) {
356 error = EINVAL;
357 goto out1;
358 }
359
360 buflen = min(MAXBSIZE, SCARG(uap, nbytes));
361 tbuf = malloc(buflen, M_TEMP, M_WAITOK);
362 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
363 off = fp->f_offset;
364 again:
365 aiov.iov_base = tbuf;
366 aiov.iov_len = buflen;
367 auio.uio_iov = &aiov;
368 auio.uio_iovcnt = 1;
369 auio.uio_rw = UIO_READ;
370 auio.uio_resid = buflen;
371 auio.uio_offset = off;
372 UIO_SETUP_SYSSPACE(&auio);
373 /*
374 * First we read into the malloc'ed buffer, then
375 * we massage it into user space, one record at a time.
376 */
377 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &cookiebuf,
378 &ncookies);
379 if (error)
380 goto out;
381
382 inp = tbuf;
383 outp = SCARG(uap, buf);
384 resid = SCARG(uap, nbytes);
385 if ((len = buflen - auio.uio_resid) == 0)
386 goto eof;
387
388 for (cookie = cookiebuf; len > 0; len -= reclen) {
389 bdp = (struct dirent *)inp;
390 reclen = bdp->d_reclen;
391 if (reclen & 3)
392 panic("svr4_getdents: bad reclen");
393 if (cookie)
394 off = *cookie++; /* each entry points to the next */
395 else
396 off += reclen;
397 if ((off >> 32) != 0) {
398 compat_offseterr(vp, "svr4_getdents");
399 error = EINVAL;
400 goto out;
401 }
402 if (bdp->d_fileno == 0) {
403 inp += reclen; /* it is a hole; squish it out */
404 continue;
405 }
406 svr4_reclen = SVR4_RECLEN(&idb, bdp->d_namlen);
407 if (reclen > len || resid < svr4_reclen) {
408 /* entry too big for buffer, so just stop */
409 outp++;
410 break;
411 }
412 /*
413 * Massage in place to make a SVR4-shaped dirent (otherwise
414 * we have to worry about touching user memory outside of
415 * the copyout() call).
416 */
417 idb.d_ino = (svr4_ino_t)bdp->d_fileno;
418 idb.d_off = (svr4_off_t)off;
419 idb.d_reclen = (u_short)svr4_reclen;
420 strlcpy(idb.d_name, bdp->d_name, sizeof(idb.d_name));
421 if ((error = copyout((void *)&idb, outp, svr4_reclen)))
422 goto out;
423 /* advance past this real entry */
424 inp += reclen;
425 /* advance output past SVR4-shaped entry */
426 outp += svr4_reclen;
427 resid -= svr4_reclen;
428 }
429
430 /* if we squished out the whole block, try again */
431 if (outp == SCARG(uap, buf)) {
432 if (cookiebuf)
433 free(cookiebuf, M_TEMP);
434 cookiebuf = NULL;
435 goto again;
436 }
437 fp->f_offset = off; /* update the vnode offset */
438
439 eof:
440 *retval = SCARG(uap, nbytes) - resid;
441 out:
442 VOP_UNLOCK(vp);
443 if (cookiebuf)
444 free(cookiebuf, M_TEMP);
445 free(tbuf, M_TEMP);
446 out1:
447 fd_putfile(SCARG(uap, fd));
448 return error;
449 }
450
451
452 static int
svr4_to_bsd_mmap_flags(int f)453 svr4_to_bsd_mmap_flags(int f)
454 {
455 int type = f & SVR4_MAP_TYPE;
456 int nf;
457
458 if (type != MAP_PRIVATE && type != MAP_SHARED)
459 return -1;
460
461 nf = f & SVR4_MAP_COPYFLAGS;
462 if (f & SVR4_MAP_ANON)
463 nf |= MAP_ANON;
464
465 return nf;
466 }
467
468
469 int
svr4_sys_mmap(struct lwp * l,const struct svr4_sys_mmap_args * uap,register_t * retval)470 svr4_sys_mmap(struct lwp *l, const struct svr4_sys_mmap_args *uap, register_t *retval)
471 {
472 struct sys_mmap_args mm;
473 /*
474 * Verify the arguments.
475 */
476 if (SCARG(uap, prot) & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
477 return EINVAL; /* XXX still needed? */
478
479 if (SCARG(uap, len) == 0)
480 return EINVAL;
481
482 if ((SCARG(&mm, flags) = svr4_to_bsd_mmap_flags(SCARG(uap, flags))) == -1)
483 return EINVAL;
484
485 SCARG(&mm, prot) = SCARG(uap, prot);
486 SCARG(&mm, len) = SCARG(uap, len);
487 SCARG(&mm, fd) = SCARG(uap, fd);
488 SCARG(&mm, addr) = SCARG(uap, addr);
489 SCARG(&mm, pos) = SCARG(uap, pos);
490
491 return sys_mmap(l, &mm, retval);
492 }
493
494
495 int
svr4_sys_mmap64(struct lwp * l,const struct svr4_sys_mmap64_args * uap,register_t * retval)496 svr4_sys_mmap64(struct lwp *l, const struct svr4_sys_mmap64_args *uap, register_t *retval)
497 {
498 struct sys_mmap_args mm;
499 /*
500 * Verify the arguments.
501 */
502 if (SCARG(uap, prot) & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
503 return EINVAL; /* XXX still needed? */
504
505 if (SCARG(uap, len) == 0)
506 return EINVAL;
507
508 if ((SCARG(&mm, flags) = svr4_to_bsd_mmap_flags(SCARG(uap, flags))) == -1)
509 return EINVAL;
510
511 SCARG(&mm, prot) = SCARG(uap, prot);
512 SCARG(&mm, len) = SCARG(uap, len);
513 SCARG(&mm, fd) = SCARG(uap, fd);
514 SCARG(&mm, addr) = SCARG(uap, addr);
515 SCARG(&mm, pos) = SCARG(uap, pos);
516
517 return sys_mmap(l, &mm, retval);
518 }
519
520
521 static int
svr4_mknod(struct lwp * l,register_t * retval,const char * path,svr4_mode_t mode,svr4_dev_t dev)522 svr4_mknod(struct lwp *l, register_t *retval, const char *path, svr4_mode_t mode, svr4_dev_t dev)
523 {
524 if (S_ISFIFO(mode)) {
525 struct sys_mkfifo_args ap;
526 SCARG(&ap, path) = path;
527 SCARG(&ap, mode) = mode;
528 return sys_mkfifo(l, &ap, retval);
529 } else {
530 return do_sys_mknod(l, path, mode, dev, retval, UIO_USERSPACE);
531 }
532 }
533
534
535 int
svr4_sys_mknod(struct lwp * l,const struct svr4_sys_mknod_args * uap,register_t * retval)536 svr4_sys_mknod(struct lwp *l, const struct svr4_sys_mknod_args *uap, register_t *retval)
537 {
538 return svr4_mknod(l, retval,
539 SCARG(uap, path), SCARG(uap, mode),
540 svr4_to_bsd_odev_t(SCARG(uap, dev)));
541 }
542
543
544 int
svr4_sys_xmknod(struct lwp * l,const struct svr4_sys_xmknod_args * uap,register_t * retval)545 svr4_sys_xmknod(struct lwp *l, const struct svr4_sys_xmknod_args *uap, register_t *retval)
546 {
547 return svr4_mknod(l, retval,
548 SCARG(uap, path), SCARG(uap, mode),
549 svr4_to_bsd_dev_t(SCARG(uap, dev)));
550 }
551
552
553 int
svr4_sys_vhangup(struct lwp * l,const void * v,register_t * retval)554 svr4_sys_vhangup(struct lwp *l, const void *v, register_t *retval)
555 {
556 return 0;
557 }
558
559
560 int
svr4_sys_sysconfig(struct lwp * l,const struct svr4_sys_sysconfig_args * uap,register_t * retval)561 svr4_sys_sysconfig(struct lwp *l, const struct svr4_sys_sysconfig_args *uap, register_t *retval)
562 {
563 int active;
564
565 switch (SCARG(uap, name)) {
566 case SVR4_CONFIG_NGROUPS:
567 *retval = NGROUPS_MAX;
568 break;
569 case SVR4_CONFIG_CHILD_MAX:
570 *retval = maxproc;
571 break;
572 case SVR4_CONFIG_OPEN_FILES:
573 *retval = maxfiles;
574 break;
575 case SVR4_CONFIG_POSIX_VER:
576 *retval = 198808;
577 break;
578 case SVR4_CONFIG_PAGESIZE:
579 *retval = PAGE_SIZE;
580 break;
581 case SVR4_CONFIG_CLK_TCK:
582 *retval = 60; /* should this be `hz', ie. 100? */
583 break;
584 case SVR4_CONFIG_XOPEN_VER:
585 *retval = 2; /* XXX: What should that be? */
586 break;
587 case SVR4_CONFIG_PROF_TCK:
588 *retval = 60; /* XXX: What should that be? */
589 break;
590 case SVR4_CONFIG_NPROC_CONF:
591 *retval = 1; /* Only one processor for now */
592 break;
593 case SVR4_CONFIG_NPROC_ONLN:
594 *retval = 1; /* And it better be online */
595 break;
596 case SVR4_CONFIG_AIO_LISTIO_MAX:
597 case SVR4_CONFIG_AIO_MAX:
598 case SVR4_CONFIG_AIO_PRIO_DELTA_MAX:
599 *retval = 0; /* No aio support */
600 break;
601 case SVR4_CONFIG_DELAYTIMER_MAX:
602 *retval = 0; /* No delaytimer support */
603 break;
604 case SVR4_CONFIG_MQ_OPEN_MAX:
605 #ifdef SYSVMSG
606 *retval = msginfo.msgmni;
607 #else
608 *retval = 0;
609 #endif
610 break;
611 case SVR4_CONFIG_MQ_PRIO_MAX:
612 *retval = 0; /* XXX: Don't know */
613 break;
614 case SVR4_CONFIG_RTSIG_MAX:
615 *retval = 0;
616 break;
617 case SVR4_CONFIG_SEM_NSEMS_MAX:
618 #ifdef SYSVSEM
619 *retval = seminfo.semmni;
620 #else
621 *retval = 0;
622 #endif
623 break;
624 case SVR4_CONFIG_SEM_VALUE_MAX:
625 #ifdef SYSVSEM
626 *retval = seminfo.semvmx;
627 #else
628 *retval = 0;
629 #endif
630 break;
631 case SVR4_CONFIG_SIGQUEUE_MAX:
632 *retval = 0; /* XXX: Don't know */
633 break;
634 case SVR4_CONFIG_SIGRT_MIN:
635 case SVR4_CONFIG_SIGRT_MAX:
636 *retval = 0; /* No real time signals */
637 break;
638 case SVR4_CONFIG_TIMER_MAX:
639 *retval = 3; /* XXX: real, virtual, profiling */
640 break;
641 case SVR4_CONFIG_PHYS_PAGES:
642 *retval = uvmexp.free; /* XXX: free instead of total */
643 break;
644 case SVR4_CONFIG_AVPHYS_PAGES:
645 uvm_estimatepageable(&active, NULL);
646 *retval = active; /* XXX: active instead of avg */
647 break;
648 case SVR4_CONFIG_COHERENCY:
649 *retval = 0; /* XXX */
650 break;
651 case SVR4_CONFIG_SPLIT_CACHE:
652 *retval = 0; /* XXX */
653 break;
654 case SVR4_CONFIG_ICACHESZ:
655 *retval = 256; /* XXX */
656 break;
657 case SVR4_CONFIG_DCACHESZ:
658 *retval = 256; /* XXX */
659 break;
660 case SVR4_CONFIG_ICACHELINESZ:
661 *retval = 64; /* XXX */
662 break;
663 case SVR4_CONFIG_DCACHELINESZ:
664 *retval = 64; /* XXX */
665 break;
666 case SVR4_CONFIG_ICACHEBLKSZ:
667 *retval = 64; /* XXX */
668 break;
669 case SVR4_CONFIG_DCACHEBLKSZ:
670 *retval = 64; /* XXX */
671 break;
672 case SVR4_CONFIG_DCACHETBLKSZ:
673 *retval = 64; /* XXX */
674 break;
675 case SVR4_CONFIG_ICACHE_ASSOC:
676 *retval = 1; /* XXX */
677 break;
678 case SVR4_CONFIG_DCACHE_ASSOC:
679 *retval = 1; /* XXX */
680 break;
681 case SVR4_CONFIG_MAXPID:
682 *retval = PID_MAX;
683 break;
684 case SVR4_CONFIG_STACK_PROT:
685 *retval = PROT_READ|PROT_WRITE|PROT_EXEC;
686 break;
687 default:
688 return EINVAL;
689 }
690 return 0;
691 }
692
693 /* ARGSUSED */
694 int
svr4_sys_break(struct lwp * l,const struct svr4_sys_break_args * uap,register_t * retval)695 svr4_sys_break(struct lwp *l, const struct svr4_sys_break_args *uap, register_t *retval)
696 {
697 struct proc *p = l->l_proc;
698 struct vmspace *vm = p->p_vmspace;
699 vaddr_t new, old;
700 int error;
701
702 old = (vaddr_t) vm->vm_daddr;
703 new = round_page((vaddr_t)SCARG(uap, nsize));
704
705 if (new - old > p->p_rlimit[RLIMIT_DATA].rlim_cur && new > old)
706 return ENOMEM;
707
708 old = round_page(old + ctob(vm->vm_dsize));
709 DPRINTF(("break(2): dsize = %x ctob %x\n",
710 vm->vm_dsize, ctob(vm->vm_dsize)));
711
712 if (new > old) {
713 error = uvm_map(&vm->vm_map, &old, new - old, NULL,
714 UVM_UNKNOWN_OFFSET, 0,
715 UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_COPY,
716 UVM_ADV_NORMAL,
717 UVM_FLAG_AMAPPAD|UVM_FLAG_FIXED|
718 UVM_FLAG_OVERLAY|UVM_FLAG_COPYONW));
719 if (error) {
720 uprintf("sbrk: grow failed, error = %d\n", error);
721 return error;
722 }
723 vm->vm_dsize += btoc(new - old);
724 } else if (new < old) {
725 uvm_deallocate(&vm->vm_map, new, old - new);
726 vm->vm_dsize -= btoc(old - new);
727 }
728 return 0;
729 }
730
731
732 static inline clock_t
timeval_to_clock_t(struct timeval * tv)733 timeval_to_clock_t(struct timeval *tv)
734 {
735 return tv->tv_sec * hz + tv->tv_usec / (1000000 / hz);
736 }
737
738
739 int
svr4_sys_times(struct lwp * l,const struct svr4_sys_times_args * uap,register_t * retval)740 svr4_sys_times(struct lwp *l, const struct svr4_sys_times_args *uap, register_t *retval)
741 {
742 struct tms tms;
743 struct timeval t;
744 struct rusage ru, *rup;
745 struct proc *p = l->l_proc;
746
747 ru = p->p_stats->p_ru;
748 mutex_enter(p->p_lock);
749 calcru(p, &ru.ru_utime, &ru.ru_stime, NULL, NULL);
750 rulwps(p, &ru);
751 mutex_exit(p->p_lock);
752
753 tms.tms_utime = timeval_to_clock_t(&ru.ru_utime);
754 tms.tms_stime = timeval_to_clock_t(&ru.ru_stime);
755
756 rup = &p->p_stats->p_cru;
757 tms.tms_cutime = timeval_to_clock_t(&rup->ru_utime);
758 tms.tms_cstime = timeval_to_clock_t(&rup->ru_stime);
759
760 microtime(&t);
761 *retval = timeval_to_clock_t(&t);
762
763 return copyout(&tms, SCARG(uap, tp), sizeof(tms));
764 }
765
766
767 int
svr4_sys_ulimit(struct lwp * l,const struct svr4_sys_ulimit_args * uap,register_t * retval)768 svr4_sys_ulimit(struct lwp *l, const struct svr4_sys_ulimit_args *uap, register_t *retval)
769 {
770 struct proc *p = l->l_proc;
771 int error;
772 struct rlimit krl;
773 register_t r;
774
775 switch (SCARG(uap, cmd)) {
776 case SVR4_GFILLIM:
777 r = p->p_rlimit[RLIMIT_FSIZE].rlim_cur / 512;
778 break;
779
780 case SVR4_SFILLIM:
781 krl.rlim_cur = SCARG(uap, newlimit) * 512;
782 krl.rlim_max = p->p_rlimit[RLIMIT_FSIZE].rlim_max;
783
784 error = dosetrlimit(l, l->l_proc, RLIMIT_FSIZE, &krl);
785 if (error)
786 return error;
787
788 r = p->p_rlimit[RLIMIT_FSIZE].rlim_cur;
789 break;
790
791 case SVR4_GMEMLIM:
792 r = p->p_rlimit[RLIMIT_DATA].rlim_cur;
793 if (r > 0x7fffffff)
794 r = 0x7fffffff;
795 r += (long)p->p_vmspace->vm_daddr;
796 break;
797
798 case SVR4_GDESLIM:
799 r = p->p_rlimit[RLIMIT_NOFILE].rlim_cur;
800 break;
801
802 default:
803 return EINVAL;
804 }
805
806 *retval = r > 0x7fffffff ? 0x7fffffff : r;
807 return 0;
808 }
809
810
811 int
svr4_sys_pgrpsys(struct lwp * l,const struct svr4_sys_pgrpsys_args * uap,register_t * retval)812 svr4_sys_pgrpsys(struct lwp *l, const struct svr4_sys_pgrpsys_args *uap, register_t *retval)
813 {
814 struct proc *p = l->l_proc;
815 pid_t pid;
816
817 switch (SCARG(uap, cmd)) {
818 case 1: /* setpgrp() */
819 /*
820 * SVR4 setpgrp() (which takes no arguments) has the
821 * semantics that the session ID is also created anew, so
822 * in almost every sense, setpgrp() is identical to
823 * setsid() for SVR4. (Under BSD, the difference is that
824 * a setpgid(0,0) will not create a new session.)
825 */
826 sys_setsid(l, NULL, retval);
827 /*FALLTHROUGH*/
828
829 case 0: /* getpgrp() */
830 mutex_enter(proc_lock);
831 *retval = p->p_pgrp->pg_id;
832 mutex_exit(proc_lock);
833 return 0;
834
835 case 2: /* getsid(pid) */
836 mutex_enter(proc_lock);
837 pid = SCARG(uap, pid);
838 if (pid && (p = proc_find(pid)) == NULL) {
839 mutex_exit(proc_lock);
840 return ESRCH;
841 }
842 /*
843 * This has already been initialized to the pid of
844 * the session leader.
845 */
846 *retval = (register_t) p->p_session->s_sid;
847 mutex_exit(proc_lock);
848 return 0;
849
850 case 3: /* setsid() */
851 return sys_setsid(l, NULL, retval);
852
853 case 4: /* getpgid(pid) */
854 mutex_enter(proc_lock);
855 pid = SCARG(uap, pid);
856 if (pid && (p = proc_find(pid)) == NULL) {
857 mutex_exit(proc_lock);
858 return ESRCH;
859 }
860
861 *retval = (int) p->p_pgrp->pg_id;
862 mutex_exit(proc_lock);
863 return 0;
864
865 case 5: /* setpgid(pid, pgid); */
866 {
867 struct sys_setpgid_args sa;
868
869 SCARG(&sa, pid) = SCARG(uap, pid);
870 SCARG(&sa, pgid) = SCARG(uap, pgid);
871 return sys_setpgid(l, &sa, retval);
872 }
873
874 default:
875 return EINVAL;
876 }
877 }
878
879 struct svr4_hrtcntl_args {
880 syscallarg(int) cmd;
881 syscallarg(int) fun;
882 syscallarg(int) clk;
883 syscallarg(svr4_hrt_interval_t *) iv;
884 syscallarg(svr4_hrt_time_t *) ti;
885 };
886
887
888 static int
svr4_hrtcntl(struct lwp * l,const struct svr4_hrtcntl_args * uap,register_t * retval)889 svr4_hrtcntl(struct lwp *l, const struct svr4_hrtcntl_args *uap,
890 register_t *retval)
891 {
892 switch (SCARG(uap, fun)) {
893 case SVR4_HRT_CNTL_RES:
894 DPRINTF(("htrcntl(RES)\n"));
895 *retval = SVR4_HRT_USEC;
896 return 0;
897
898 case SVR4_HRT_CNTL_TOFD:
899 DPRINTF(("htrcntl(TOFD)\n"));
900 {
901 struct timeval tv;
902 svr4_hrt_time_t t;
903 if (SCARG(uap, clk) != SVR4_HRT_CLK_STD) {
904 DPRINTF(("clk == %d\n", SCARG(uap, clk)));
905 return EINVAL;
906 }
907 if (SCARG(uap, ti) == NULL) {
908 DPRINTF(("ti NULL\n"));
909 return EINVAL;
910 }
911 microtime(&tv);
912 t.h_sec = tv.tv_sec;
913 t.h_rem = tv.tv_usec;
914 t.h_res = SVR4_HRT_USEC;
915 return copyout(&t, SCARG(uap, ti), sizeof(t));
916 }
917
918 case SVR4_HRT_CNTL_START:
919 DPRINTF(("htrcntl(START)\n"));
920 return ENOSYS;
921
922 case SVR4_HRT_CNTL_GET:
923 DPRINTF(("htrcntl(GET)\n"));
924 return ENOSYS;
925 default:
926 DPRINTF(("Bad htrcntl command %d\n", SCARG(uap, fun)));
927 return ENOSYS;
928 }
929 }
930
931
932 int
svr4_sys_hrtsys(struct lwp * l,const struct svr4_sys_hrtsys_args * uap,register_t * retval)933 svr4_sys_hrtsys(struct lwp *l, const struct svr4_sys_hrtsys_args *uap, register_t *retval)
934 {
935
936 switch (SCARG(uap, cmd)) {
937 case SVR4_HRT_CNTL:
938 return svr4_hrtcntl(l, (const struct svr4_hrtcntl_args *) uap,
939 retval);
940
941 case SVR4_HRT_ALRM:
942 DPRINTF(("hrtalarm\n"));
943 return ENOSYS;
944
945 case SVR4_HRT_SLP:
946 DPRINTF(("hrtsleep\n"));
947 return ENOSYS;
948
949 case SVR4_HRT_CAN:
950 DPRINTF(("hrtcancel\n"));
951 return ENOSYS;
952
953 default:
954 DPRINTF(("Bad hrtsys command %d\n", SCARG(uap, cmd)));
955 return EINVAL;
956 }
957 }
958
959
960 static void
svr4_setinfo(int pid,struct rusage * ru,int st,svr4_siginfo_t * s)961 svr4_setinfo(int pid, struct rusage *ru, int st, svr4_siginfo_t *s)
962 {
963 int sig;
964
965 memset(s, 0, sizeof(*s));
966
967 s->si_signo = SVR4_SIGCHLD;
968 s->si_errno = 0; /* XXX? */
969
970 if (pid != 0) {
971 s->si_pid = pid;
972 s->si_stime = ru->ru_stime.tv_sec;
973 s->si_utime = ru->ru_utime.tv_sec;
974 }
975
976 if (WIFEXITED(st)) {
977 s->si_status = WEXITSTATUS(st);
978 s->si_code = SVR4_CLD_EXITED;
979 } else if (WIFSTOPPED(st)) {
980 sig = WSTOPSIG(st);
981 if (sig >= 0 && sig < NSIG)
982 s->si_status = native_to_svr4_signo[sig];
983
984 if (s->si_status == SVR4_SIGCONT)
985 s->si_code = SVR4_CLD_CONTINUED;
986 else
987 s->si_code = SVR4_CLD_STOPPED;
988 } else {
989 sig = WTERMSIG(st);
990 if (sig >= 0 && sig < NSIG)
991 s->si_status = native_to_svr4_signo[sig];
992
993 if (WCOREDUMP(st))
994 s->si_code = SVR4_CLD_DUMPED;
995 else
996 s->si_code = SVR4_CLD_KILLED;
997 }
998
999 DPRINTF(("siginfo [pid %ld signo %d code %d errno %d status %d]\n",
1000 (long) s->si_pid,
1001 s->si_signo, s->si_code, s->si_errno, s->si_status));
1002 }
1003
1004
1005 int
svr4_sys_waitsys(struct lwp * l,const struct svr4_sys_waitsys_args * uap,register_t * retval)1006 svr4_sys_waitsys(struct lwp *l, const struct svr4_sys_waitsys_args *uap, register_t *retval)
1007 {
1008 int options, status;
1009 int error;
1010 struct rusage ru;
1011 svr4_siginfo_t i;
1012 int id = SCARG(uap, id);
1013
1014 switch (SCARG(uap, grp)) {
1015 case SVR4_P_PID:
1016 break;
1017
1018 case SVR4_P_PGID:
1019 mutex_enter(proc_lock);
1020 id = -l->l_proc->p_pgid;
1021 mutex_exit(proc_lock);
1022 break;
1023
1024 case SVR4_P_ALL:
1025 id = WAIT_ANY;
1026 break;
1027
1028 default:
1029 return EINVAL;
1030 }
1031
1032 /* Translate options */
1033 options = WOPTSCHECKED;
1034 if (SCARG(uap, options) & SVR4_WNOWAIT)
1035 options |= WNOWAIT;
1036 if (SCARG(uap, options) & SVR4_WNOHANG)
1037 options |= WNOHANG;
1038 if ((SCARG(uap, options) & (SVR4_WEXITED|SVR4_WTRAPPED)) == 0)
1039 options |= WNOZOMBIE;
1040 if (SCARG(uap, options) & (SVR4_WSTOPPED|SVR4_WCONTINUED))
1041 options |= WUNTRACED;
1042
1043 DPRINTF(("waitsys(%d, %d, %p, %x)\n",
1044 SCARG(uap, grp), id,
1045 SCARG(uap, info), SCARG(uap, options)));
1046
1047 error = do_sys_wait(&id, &status, options, &ru);
1048
1049 retval[0] = id;
1050 if (error != 0)
1051 return error;
1052
1053 svr4_setinfo(id, &ru, status, &i);
1054 return copyout(&i, SCARG(uap, info), sizeof(i));
1055 }
1056
1057
1058 static int
svr4_copyout_statvfs(const struct statvfs * bfs,struct svr4_statvfs * sufs)1059 svr4_copyout_statvfs(const struct statvfs *bfs, struct svr4_statvfs *sufs)
1060 {
1061 struct svr4_statvfs *sfs = malloc(sizeof(*sfs), M_TEMP, M_WAITOK);
1062 int error;
1063
1064 sfs->f_bsize = bfs->f_bsize;
1065 sfs->f_frsize = bfs->f_frsize;
1066 sfs->f_blocks = bfs->f_blocks;
1067 sfs->f_bfree = bfs->f_bfree;
1068 sfs->f_bavail = bfs->f_bavail;
1069 sfs->f_files = bfs->f_files;
1070 sfs->f_ffree = bfs->f_ffree;
1071 sfs->f_favail = bfs->f_favail;
1072 sfs->f_fsid = bfs->f_fsidx.__fsid_val[0];
1073 memcpy(sfs->f_basetype, bfs->f_fstypename, sizeof(sfs->f_basetype));
1074 sfs->f_flag = 0;
1075 if (bfs->f_flag & MNT_RDONLY)
1076 sfs->f_flag |= SVR4_ST_RDONLY;
1077 if (bfs->f_flag & MNT_NOSUID)
1078 sfs->f_flag |= SVR4_ST_NOSUID;
1079 sfs->f_namemax = bfs->f_namemax;
1080 memcpy(sfs->f_fstr, bfs->f_fstypename, sizeof(sfs->f_fstr)); /* XXX */
1081 memset(sfs->f_filler, 0, sizeof(sfs->f_filler));
1082
1083 error = copyout(sfs, sufs, sizeof(*sfs));
1084
1085 free(sfs, M_TEMP);
1086 return error;
1087 }
1088
1089
1090 static int
svr4_copyout_statvfs64(const struct statvfs * bfs,struct svr4_statvfs64 * sufs)1091 svr4_copyout_statvfs64(const struct statvfs *bfs, struct svr4_statvfs64 *sufs)
1092 {
1093 struct svr4_statvfs64 *sfs = malloc(sizeof(*sfs), M_TEMP, M_WAITOK);
1094 int error;
1095
1096 sfs->f_bsize = bfs->f_bsize;
1097 sfs->f_frsize = bfs->f_frsize;
1098 sfs->f_blocks = bfs->f_blocks;
1099 sfs->f_bfree = bfs->f_bfree;
1100 sfs->f_bavail = bfs->f_bavail;
1101 sfs->f_files = bfs->f_files;
1102 sfs->f_ffree = bfs->f_ffree;
1103 sfs->f_favail = bfs->f_ffree;
1104 sfs->f_fsid = bfs->f_fsidx.__fsid_val[0];
1105 memcpy(sfs->f_basetype, bfs->f_fstypename, sizeof(sfs->f_basetype));
1106 sfs->f_flag = 0;
1107 if (bfs->f_flag & MNT_RDONLY)
1108 sfs->f_flag |= SVR4_ST_RDONLY;
1109 if (bfs->f_flag & MNT_NOSUID)
1110 sfs->f_flag |= SVR4_ST_NOSUID;
1111 sfs->f_namemax = bfs->f_namemax;
1112 memcpy(sfs->f_fstr, bfs->f_fstypename, sizeof(sfs->f_fstr)); /* XXX */
1113 memset(sfs->f_filler, 0, sizeof(sfs->f_filler));
1114
1115 error = copyout(sfs, sufs, sizeof(*sfs));
1116
1117 free(sfs, M_TEMP);
1118 return error;
1119 }
1120
1121
1122 int
svr4_sys_statvfs(struct lwp * l,const struct svr4_sys_statvfs_args * uap,register_t * retval)1123 svr4_sys_statvfs(struct lwp *l, const struct svr4_sys_statvfs_args *uap, register_t *retval)
1124 {
1125 struct statvfs *sb;
1126 int error;
1127
1128 sb = STATVFSBUF_GET();
1129 error = do_sys_pstatvfs(l, SCARG(uap, path), ST_WAIT, sb);
1130 if (error == 0)
1131 error = svr4_copyout_statvfs(sb, SCARG(uap, fs));
1132 STATVFSBUF_PUT(sb);
1133 return error;
1134 }
1135
1136
1137 int
svr4_sys_fstatvfs(struct lwp * l,const struct svr4_sys_fstatvfs_args * uap,register_t * retval)1138 svr4_sys_fstatvfs(struct lwp *l, const struct svr4_sys_fstatvfs_args *uap, register_t *retval)
1139 {
1140 struct statvfs *sb;
1141 int error;
1142
1143 sb = STATVFSBUF_GET();
1144 error = do_sys_fstatvfs(l, SCARG(uap, fd), ST_WAIT, sb);
1145 if (error == 0)
1146 error = svr4_copyout_statvfs(sb, SCARG(uap, fs));
1147 STATVFSBUF_PUT(sb);
1148 return error;
1149 }
1150
1151
1152 int
svr4_sys_statvfs64(struct lwp * l,const struct svr4_sys_statvfs64_args * uap,register_t * retval)1153 svr4_sys_statvfs64(struct lwp *l, const struct svr4_sys_statvfs64_args *uap, register_t *retval)
1154 {
1155 struct statvfs *sb;
1156 int error;
1157
1158 sb = STATVFSBUF_GET();
1159 error = do_sys_pstatvfs(l, SCARG(uap, path), ST_WAIT, sb);
1160 if (error == 0)
1161 error = svr4_copyout_statvfs64(sb, SCARG(uap, fs));
1162 STATVFSBUF_PUT(sb);
1163 return error;
1164 }
1165
1166
1167 int
svr4_sys_fstatvfs64(struct lwp * l,const struct svr4_sys_fstatvfs64_args * uap,register_t * retval)1168 svr4_sys_fstatvfs64(struct lwp *l, const struct svr4_sys_fstatvfs64_args *uap, register_t *retval)
1169 {
1170 struct statvfs *sb;
1171 int error;
1172
1173 sb = STATVFSBUF_GET();
1174 error = do_sys_fstatvfs(l, SCARG(uap, fd), ST_WAIT, sb);
1175 if (error == 0)
1176 error = svr4_copyout_statvfs64(sb, SCARG(uap, fs));
1177 STATVFSBUF_PUT(sb);
1178 return error;
1179 }
1180
1181 int
svr4_sys_alarm(struct lwp * l,const struct svr4_sys_alarm_args * uap,register_t * retval)1182 svr4_sys_alarm(struct lwp *l, const struct svr4_sys_alarm_args *uap, register_t *retval)
1183 {
1184 struct itimerval tp;
1185
1186 dogetitimer(l->l_proc, ITIMER_REAL, &tp);
1187 if (tp.it_value.tv_usec)
1188 tp.it_value.tv_sec++;
1189 *retval = (register_t)tp.it_value.tv_sec;
1190
1191 timerclear(&tp.it_interval);
1192 tp.it_value.tv_sec = SCARG(uap, sec);
1193 tp.it_value.tv_usec = 0;
1194
1195 return dosetitimer(l->l_proc, ITIMER_REAL, &tp);
1196 }
1197
1198
1199 int
svr4_sys_gettimeofday(struct lwp * l,const struct svr4_sys_gettimeofday_args * uap,register_t * retval)1200 svr4_sys_gettimeofday(struct lwp *l, const struct svr4_sys_gettimeofday_args *uap, register_t *retval)
1201 {
1202
1203 if (SCARG(uap, tp)) {
1204 struct timeval atv;
1205
1206 microtime(&atv);
1207 return copyout(&atv, SCARG(uap, tp), sizeof (atv));
1208 }
1209
1210 return 0;
1211 }
1212
1213
1214 int
svr4_sys_facl(struct lwp * l,const struct svr4_sys_facl_args * uap,register_t * retval)1215 svr4_sys_facl(struct lwp *l, const struct svr4_sys_facl_args *uap, register_t *retval)
1216 {
1217
1218 *retval = 0;
1219
1220 switch (SCARG(uap, cmd)) {
1221 case SVR4_SYS_SETACL:
1222 /* We don't support acls on any filesystem */
1223 return ENOSYS;
1224
1225 case SVR4_SYS_GETACL:
1226 #if 1
1227 return ENOSYS;
1228 #else
1229 /*
1230 * XXX This code is completly borked, no idea what it was
1231 * trying to do.
1232 */
1233 return copyout(retval, &SCARG(uap, num),
1234 sizeof(SCARG(uap, num)));
1235 #endif
1236
1237 case SVR4_SYS_GETACLCNT:
1238 return 0;
1239
1240 default:
1241 return EINVAL;
1242 }
1243 }
1244
1245
1246 int
svr4_sys_acl(struct lwp * l,const struct svr4_sys_acl_args * uap,register_t * retval)1247 svr4_sys_acl(struct lwp *l, const struct svr4_sys_acl_args *uap, register_t *retval)
1248 {
1249 return svr4_sys_facl(l, (const void *)uap, retval); /* XXX: for now the same */
1250 }
1251
1252
1253 int
svr4_sys_auditsys(struct lwp * l,const struct svr4_sys_auditsys_args * uap,register_t * retval)1254 svr4_sys_auditsys(struct lwp *l, const struct svr4_sys_auditsys_args *uap, register_t *retval)
1255 {
1256 /*
1257 * XXX: Big brother is *not* watching.
1258 */
1259 return 0;
1260 }
1261
1262
1263 int
svr4_sys_memcntl(struct lwp * l,const struct svr4_sys_memcntl_args * uap,register_t * retval)1264 svr4_sys_memcntl(struct lwp *l, const struct svr4_sys_memcntl_args *uap, register_t *retval)
1265 {
1266 switch (SCARG(uap, cmd)) {
1267 case SVR4_MC_SYNC:
1268 {
1269 struct sys___msync13_args msa;
1270
1271 SCARG(&msa, addr) = SCARG(uap, addr);
1272 SCARG(&msa, len) = SCARG(uap, len);
1273 SCARG(&msa, flags) = (int)(u_long)SCARG(uap, arg);
1274
1275 return sys___msync13(l, &msa, retval);
1276 }
1277 case SVR4_MC_ADVISE:
1278 {
1279 struct sys_madvise_args maa;
1280
1281 SCARG(&maa, addr) = SCARG(uap, addr);
1282 SCARG(&maa, len) = SCARG(uap, len);
1283 SCARG(&maa, behav) = (int)(u_long)SCARG(uap, arg);
1284
1285 return sys_madvise(l, &maa, retval);
1286 }
1287 case SVR4_MC_LOCK:
1288 case SVR4_MC_UNLOCK:
1289 case SVR4_MC_LOCKAS:
1290 case SVR4_MC_UNLOCKAS:
1291 return EOPNOTSUPP;
1292 default:
1293 return ENOSYS;
1294 }
1295 }
1296
1297
1298 int
svr4_sys_nice(struct lwp * l,const struct svr4_sys_nice_args * uap,register_t * retval)1299 svr4_sys_nice(struct lwp *l, const struct svr4_sys_nice_args *uap, register_t *retval)
1300 {
1301 struct sys_setpriority_args ap;
1302 int error;
1303
1304 SCARG(&ap, which) = PRIO_PROCESS;
1305 SCARG(&ap, who) = 0;
1306 SCARG(&ap, prio) = SCARG(uap, prio);
1307
1308 if ((error = sys_setpriority(l, &ap, retval)) != 0)
1309 return error;
1310
1311 if ((error = sys_getpriority(l, (const void *)&ap, retval)) != 0)
1312 return error;
1313
1314 return 0;
1315 }
1316
1317
1318 int
svr4_sys_resolvepath(struct lwp * l,const struct svr4_sys_resolvepath_args * uap,register_t * retval)1319 svr4_sys_resolvepath(struct lwp *l, const struct svr4_sys_resolvepath_args *uap, register_t *retval)
1320 {
1321 struct pathbuf *pb;
1322 struct nameidata nd;
1323 int error;
1324 size_t len;
1325
1326 error = pathbuf_copyin(SCARG(uap, path), &pb);
1327 if (error) {
1328 return ENOMEM;
1329 }
1330
1331 NDINIT(&nd, LOOKUP, NOFOLLOW | TRYEMULROOT, pb);
1332 if ((error = namei(&nd)) != 0) {
1333 pathbuf_destroy(pb);
1334 return error;
1335 }
1336
1337 if ((error = copyoutstr(nd.ni_pnbuf, SCARG(uap, buf),
1338 SCARG(uap, bufsiz), &len)) != 0)
1339 goto bad;
1340
1341 *retval = len;
1342 bad:
1343 vrele(nd.ni_vp);
1344 pathbuf_destroy(pb);
1345 return error;
1346 }
1347