1 /* $NetBSD: ibcs2_misc.c,v 1.113 2014/09/05 09:21:54 matt Exp $ */
2
3 /*
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This software was developed by the Computer Systems Engineering group
8 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
9 * contributed to Berkeley.
10 *
11 * All advertising materials mentioning features or use of this software
12 * must display the following acknowledgement:
13 * This product includes software developed by the University of
14 * California, Lawrence Berkeley Laboratory.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * SUCH DAMAGE.
39 *
40 * from: Header: sun_misc.c,v 1.16 93/04/07 02:46:27 torek Exp
41 *
42 * @(#)sun_misc.c 8.1 (Berkeley) 6/18/93
43 */
44
45 /*
46 * Copyright (c) 1994, 1995, 1998 Scott Bartram
47 *
48 * This software was developed by the Computer Systems Engineering group
49 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
50 * contributed to Berkeley.
51 *
52 * All advertising materials mentioning features or use of this software
53 * must display the following acknowledgement:
54 * This product includes software developed by the University of
55 * California, Lawrence Berkeley Laboratory.
56 *
57 * Redistribution and use in source and binary forms, with or without
58 * modification, are permitted provided that the following conditions
59 * are met:
60 * 1. Redistributions of source code must retain the above copyright
61 * notice, this list of conditions and the following disclaimer.
62 * 2. Redistributions in binary form must reproduce the above copyright
63 * notice, this list of conditions and the following disclaimer in the
64 * documentation and/or other materials provided with the distribution.
65 * 3. All advertising materials mentioning features or use of this software
66 * must display the following acknowledgement:
67 * This product includes software developed by the University of
68 * California, Berkeley and its contributors.
69 * 4. Neither the name of the University nor the names of its contributors
70 * may be used to endorse or promote products derived from this software
71 * without specific prior written permission.
72 *
73 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
74 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
75 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
76 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
77 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
78 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
79 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
80 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
81 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
82 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
83 * SUCH DAMAGE.
84 *
85 * from: Header: sun_misc.c,v 1.16 93/04/07 02:46:27 torek Exp
86 *
87 * @(#)sun_misc.c 8.1 (Berkeley) 6/18/93
88 */
89
90 /*
91 * IBCS2 compatibility module.
92 *
93 * IBCS2 system calls that are implemented differently in BSD are
94 * handled here.
95 */
96
97 #include <sys/cdefs.h>
98 __KERNEL_RCSID(0, "$NetBSD: ibcs2_misc.c,v 1.113 2014/09/05 09:21:54 matt Exp $");
99
100 #include <sys/param.h>
101 #include <sys/systm.h>
102 #include <sys/namei.h>
103 #include <sys/dirent.h>
104 #include <sys/proc.h>
105 #include <sys/file.h>
106 #include <sys/filedesc.h>
107 #include <sys/ioctl.h>
108 #include <sys/kernel.h>
109 #include <sys/malloc.h>
110 #include <sys/mbuf.h>
111 #include <sys/mman.h>
112 #include <sys/mount.h>
113 #include <sys/prot.h>
114 #include <sys/reboot.h>
115 #include <sys/resource.h>
116 #include <sys/resourcevar.h>
117 #include <sys/socket.h>
118 #include <sys/stat.h>
119 #include <sys/syslog.h>
120 #include <sys/time.h>
121 #include <sys/times.h>
122 #include <sys/vnode.h>
123 #include <sys/uio.h>
124 #include <sys/wait.h>
125 #include <sys/utsname.h>
126 #include <sys/unistd.h>
127 #include <sys/kauth.h>
128 #include <sys/vfs_syscalls.h>
129
130 #include <netinet/in.h>
131 #include <sys/syscallargs.h>
132
133 #include <miscfs/specfs/specdev.h>
134
135 #include <uvm/uvm_extern.h>
136 #include <sys/sysctl.h>
137
138 #if defined(__i386__)
139 #include <i386/include/reg.h>
140 #endif
141
142 #include <compat/ibcs2/ibcs2_types.h>
143 #include <compat/ibcs2/ibcs2_dirent.h>
144 #include <compat/ibcs2/ibcs2_fcntl.h>
145 #include <compat/ibcs2/ibcs2_mman.h>
146 #include <compat/ibcs2/ibcs2_time.h>
147 #include <compat/ibcs2/ibcs2_signal.h>
148 #include <compat/ibcs2/ibcs2_timeb.h>
149 #include <compat/ibcs2/ibcs2_unistd.h>
150 #include <compat/ibcs2/ibcs2_utsname.h>
151 #include <compat/ibcs2/ibcs2_util.h>
152 #include <compat/ibcs2/ibcs2_utime.h>
153 #include <compat/ibcs2/ibcs2_syscallargs.h>
154 #include <compat/ibcs2/ibcs2_sysi86.h>
155 #include <compat/ibcs2/ibcs2_exec.h>
156
157 #include <compat/sys/mount.h>
158
159 int
ibcs2_sys_ulimit(struct lwp * l,const struct ibcs2_sys_ulimit_args * uap,register_t * retval)160 ibcs2_sys_ulimit(struct lwp *l, const struct ibcs2_sys_ulimit_args *uap, register_t *retval)
161 {
162 /* {
163 syscallarg(int) cmd;
164 syscallarg(int) newlimit;
165 } */
166 struct proc *p = l->l_proc;
167 struct ibcs2_sys_sysconf_args sysconf_ua;
168 #ifdef notyet
169 int error;
170 struct rlimit rl;
171 struct sys_setrlimit_args sra;
172 #endif
173 #define IBCS2_GETFSIZE 1
174 #define IBCS2_SETFSIZE 2
175 #define IBCS2_GETPSIZE 3
176 #define IBCS2_GETDTABLESIZE 4
177
178 switch (SCARG(uap, cmd)) {
179 case IBCS2_GETFSIZE:
180 *retval = p->p_rlimit[RLIMIT_FSIZE].rlim_cur;
181 return 0;
182 case IBCS2_SETFSIZE: /* XXX - fix this */
183 #ifdef notyet
184 rl.rlim_cur = SCARG(uap, newlimit);
185 SCARG(&sra, which) = RLIMIT_FSIZE;
186 SCARG(&sra, rlp) = &rl;
187 error = setrlimit(p, &sra, retval);
188 if (!error)
189 *retval = p->p_rlimit[RLIMIT_FSIZE].rlim_cur;
190 else
191 DPRINTF(("failed "));
192 return error;
193 #else
194 *retval = SCARG(uap, newlimit);
195 return 0;
196 #endif
197 case IBCS2_GETPSIZE:
198 *retval = p->p_rlimit[RLIMIT_RSS].rlim_cur; /* XXX */
199 return 0;
200 case IBCS2_GETDTABLESIZE:
201 SCARG(&sysconf_ua, name) = IBCS2_SC_OPEN_MAX;
202 return ibcs2_sys_sysconf(l, &sysconf_ua, retval);
203 default:
204 return ENOSYS;
205 }
206 }
207
208 int
ibcs2_sys_waitsys(struct lwp * l,const struct ibcs2_sys_waitsys_args * uap,register_t * retval)209 ibcs2_sys_waitsys(struct lwp *l, const struct ibcs2_sys_waitsys_args *uap, register_t *retval)
210 {
211 #if defined(__i386__)
212 /* {
213 syscallarg(int) a1;
214 syscallarg(int) a2;
215 syscallarg(int) a3;
216 } */
217 #endif
218 int error, options, status, pid;
219
220 #if defined(__i386__)
221 #define WAITPID_EFLAGS 0x8c4 /* OF, SF, ZF, PF */
222 if ((l->l_md.md_regs->tf_eflags & WAITPID_EFLAGS) == WAITPID_EFLAGS) {
223 /* waitpid */
224 pid = SCARG(uap, a1);
225 options = SCARG(uap, a3);
226 } else {
227 #endif
228 /* wait */
229 pid = WAIT_ANY;
230 options = 0;
231 #if defined(__i386__)
232 }
233 #endif
234
235 error = do_sys_wait(&pid, &status, options, NULL);
236 retval[0] = pid;
237 retval[1] = status;
238 return error;
239 }
240
241 int
ibcs2_sys_execv(struct lwp * l,const struct ibcs2_sys_execv_args * uap,register_t * retval)242 ibcs2_sys_execv(struct lwp *l, const struct ibcs2_sys_execv_args *uap, register_t *retval)
243 {
244 /* {
245 syscallarg(const char *) path;
246 syscallarg(char **) argp;
247 } */
248 struct sys_execve_args ap;
249
250 SCARG(&ap, path) = SCARG(uap, path);
251 SCARG(&ap, argp) = SCARG(uap, argp);
252 SCARG(&ap, envp) = NULL;
253
254 return sys_execve(l, &ap, retval);
255 }
256
257 int
ibcs2_sys_execve(struct lwp * l,const struct ibcs2_sys_execve_args * uap,register_t * retval)258 ibcs2_sys_execve(struct lwp *l, const struct ibcs2_sys_execve_args *uap, register_t *retval)
259 {
260 /* {
261 syscallarg(const char *) path;
262 syscallarg(char **) argp;
263 syscallarg(char **) envp;
264 } */
265 struct sys_execve_args ap;
266
267 SCARG(&ap, path) = SCARG(uap, path);
268 SCARG(&ap, argp) = SCARG(uap, argp);
269 SCARG(&ap, envp) = SCARG(uap, envp);
270
271 return sys_execve(l, &ap, retval);
272 }
273
274 int
ibcs2_sys_umount(struct lwp * l,const struct ibcs2_sys_umount_args * uap,register_t * retval)275 ibcs2_sys_umount(struct lwp *l, const struct ibcs2_sys_umount_args *uap, register_t *retval)
276 {
277 /* {
278 syscallarg(char *) name;
279 } */
280 struct sys_unmount_args um;
281
282 SCARG(&um, path) = SCARG(uap, name);
283 SCARG(&um, flags) = 0;
284 return sys_unmount(l, &um, retval);
285 }
286
287 int
ibcs2_sys_mount(struct lwp * l,const struct ibcs2_sys_mount_args * uap,register_t * retval)288 ibcs2_sys_mount(struct lwp *l, const struct ibcs2_sys_mount_args *uap, register_t *retval)
289 {
290 #ifdef notyet
291 /* {
292 syscallarg(char *) special;
293 syscallarg(char *) dir;
294 syscallarg(int) flags;
295 syscallarg(int) fstype;
296 syscallarg(char *) data;
297 syscallarg(int) len;
298 } */
299 int oflags = SCARG(uap, flags), nflags, error;
300 char fsname[MFSNAMELEN];
301
302 if (oflags & (IBCS2_MS_NOSUB | IBCS2_MS_SYS5))
303 return EINVAL;
304 if ((oflags & IBCS2_MS_NEWTYPE) == 0)
305 return EINVAL;
306 nflags = 0;
307 if (oflags & IBCS2_MS_RDONLY)
308 nflags |= MNT_RDONLY;
309 if (oflags & IBCS2_MS_NOSUID)
310 nflags |= MNT_NOSUID;
311 if (oflags & IBCS2_MS_REMOUNT)
312 nflags |= MNT_UPDATE;
313 SCARG(uap, flags) = nflags;
314
315 if (error = copyinstr(SCARG(uap, type), fsname, sizeof fsname, NULL))
316 return error;
317
318 if (strncmp(fsname, "4.2", sizeof fsname) == 0) {
319 SCARG(uap, type) = (void *)STACK_ALLOC();
320 if (error = copyout("ffs", SCARG(uap, type), sizeof("ffs")))
321 return error;
322 } else if (strncmp(fsname, "nfs", sizeof fsname) == 0) {
323 struct ibcs2_nfs_args sna;
324 struct sockaddr_in sain;
325 struct nfs_args na;
326 struct sockaddr sa;
327
328 if (error = copyin(SCARG(uap, data), &sna, sizeof sna))
329 return error;
330 if (error = copyin(sna.addr, &sain, sizeof sain))
331 return error;
332 memcpy(&sa, &sain, sizeof sa);
333 sa.sa_len = sizeof(sain);
334 SCARG(uap, data) = STACK_ALLOC();
335 na.addr = (void *)((unsigned long)SCARG(uap, data) + sizeof na);
336 na.sotype = SOCK_DGRAM;
337 na.proto = IPPROTO_UDP;
338 na.fh = (nfsv2fh_t *)sna.fh;
339 na.flags = sna.flags;
340 na.wsize = sna.wsize;
341 na.rsize = sna.rsize;
342 na.timeo = sna.timeo;
343 na.retrans = sna.retrans;
344 na.hostname = sna.hostname;
345
346 if (error = copyout(&sa, na.addr, sizeof sa))
347 return error;
348 if (error = copyout(&na, SCARG(uap, data), sizeof na))
349 return error;
350 }
351 return sys_mount(p, uap, retval);
352 #else
353 return EINVAL;
354 #endif
355 }
356
357 /*
358 * Read iBCS2-style directory entries. We suck them into kernel space so
359 * that they can be massaged before being copied out to user code. Like
360 * SunOS, we squish out `empty' entries.
361 *
362 * This is quite ugly, but what do you expect from compatibility code?
363 */
364
365 int
ibcs2_sys_getdents(struct lwp * l,const struct ibcs2_sys_getdents_args * uap,register_t * retval)366 ibcs2_sys_getdents(struct lwp *l, const struct ibcs2_sys_getdents_args *uap, register_t *retval)
367 {
368 /* {
369 syscallarg(int) fd;
370 syscallarg(char *) buf;
371 syscallarg(int) nbytes;
372 } */
373 struct dirent *bdp;
374 struct vnode *vp;
375 char *inp, *tbuf; /* BSD-format */
376 int len, reclen; /* BSD-format */
377 char *outp; /* iBCS2-format */
378 int resid, ibcs2_reclen;/* iBCS2-format */
379 file_t *fp;
380 struct uio auio;
381 struct iovec aiov;
382 struct ibcs2_dirent idb;
383 off_t off; /* true file offset */
384 size_t buflen;
385 int error, eofflag;
386 off_t *cookiebuf = NULL, *cookie;
387 int ncookies;
388
389 /* fd_getvnode() will use the descriptor for us */
390 if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
391 return (error);
392 if ((fp->f_flag & FREAD) == 0) {
393 error = EBADF;
394 goto out1;
395 }
396 vp = fp->f_vnode;
397 if (vp->v_type != VDIR) {
398 error = EINVAL;
399 goto out1;
400 }
401 buflen = min(MAXBSIZE, (size_t)SCARG(uap, nbytes));
402 tbuf = malloc(buflen, M_TEMP, M_WAITOK);
403 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
404 off = fp->f_offset;
405 again:
406 aiov.iov_base = tbuf;
407 aiov.iov_len = buflen;
408 auio.uio_iov = &aiov;
409 auio.uio_iovcnt = 1;
410 auio.uio_rw = UIO_READ;
411 auio.uio_resid = buflen;
412 auio.uio_offset = off;
413 UIO_SETUP_SYSSPACE(&auio);
414 /*
415 * First we read into the malloc'ed buffer, then
416 * we massage it into user space, one record at a time.
417 */
418 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &cookiebuf,
419 &ncookies);
420 if (error)
421 goto out;
422 inp = tbuf;
423 outp = SCARG(uap, buf);
424 resid = SCARG(uap, nbytes);
425 if ((len = buflen - auio.uio_resid) == 0)
426 goto eof;
427 for (cookie = cookiebuf; len > 0; len -= reclen) {
428 bdp = (struct dirent *)inp;
429 reclen = bdp->d_reclen;
430 if (reclen & 3)
431 panic("ibcs2_getdents: bad reclen");
432 if (cookie && (*cookie >> 32) != 0) {
433 compat_offseterr(vp, "ibcs2_getdents");
434 error = EINVAL;
435 goto out;
436 }
437 if (bdp->d_fileno == 0) {
438 inp += reclen; /* it is a hole; squish it out */
439 if (cookie)
440 off = *cookie++;
441 else
442 off += reclen;
443 continue;
444 }
445 ibcs2_reclen = IBCS2_RECLEN(&idb, bdp->d_namlen);
446 if (reclen > len || resid < ibcs2_reclen) {
447 /* entry too big for buffer, so just stop */
448 outp++;
449 break;
450 }
451 if (cookie)
452 off = *cookie++; /* each entry points to the next */
453 else
454 off += reclen;
455 /*
456 * Massage in place to make a iBCS2-shaped dirent (otherwise
457 * we have to worry about touching user memory outside of
458 * the copyout() call).
459 */
460 idb.d_ino = (ibcs2_ino_t)bdp->d_fileno;
461 idb.d_off = (ibcs2_off_t)off;
462 idb.d_reclen = (u_short)ibcs2_reclen;
463 strlcpy(idb.d_name, bdp->d_name, sizeof(idb.d_name));
464 error = copyout(&idb, outp, ibcs2_reclen);
465 if (error)
466 goto out;
467 /* advance past this real entry */
468 inp += reclen;
469 /* advance output past iBCS2-shaped entry */
470 outp += ibcs2_reclen;
471 resid -= ibcs2_reclen;
472 }
473
474 /* if we squished out the whole block, try again */
475 if (outp == SCARG(uap, buf)) {
476 if (cookiebuf)
477 free(cookiebuf, M_TEMP);
478 cookiebuf = NULL;
479 goto again;
480 }
481 fp->f_offset = off; /* update the vnode offset */
482
483 eof:
484 *retval = SCARG(uap, nbytes) - resid;
485 out:
486 VOP_UNLOCK(vp);
487 if (cookiebuf)
488 free(cookiebuf, M_TEMP);
489 free(tbuf, M_TEMP);
490 out1:
491 fd_putfile(SCARG(uap, fd));
492 return (error);
493 }
494
495 int
ibcs2_sys_read(struct lwp * l,const struct ibcs2_sys_read_args * uap,register_t * retval)496 ibcs2_sys_read(struct lwp *l, const struct ibcs2_sys_read_args *uap, register_t *retval)
497 {
498 /* {
499 syscallarg(int) fd;
500 syscallarg(char *) buf;
501 syscallarg(u_int) nbytes;
502 } */
503 struct dirent *bdp;
504 struct vnode *vp;
505 char *inp, *tbuf; /* BSD-format */
506 int len, reclen; /* BSD-format */
507 char *outp; /* iBCS2-format */
508 int resid, ibcs2_reclen;/* iBCS2-format */
509 file_t *fp;
510 struct uio auio;
511 struct iovec aiov;
512 struct ibcs2_direct {
513 ibcs2_ino_t ino;
514 char name[14];
515 } idb;
516 size_t buflen;
517 int error, eofflag;
518 size_t size;
519 off_t *cookiebuf = NULL, *cookie;
520 off_t off; /* true file offset */
521 int ncookies;
522
523 /* fd_getvnode() will use the descriptor for us */
524 if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0) {
525 if (error == EINVAL)
526 return sys_read(l, (const void *)uap, retval);
527 else
528 return error;
529 }
530 if ((fp->f_flag & FREAD) == 0) {
531 error = EBADF;
532 goto out1;
533 }
534 vp = fp->f_vnode;
535 if (vp->v_type != VDIR) {
536 fd_putfile(SCARG(uap, fd));
537 return sys_read(l, (const void *)uap, retval);
538 }
539 buflen = min(MAXBSIZE, max(DEV_BSIZE, (size_t)SCARG(uap, nbytes)));
540 tbuf = malloc(buflen, M_TEMP, M_WAITOK);
541 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
542 off = fp->f_offset;
543 again:
544 aiov.iov_base = tbuf;
545 aiov.iov_len = buflen;
546 auio.uio_iov = &aiov;
547 auio.uio_iovcnt = 1;
548 auio.uio_rw = UIO_READ;
549 auio.uio_resid = buflen;
550 auio.uio_offset = off;
551 UIO_SETUP_SYSSPACE(&auio);
552 /*
553 * First we read into the malloc'ed buffer, then
554 * we massage it into user space, one record at a time.
555 */
556 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &cookiebuf,
557 &ncookies);
558 if (error)
559 goto out;
560 inp = tbuf;
561 outp = SCARG(uap, buf);
562 resid = SCARG(uap, nbytes);
563 if ((len = buflen - auio.uio_resid) == 0)
564 goto eof;
565 for (cookie = cookiebuf; len > 0 && resid > 0; len -= reclen) {
566 bdp = (struct dirent *)inp;
567 reclen = bdp->d_reclen;
568 if (reclen & 3)
569 panic("ibcs2_sys_read");
570 if (cookie)
571 off = *cookie++; /* each entry points to the next */
572 else
573 off += reclen;
574 if ((off >> 32) != 0) {
575 error = EINVAL;
576 goto out;
577 }
578 if (bdp->d_fileno == 0) {
579 inp += reclen; /* it is a hole; squish it out */
580 continue;
581 }
582 ibcs2_reclen = 16;
583 if (reclen > len || resid < ibcs2_reclen) {
584 /* entry too big for buffer, so just stop */
585 outp++;
586 break;
587 }
588 /*
589 * Massage in place to make a iBCS2-shaped dirent (otherwise
590 * we have to worry about touching user memory outside of
591 * the copyout() call).
592 *
593 * TODO: if length(filename) > 14, then break filename into
594 * multiple entries and set inode = 0xffff except last
595 */
596 idb.ino = (bdp->d_fileno > 0xfffe) ? 0xfffe : bdp->d_fileno;
597 (void)copystr(bdp->d_name, idb.name, 14, &size);
598 memset(idb.name + size, 0, 14 - size);
599 error = copyout(&idb, outp, ibcs2_reclen);
600 if (error)
601 goto out;
602 /* advance past this real entry */
603 inp += reclen;
604 /* advance output past iBCS2-shaped entry */
605 outp += ibcs2_reclen;
606 resid -= ibcs2_reclen;
607 }
608 /* if we squished out the whole block, try again */
609 if (outp == SCARG(uap, buf)) {
610 if (cookiebuf)
611 free(cookiebuf, M_TEMP);
612 cookiebuf = NULL;
613 goto again;
614 }
615 fp->f_offset = off; /* update the vnode offset */
616 eof:
617 *retval = SCARG(uap, nbytes) - resid;
618 out:
619 VOP_UNLOCK(vp);
620 if (cookiebuf)
621 free(cookiebuf, M_TEMP);
622 free(tbuf, M_TEMP);
623 out1:
624 fd_putfile(SCARG(uap, fd));
625 return (error);
626 }
627
628 int
ibcs2_sys_mknod(struct lwp * l,const struct ibcs2_sys_mknod_args * uap,register_t * retval)629 ibcs2_sys_mknod(struct lwp *l, const struct ibcs2_sys_mknod_args *uap, register_t *retval)
630 {
631 /* {
632 syscallarg(const char *) path;
633 syscallarg(int) mode;
634 syscallarg(int) dev;
635 } */
636
637 if (S_ISFIFO(SCARG(uap, mode))) {
638 struct sys_mkfifo_args ap;
639 SCARG(&ap, path) = SCARG(uap, path);
640 SCARG(&ap, mode) = SCARG(uap, mode);
641 return sys_mkfifo(l, &ap, retval);
642 } else {
643 return do_sys_mknod(l, SCARG(uap, path), SCARG(uap, mode),
644 SCARG(uap, dev), retval, UIO_USERSPACE);
645 }
646 }
647
648 int
ibcs2_sys_getgroups(struct lwp * l,const struct ibcs2_sys_getgroups_args * uap,register_t * retval)649 ibcs2_sys_getgroups(struct lwp *l, const struct ibcs2_sys_getgroups_args *uap, register_t *retval)
650 {
651 /* {
652 syscallarg(int) gidsetsize;
653 syscallarg(ibcs2_gid_t *) gidset;
654 } */
655 ibcs2_gid_t iset[16];
656 ibcs2_gid_t *gidset;
657 unsigned int ngrps;
658 int i, n, j;
659 int error;
660
661 ngrps = kauth_cred_ngroups(l->l_cred);
662 *retval = ngrps;
663 if (SCARG(uap, gidsetsize) == 0)
664 return 0;
665 if (SCARG(uap, gidsetsize) < ngrps)
666 return EINVAL;
667
668 gidset = SCARG(uap, gidset);
669 for (i = 0; i < (n = ngrps); i += n, gidset += n) {
670 n -= i;
671 if (n > __arraycount(iset))
672 n = __arraycount(iset);
673 for (j = 0; j < n; j++)
674 iset[j] = kauth_cred_group(l->l_cred, i + j);
675 error = copyout(iset, gidset, n * sizeof(iset[0]));
676 if (error != 0)
677 return error;
678 }
679
680 return 0;
681 }
682
683 /*
684 * It is very unlikly that any problem using 16bit groups is written
685 * to allow for more than 16 of them, so don't bother trying to
686 * support that.
687 */
688 #define COMPAT_NGROUPS16 16
689
690 int
ibcs2_sys_setgroups(struct lwp * l,const struct ibcs2_sys_setgroups_args * uap,register_t * retval)691 ibcs2_sys_setgroups(struct lwp *l, const struct ibcs2_sys_setgroups_args *uap, register_t *retval)
692 {
693 /* {
694 syscallarg(int) gidsetsize;
695 syscallarg(ibcs2_gid_t *) gidset;
696 } */
697
698 ibcs2_gid_t iset[COMPAT_NGROUPS16];
699 kauth_cred_t ncred;
700 int error;
701 gid_t grbuf[COMPAT_NGROUPS16];
702 unsigned int i, ngroups = SCARG(uap, gidsetsize);
703
704 if (ngroups > COMPAT_NGROUPS16)
705 return EINVAL;
706 error = copyin(SCARG(uap, gidset), iset, ngroups);
707 if (error != 0)
708 return error;
709
710 for (i = 0; i < ngroups; i++)
711 grbuf[i] = iset[i];
712
713 ncred = kauth_cred_alloc();
714 error = kauth_cred_setgroups(ncred, grbuf, SCARG(uap, gidsetsize),
715 -1, UIO_SYSSPACE);
716 if (error != 0) {
717 kauth_cred_free(ncred);
718 return error;
719 }
720
721 return kauth_proc_setgroups(l, ncred);
722 }
723
724 int
ibcs2_sys_setuid(struct lwp * l,const struct ibcs2_sys_setuid_args * uap,register_t * retval)725 ibcs2_sys_setuid(struct lwp *l, const struct ibcs2_sys_setuid_args *uap, register_t *retval)
726 {
727 /* {
728 syscallarg(int) uid;
729 } */
730 struct sys_setuid_args sa;
731
732 SCARG(&sa, uid) = (uid_t)SCARG(uap, uid);
733 return sys_setuid(l, &sa, retval);
734 }
735
736 int
ibcs2_sys_setgid(struct lwp * l,const struct ibcs2_sys_setgid_args * uap,register_t * retval)737 ibcs2_sys_setgid(struct lwp *l, const struct ibcs2_sys_setgid_args *uap, register_t *retval)
738 {
739 /* {
740 syscallarg(int) gid;
741 } */
742 struct sys_setgid_args sa;
743
744 SCARG(&sa, gid) = (gid_t)SCARG(uap, gid);
745 return sys_setgid(l, &sa, retval);
746 }
747
748 int
xenix_sys_ftime(struct lwp * l,const struct xenix_sys_ftime_args * uap,register_t * retval)749 xenix_sys_ftime(struct lwp *l, const struct xenix_sys_ftime_args *uap, register_t *retval)
750 {
751 /* {
752 syscallarg(struct xenix_timeb *) tp;
753 } */
754 struct timeval tv;
755 struct xenix_timeb itb;
756
757 microtime(&tv);
758 itb.time = tv.tv_sec;
759 itb.millitm = (tv.tv_usec / 1000);
760 /* NetBSD has no kernel notion of timezone -- fake it. */
761 itb.timezone = 0;
762 itb.dstflag = 0;
763 return copyout(&itb, SCARG(uap, tp), xenix_timeb_len);
764 }
765
766 int
ibcs2_sys_time(struct lwp * l,const struct ibcs2_sys_time_args * uap,register_t * retval)767 ibcs2_sys_time(struct lwp *l, const struct ibcs2_sys_time_args *uap, register_t *retval)
768 {
769 /* {
770 syscallarg(ibcs2_time_t *) tp;
771 } */
772 struct proc *p = l->l_proc;
773 struct timeval tv;
774
775 microtime(&tv);
776 *retval = tv.tv_sec;
777 if (p->p_emuldata == IBCS2_EXEC_XENIX && SCARG(uap, tp))
778 return copyout(&tv.tv_sec, SCARG(uap, tp),
779 sizeof(ibcs2_time_t));
780 else
781 return 0;
782 }
783
784 int
ibcs2_sys_pathconf(struct lwp * l,const struct ibcs2_sys_pathconf_args * uap,register_t * retval)785 ibcs2_sys_pathconf(struct lwp *l, const struct ibcs2_sys_pathconf_args *uap, register_t *retval)
786 {
787 /* {
788 syscallarg(char *) path;
789 syscallarg(int) name;
790 } */
791 struct sys_pathconf_args bsd_ua;
792
793 SCARG(&bsd_ua, path) = SCARG(uap, path);
794 /* iBCS2 _PC_* defines are offset by one */
795 SCARG(&bsd_ua, name) = SCARG(uap, name) + 1;
796 return sys_pathconf(l, &bsd_ua, retval);
797 }
798
799 int
ibcs2_sys_fpathconf(struct lwp * l,const struct ibcs2_sys_fpathconf_args * uap,register_t * retval)800 ibcs2_sys_fpathconf(struct lwp *l, const struct ibcs2_sys_fpathconf_args *uap, register_t *retval)
801 {
802 /* {
803 syscallarg(int) fd;
804 syscallarg(int) name;
805 } */
806 struct sys_fpathconf_args bsd_ua;
807
808 SCARG(&bsd_ua, fd) = SCARG(uap, fd);
809 /* iBCS2 _PC_* defines are offset by one */
810 SCARG(&bsd_ua, name) = SCARG(uap, name) + 1;
811 return sys_fpathconf(l, &bsd_ua, retval);
812 }
813
814 int
ibcs2_sys_sysconf(struct lwp * l,const struct ibcs2_sys_sysconf_args * uap,register_t * retval)815 ibcs2_sys_sysconf(struct lwp *l, const struct ibcs2_sys_sysconf_args *uap, register_t *retval)
816 {
817 /* {
818 syscallarg(int) name;
819 } */
820 struct proc *p = l->l_proc;
821 int mib[2], value, error;
822 size_t len;
823
824 switch(SCARG(uap, name)) {
825 case IBCS2_SC_ARG_MAX:
826 mib[1] = KERN_ARGMAX;
827 break;
828
829 case IBCS2_SC_CHILD_MAX:
830 *retval = p->p_rlimit[RLIMIT_NPROC].rlim_cur;
831 return 0;
832
833 case IBCS2_SC_CLK_TCK:
834 *retval = hz;
835 return 0;
836
837 case IBCS2_SC_NGROUPS_MAX:
838 mib[1] = KERN_NGROUPS;
839 break;
840
841 case IBCS2_SC_OPEN_MAX:
842 *retval = p->p_rlimit[RLIMIT_NPROC].rlim_cur;
843 return 0;
844
845 case IBCS2_SC_JOB_CONTROL:
846 mib[1] = KERN_JOB_CONTROL;
847 break;
848
849 case IBCS2_SC_SAVED_IDS:
850 mib[1] = KERN_SAVED_IDS;
851 break;
852
853 case IBCS2_SC_VERSION:
854 mib[1] = KERN_POSIX1;
855 break;
856
857 case IBCS2_SC_PASS_MAX:
858 *retval = 128; /* XXX - should we create PASS_MAX ? */
859 return 0;
860
861 case IBCS2_SC_XOPEN_VERSION:
862 *retval = 2; /* XXX: What should that be? */
863 return 0;
864
865 default:
866 return EINVAL;
867 }
868
869 mib[0] = CTL_KERN;
870 len = sizeof(value);
871 /*
872 * calling into sysctl with superuser privs, but we don't mind,
873 * 'cause we're only querying a value.
874 */
875 error = old_sysctl(&mib[0], 2, &value, &len, NULL, 0, NULL);
876 if (error)
877 return (error);
878 *retval = value;
879 return 0;
880 }
881
882 int
ibcs2_sys_alarm(struct lwp * l,const struct ibcs2_sys_alarm_args * uap,register_t * retval)883 ibcs2_sys_alarm(struct lwp *l, const struct ibcs2_sys_alarm_args *uap, register_t *retval)
884 {
885 /* {
886 syscallarg(unsigned) sec;
887 } */
888 struct proc *p = l->l_proc;
889 struct itimerval it, oit;
890 int error;
891
892 error = dogetitimer(p, ITIMER_REAL, &oit);
893 if (error != 0)
894 return error;
895
896 timerclear(&it.it_interval);
897 it.it_value.tv_sec = SCARG(uap, sec);
898 it.it_value.tv_usec = 0;
899
900 error = dosetitimer(p, ITIMER_REAL, &it);
901 if (error)
902 return error;
903
904 if (oit.it_value.tv_usec)
905 oit.it_value.tv_sec++;
906 *retval = oit.it_value.tv_sec;
907 return 0;
908 }
909
910 int
ibcs2_sys_getmsg(struct lwp * l,const struct ibcs2_sys_getmsg_args * uap,register_t * retval)911 ibcs2_sys_getmsg(struct lwp *l, const struct ibcs2_sys_getmsg_args *uap, register_t *retval)
912 {
913 #ifdef notyet
914 /* {
915 syscallarg(int) fd;
916 syscallarg(struct ibcs2_stropts *) ctl;
917 syscallarg(struct ibcs2_stropts *) dat;
918 syscallarg(int *) flags;
919 } */
920 #endif
921
922 return 0;
923 }
924
925 int
ibcs2_sys_putmsg(struct lwp * l,const struct ibcs2_sys_putmsg_args * uap,register_t * retval)926 ibcs2_sys_putmsg(struct lwp *l, const struct ibcs2_sys_putmsg_args *uap, register_t *retval)
927 {
928 #ifdef notyet
929 /* {
930 syscallarg(int) fd;
931 syscallarg(struct ibcs2_stropts *) ctl;
932 syscallarg(struct ibcs2_stropts *) dat;
933 syscallarg(int) flags;
934 } */
935 #endif
936
937 return 0;
938 }
939
940 int
ibcs2_sys_times(struct lwp * l,const struct ibcs2_sys_times_args * uap,register_t * retval)941 ibcs2_sys_times(struct lwp *l, const struct ibcs2_sys_times_args *uap, register_t *retval)
942 {
943 /* {
944 syscallarg(struct tms *) tp;
945 } */
946 struct tms tms;
947 struct timeval t;
948 struct rusage ru, *rup;
949 #define CONVTCK(r) (r.tv_sec * hz + r.tv_usec / (1000000 / hz))
950
951 ru = l->l_proc->p_stats->p_ru;
952 mutex_enter(l->l_proc->p_lock);
953 calcru(l->l_proc, &ru.ru_utime, &ru.ru_stime, NULL, NULL);
954 rulwps(l->l_proc, &ru);
955 mutex_exit(l->l_proc->p_lock);
956 tms.tms_utime = CONVTCK(ru.ru_utime);
957 tms.tms_stime = CONVTCK(ru.ru_stime);
958
959 rup = &l->l_proc->p_stats->p_cru;
960 tms.tms_cutime = CONVTCK(rup->ru_utime);
961 tms.tms_cstime = CONVTCK(rup->ru_stime);
962
963 microtime(&t);
964 *retval = CONVTCK(t);
965
966 return copyout(&tms, SCARG(uap, tp), sizeof(tms));
967 }
968
969 int
ibcs2_sys_stime(struct lwp * l,const struct ibcs2_sys_stime_args * uap,register_t * retval)970 ibcs2_sys_stime(struct lwp *l, const struct ibcs2_sys_stime_args *uap, register_t *retval)
971 {
972 /* {
973 syscallarg(long *) timep;
974 } */
975 struct timeval tv;
976 int error;
977
978 error = copyin(SCARG(uap, timep), &tv.tv_sec, sizeof(long));
979 if (error)
980 return error;
981 tv.tv_usec = 0;
982 return settimeofday1(&tv, false, NULL, l, true);
983 }
984
985 int
ibcs2_sys_utime(struct lwp * l,const struct ibcs2_sys_utime_args * uap,register_t * retval)986 ibcs2_sys_utime(struct lwp *l, const struct ibcs2_sys_utime_args *uap, register_t *retval)
987 {
988 /* {
989 syscallarg(const char *) path;
990 syscallarg(struct ibcs2_utimbuf *) buf;
991 } */
992 int error;
993 struct timeval *tptr;
994 struct timeval tp[2];
995
996 if (SCARG(uap, buf)) {
997 struct ibcs2_utimbuf ubuf;
998
999 error = copyin(SCARG(uap, buf), &ubuf, sizeof(ubuf));
1000 if (error)
1001 return error;
1002 tp[0].tv_sec = ubuf.actime;
1003 tp[0].tv_usec = 0;
1004 tp[1].tv_sec = ubuf.modtime;
1005 tp[1].tv_usec = 0;
1006 tptr = tp;
1007 } else
1008 tptr = NULL;
1009
1010 return do_sys_utimes(l, NULL, SCARG(uap, path), FOLLOW,
1011 tptr, UIO_SYSSPACE);
1012 }
1013
1014 int
ibcs2_sys_nice(struct lwp * l,const struct ibcs2_sys_nice_args * uap,register_t * retval)1015 ibcs2_sys_nice(struct lwp *l, const struct ibcs2_sys_nice_args *uap, register_t *retval)
1016 {
1017 /* {
1018 syscallarg(int) incr;
1019 } */
1020 struct proc *p = l->l_proc;
1021 struct sys_setpriority_args sa;
1022
1023 SCARG(&sa, which) = PRIO_PROCESS;
1024 SCARG(&sa, who) = 0;
1025 SCARG(&sa, prio) = p->p_nice - NZERO + SCARG(uap, incr);
1026 if (sys_setpriority(l, &sa, retval) != 0)
1027 return EPERM;
1028 *retval = p->p_nice - NZERO;
1029 return 0;
1030 }
1031
1032 /*
1033 * iBCS2 getpgrp, setpgrp, setsid, and setpgid
1034 */
1035
1036 int
ibcs2_sys_pgrpsys(struct lwp * l,const struct ibcs2_sys_pgrpsys_args * uap,register_t * retval)1037 ibcs2_sys_pgrpsys(struct lwp *l, const struct ibcs2_sys_pgrpsys_args *uap, register_t *retval)
1038 {
1039 /* {
1040 syscallarg(int) type;
1041 syscallarg(void *) dummy;
1042 syscallarg(int) pid;
1043 syscallarg(int) pgid;
1044 } */
1045 struct proc *p = l->l_proc;
1046
1047 switch (SCARG(uap, type)) {
1048 case 0: /* getpgrp */
1049 mutex_enter(proc_lock);
1050 *retval = p->p_pgrp->pg_id;
1051 mutex_exit(proc_lock);
1052 return 0;
1053
1054 case 1: /* setpgrp */
1055 {
1056 struct sys_setpgid_args sa;
1057
1058 SCARG(&sa, pid) = 0;
1059 SCARG(&sa, pgid) = 0;
1060 sys_setpgid(l, &sa, retval);
1061 mutex_enter(proc_lock);
1062 *retval = p->p_pgrp->pg_id;
1063 mutex_exit(proc_lock);
1064 return 0;
1065 }
1066
1067 case 2: /* setpgid */
1068 {
1069 struct sys_setpgid_args sa;
1070
1071 SCARG(&sa, pid) = SCARG(uap, pid);
1072 SCARG(&sa, pgid) = SCARG(uap, pgid);
1073 return sys_setpgid(l, &sa, retval);
1074 }
1075
1076 case 3: /* setsid */
1077 return sys_setsid(l, NULL, retval);
1078
1079 default:
1080 return EINVAL;
1081 }
1082 }
1083
1084 /*
1085 * See http://docsrv.sco.com:507/en/man/html.S/plock.S.html
1086 *
1087 * XXX - need to check for nested calls
1088 */
1089
1090 int
ibcs2_sys_plock(struct lwp * l,const struct ibcs2_sys_plock_args * uap,register_t * retval)1091 ibcs2_sys_plock(struct lwp *l, const struct ibcs2_sys_plock_args *uap, register_t *retval)
1092 {
1093 /* {
1094 syscallarg(int) cmd;
1095 } */
1096 #define IBCS2_UNLOCK 0
1097 #define IBCS2_PROCLOCK 1
1098 #define IBCS2_TEXTLOCK 2
1099 #define IBCS2_DATALOCK 4
1100
1101 /*
1102 * NOTE: This is a privileged operation. Normally it would require root
1103 * access. When implementing, please make sure to use an appropriate
1104 * kauth(9) request. See the man-page for more information.
1105 */
1106
1107 switch(SCARG(uap, cmd)) {
1108 case IBCS2_UNLOCK:
1109 case IBCS2_PROCLOCK:
1110 case IBCS2_TEXTLOCK:
1111 case IBCS2_DATALOCK:
1112 return 0; /* XXX - TODO */
1113 }
1114 return EINVAL;
1115 }
1116
1117 /*
1118 * See http://docsrv.sco.com:507/en/man/html.S/uadmin.S.html
1119 */
1120 int
ibcs2_sys_uadmin(struct lwp * l,const struct ibcs2_sys_uadmin_args * uap,register_t * retval)1121 ibcs2_sys_uadmin(struct lwp *l, const struct ibcs2_sys_uadmin_args *uap, register_t *retval)
1122 {
1123 /* {
1124 syscallarg(int) cmd;
1125 syscallarg(int) func;
1126 syscallarg(void *) data;
1127 } */
1128 int error;
1129
1130 #define SCO_A_REBOOT 1
1131 #define SCO_A_SHUTDOWN 2
1132 #define SCO_A_REMOUNT 4
1133 #define SCO_A_CLOCK 8
1134 #define SCO_A_SETCONFIG 128
1135 #define SCO_A_GETDEV 130
1136
1137 #define SCO_AD_HALT 0
1138 #define SCO_AD_BOOT 1
1139 #define SCO_AD_IBOOT 2
1140 #define SCO_AD_PWRDOWN 3
1141 #define SCO_AD_PWRNAP 4
1142
1143 #define SCO_AD_PANICBOOT 1
1144
1145 #define SCO_AD_GETBMAJ 0
1146 #define SCO_AD_GETCMAJ 1
1147
1148
1149 switch(SCARG(uap, cmd)) {
1150 case SCO_A_REBOOT:
1151 case SCO_A_SHUTDOWN:
1152 error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_REBOOT,
1153 0, NULL, NULL, NULL);
1154 if (error)
1155 return (error);
1156
1157 switch(SCARG(uap, func)) {
1158 case SCO_AD_HALT:
1159 case SCO_AD_PWRDOWN:
1160 case SCO_AD_PWRNAP:
1161 cpu_reboot(RB_HALT, NULL);
1162 case SCO_AD_BOOT:
1163 case SCO_AD_IBOOT:
1164 cpu_reboot(RB_AUTOBOOT, NULL);
1165 }
1166 return EINVAL;
1167 case SCO_A_REMOUNT:
1168 case SCO_A_CLOCK:
1169 case SCO_A_SETCONFIG:
1170 case SCO_A_GETDEV:
1171 /*
1172 * NOTE: These are all privileged operations, that otherwise
1173 * would require root access or similar. When implementing,
1174 * please use appropriate kauth(9) requests. See the man-page
1175 * for more information.
1176 */
1177
1178 if (SCARG(uap, cmd) != SCO_A_GETDEV)
1179 return 0;
1180 else
1181 return EINVAL; /* XXX - TODO */
1182 }
1183 return EINVAL;
1184 }
1185
1186 int
ibcs2_sys_sysfs(struct lwp * l,const struct ibcs2_sys_sysfs_args * uap,register_t * retval)1187 ibcs2_sys_sysfs(struct lwp *l, const struct ibcs2_sys_sysfs_args *uap, register_t *retval)
1188 {
1189 /* {
1190 syscallarg(int) cmd;
1191 syscallarg(void *) d1;
1192 syscallarg(char *) buf;
1193 } */
1194
1195 #define IBCS2_GETFSIND 1
1196 #define IBCS2_GETFSTYP 2
1197 #define IBCS2_GETNFSTYP 3
1198
1199 switch(SCARG(uap, cmd)) {
1200 case IBCS2_GETFSIND:
1201 case IBCS2_GETFSTYP:
1202 case IBCS2_GETNFSTYP:
1203 break;
1204 }
1205 return EINVAL; /* XXX - TODO */
1206 }
1207
1208 int
xenix_sys_rdchk(struct lwp * l,const struct xenix_sys_rdchk_args * uap,register_t * retval)1209 xenix_sys_rdchk(struct lwp *l, const struct xenix_sys_rdchk_args *uap, register_t *retval)
1210 {
1211 /* {
1212 syscallarg(int) fd;
1213 } */
1214 file_t *fp;
1215 int nbytes;
1216 int error;
1217
1218 if ((fp = fd_getfile(SCARG(uap, fd))) == NULL)
1219 return (EBADF);
1220 error = (*fp->f_ops->fo_ioctl)(fp, FIONREAD, &nbytes);
1221 fd_putfile(SCARG(uap, fd));
1222
1223 if (error != 0)
1224 return error;
1225
1226 *retval = nbytes ? 1 : 0;
1227 return 0;
1228 }
1229
1230 int
xenix_sys_chsize(struct lwp * l,const struct xenix_sys_chsize_args * uap,register_t * retval)1231 xenix_sys_chsize(struct lwp *l, const struct xenix_sys_chsize_args *uap, register_t *retval)
1232 {
1233 /* {
1234 syscallarg(int) fd;
1235 syscallarg(long) size;
1236 } */
1237 struct sys_ftruncate_args sa;
1238
1239 SCARG(&sa, fd) = SCARG(uap, fd);
1240 SCARG(&sa, PAD) = 0;
1241 SCARG(&sa, length) = SCARG(uap, size);
1242 return sys_ftruncate(l, &sa, retval);
1243 }
1244
1245 int
xenix_sys_nap(struct lwp * l,const struct xenix_sys_nap_args * uap,register_t * retval)1246 xenix_sys_nap(struct lwp *l, const struct xenix_sys_nap_args *uap, register_t *retval)
1247 {
1248 /* {
1249 syscallarg(long) millisec;
1250 } */
1251 int error;
1252 struct timespec rqt;
1253 struct timespec rmt;
1254
1255 rqt.tv_sec = 0;
1256 rqt.tv_nsec = SCARG(uap, millisec) * 1000;
1257 error = nanosleep1(l, CLOCK_MONOTONIC, 0, &rqt, &rmt);
1258 /* If interrupted we can either report EINTR, or the time left */
1259 if (error != 0 && error != EINTR)
1260 return error;
1261 *retval = rmt.tv_nsec / 1000;
1262 return 0;
1263 }
1264
1265 /*
1266 * mmap compat code borrowed from svr4/svr4_misc.c
1267 */
1268
1269 int
ibcs2_sys_mmap(struct lwp * l,const struct ibcs2_sys_mmap_args * uap,register_t * retval)1270 ibcs2_sys_mmap(struct lwp *l, const struct ibcs2_sys_mmap_args *uap, register_t *retval)
1271 {
1272 /* {
1273 syscallarg(ibcs2_void *) addr;
1274 syscallarg(ibcs2_size_t) len;
1275 syscallarg(int) prot;
1276 syscallarg(int) flags;
1277 syscallarg(int) fd;
1278 syscallarg(ibcs2_off_t) off;
1279 } */
1280 struct sys_mmap_args mm;
1281
1282 #define _MAP_NEW 0x80000000 /* XXX why? */
1283
1284 if (SCARG(uap, prot) & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
1285 return EINVAL;
1286 if (SCARG(uap, len) == 0)
1287 return EINVAL;
1288
1289 SCARG(&mm, prot) = SCARG(uap, prot);
1290 SCARG(&mm, len) = SCARG(uap, len);
1291 SCARG(&mm, flags) = SCARG(uap, flags) & ~_MAP_NEW;
1292 SCARG(&mm, fd) = SCARG(uap, fd);
1293 SCARG(&mm, addr) = SCARG(uap, addr);
1294 SCARG(&mm, pos) = SCARG(uap, off);
1295
1296 return sys_mmap(l, &mm, retval);
1297 }
1298
1299 int
ibcs2_sys_memcntl(struct lwp * l,const struct ibcs2_sys_memcntl_args * uap,register_t * retval)1300 ibcs2_sys_memcntl(struct lwp *l, const struct ibcs2_sys_memcntl_args *uap, register_t *retval)
1301 {
1302 /* {
1303 syscallarg(ibcs2_void *) addr;
1304 syscallarg(ibcs2_size_t) len;
1305 syscallarg(int) cmd;
1306 syscallarg(ibcs2_void *) arg;
1307 syscallarg(int) attr;
1308 syscallarg(int) mask;
1309 } */
1310
1311 switch (SCARG(uap, cmd)) {
1312 case IBCS2_MC_SYNC:
1313 {
1314 struct sys___msync13_args msa;
1315
1316 SCARG(&msa, addr) = SCARG(uap, addr);
1317 SCARG(&msa, len) = SCARG(uap, len);
1318 SCARG(&msa, flags) = (int)SCARG(uap, arg);
1319
1320 return sys___msync13(l, &msa, retval);
1321 }
1322 #ifdef IBCS2_MC_ADVISE /* supported? */
1323 case IBCS2_MC_ADVISE:
1324 {
1325 struct sys_madvise_args maa;
1326
1327 SCARG(&maa, addr) = SCARG(uap, addr);
1328 SCARG(&maa, len) = SCARG(uap, len);
1329 SCARG(&maa, behav) = (int)SCARG(uap, arg);
1330
1331 return sys_madvise(l, &maa, retval);
1332 }
1333 #endif
1334 case IBCS2_MC_LOCK:
1335 case IBCS2_MC_UNLOCK:
1336 case IBCS2_MC_LOCKAS:
1337 case IBCS2_MC_UNLOCKAS:
1338 return EOPNOTSUPP;
1339 default:
1340 return ENOSYS;
1341 }
1342 }
1343
1344 int
ibcs2_sys_gettimeofday(struct lwp * l,const struct ibcs2_sys_gettimeofday_args * uap,register_t * retval)1345 ibcs2_sys_gettimeofday(struct lwp *l, const struct ibcs2_sys_gettimeofday_args *uap, register_t *retval)
1346 {
1347 /* {
1348 syscallarg(struct timeval *) tp;
1349 } */
1350
1351 if (SCARG(uap, tp)) {
1352 struct timeval atv;
1353
1354 microtime(&atv);
1355 return copyout(&atv, SCARG(uap, tp), sizeof (atv));
1356 }
1357
1358 return 0;
1359 }
1360
1361 int
ibcs2_sys_settimeofday(struct lwp * l,const struct ibcs2_sys_settimeofday_args * uap,register_t * retval)1362 ibcs2_sys_settimeofday(struct lwp *l, const struct ibcs2_sys_settimeofday_args *uap, register_t *retval)
1363 {
1364 /* {
1365 syscallarg(struct timeval *) tp;
1366 } */
1367 struct compat_50_sys_settimeofday_args ap;
1368
1369 SCARG(&ap, tv) = SCARG(uap, tp);
1370 SCARG(&ap, tzp) = NULL;
1371 return compat_50_sys_settimeofday(l, &ap, retval);
1372 }
1373
1374 int
ibcs2_sys_scoinfo(struct lwp * l,const struct ibcs2_sys_scoinfo_args * uap,register_t * retval)1375 ibcs2_sys_scoinfo(struct lwp *l, const struct ibcs2_sys_scoinfo_args *uap, register_t *retval)
1376 {
1377 /* {
1378 syscallarg(struct scoutsname *) bp;
1379 syscallarg(int) len;
1380 } */
1381 struct scoutsname uts;
1382
1383 (void)memset(&uts, 0, sizeof(uts));
1384 (void)strncpy(uts.sysname, ostype, 8);
1385 (void)strncpy(uts.nodename, hostname, 8);
1386 (void)strncpy(uts.release, osrelease, 15);
1387 (void)strncpy(uts.kid, "kernel id 1", 19);
1388 (void)strncpy(uts.machine, machine, 8);
1389 (void)strncpy(uts.bustype, "pci", 8);
1390 (void)strncpy(uts.serial, "1234", 9);
1391 uts.origin = 0;
1392 uts.oem = 0;
1393 (void)strncpy(uts.nusers, "unlim", 8);
1394 uts.ncpu = 1;
1395
1396 return copyout(&uts, SCARG(uap, bp), sizeof(uts));
1397 }
1398
1399 #define X_LK_UNLCK 0
1400 #define X_LK_LOCK 1
1401 #define X_LK_NBLCK 20
1402 #define X_LK_RLCK 3
1403 #define X_LK_NBRLCK 4
1404 #define X_LK_GETLK 5
1405 #define X_LK_SETLK 6
1406 #define X_LK_SETLKW 7
1407 #define X_LK_TESTLK 8
1408
1409 int
xenix_sys_locking(struct lwp * l,const struct xenix_sys_locking_args * uap,register_t * retval)1410 xenix_sys_locking(struct lwp *l, const struct xenix_sys_locking_args *uap, register_t *retval)
1411 {
1412 /* {
1413 syscallarg(int) fd;
1414 syscallarg(int) blk;
1415 syscallarg(int) size;
1416 } */
1417 struct flock fl;
1418 int cmd;
1419
1420 switch SCARG(uap, blk) {
1421 case X_LK_GETLK:
1422 case X_LK_SETLK:
1423 case X_LK_SETLKW:
1424 return ibcs2_sys_fcntl(l, (const void *)uap, retval);
1425 }
1426
1427 switch SCARG(uap, blk) {
1428 case X_LK_UNLCK:
1429 cmd = F_SETLK;
1430 fl.l_type = F_UNLCK;
1431 break;
1432 case X_LK_LOCK:
1433 cmd = F_SETLKW;
1434 fl.l_type = F_WRLCK;
1435 break;
1436 case X_LK_RLCK:
1437 cmd = F_SETLKW;
1438 fl.l_type = F_RDLCK;
1439 break;
1440 case X_LK_NBRLCK:
1441 cmd = F_SETLK;
1442 fl.l_type = F_RDLCK;
1443 break;
1444 case X_LK_NBLCK:
1445 cmd = F_SETLK;
1446 fl.l_type = F_WRLCK;
1447 break;
1448 default:
1449 return EINVAL;
1450 }
1451 fl.l_len = SCARG(uap, size);
1452 fl.l_start = 0;
1453 fl.l_whence = SEEK_CUR;
1454
1455 return do_fcntl_lock(SCARG(uap, fd), cmd, &fl);
1456 }
1457