1/* $NetBSD: ibcs2_misc.c,v 1.110 2010/03/03 08:20:39 he 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.110 2010/03/03 08:20:39 he 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 159int 160ibcs2_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 208int 209ibcs2_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 241int 242ibcs2_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 257int 258ibcs2_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 274int 275ibcs2_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 287int 288ibcs2_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 365int 366ibcs2_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_data; 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; 405again: 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 483eof: 484 *retval = SCARG(uap, nbytes) - resid; 485out: 486 VOP_UNLOCK(vp); 487 if (cookiebuf) 488 free(cookiebuf, M_TEMP); 489 free(tbuf, M_TEMP); 490out1: 491 fd_putfile(SCARG(uap, fd)); 492 return (error); 493} 494 495int 496ibcs2_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_data; 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; 543again: 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 */ 616eof: 617 *retval = SCARG(uap, nbytes) - resid; 618out: 619 VOP_UNLOCK(vp); 620 if (cookiebuf) 621 free(cookiebuf, M_TEMP); 622 free(tbuf, M_TEMP); 623out1: 624 fd_putfile(SCARG(uap, fd)); 625 return (error); 626} 627 628int 629ibcs2_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 648int 649ibcs2_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 690int 691ibcs2_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 724int 725ibcs2_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 736int 737ibcs2_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 748int 749xenix_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 766int 767ibcs2_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 784int 785ibcs2_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 799int 800ibcs2_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 814int 815ibcs2_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 882int 883ibcs2_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 910int 911ibcs2_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 925int 926ibcs2_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 940int 941ibcs2_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 969int 970ibcs2_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 985int 986ibcs2_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 1014int 1015ibcs2_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 1036int 1037ibcs2_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 1090int 1091ibcs2_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 */ 1120int 1121ibcs2_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 1186int 1187ibcs2_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 1208int 1209xenix_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 1230int 1231xenix_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 1245int 1246xenix_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, &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 1269int 1270ibcs2_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 1299int 1300ibcs2_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 1344int 1345ibcs2_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 1361int 1362ibcs2_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 1374int 1375ibcs2_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 1409int 1410xenix_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