1 /* $NetBSD: netbsd32_compat_43.c,v 1.53 2010/04/23 23:05:40 joerg Exp $ */ 2 3 /* 4 * Copyright (c) 1998, 2001 Matthew R. Green 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: netbsd32_compat_43.c,v 1.53 2010/04/23 23:05:40 joerg Exp $"); 31 32 #if defined(_KERNEL_OPT) 33 #include "opt_compat_43.h" 34 #endif 35 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/fcntl.h> 39 #include <sys/filedesc.h> 40 #include <sys/mbuf.h> 41 #include <sys/mount.h> 42 #include <sys/namei.h> 43 #include <sys/socket.h> 44 #include <sys/proc.h> 45 #include <sys/socket.h> 46 #include <sys/socketvar.h> 47 #include <sys/stat.h> 48 #include <sys/syscallargs.h> 49 #include <sys/time.h> 50 #include <sys/ucred.h> 51 #include <sys/vfs_syscalls.h> 52 #include <uvm/uvm_extern.h> 53 #include <sys/sysctl.h> 54 #include <sys/swap.h> 55 56 #include <compat/netbsd32/netbsd32.h> 57 #include <compat/netbsd32/netbsd32_syscallargs.h> 58 59 #include <compat/sys/stat.h> 60 #include <compat/sys/signal.h> 61 #include <compat/sys/signalvar.h> 62 #include <compat/sys/socket.h> 63 64 #define SYS_DEF(foo) struct foo##_args; \ 65 int foo(struct lwp *, const struct foo##_args *, register_t *) 66 67 SYS_DEF(compat_43_netbsd32_sethostid); 68 SYS_DEF(compat_43_netbsd32_killpg); 69 SYS_DEF(compat_43_netbsd32_sigblock); 70 SYS_DEF(compat_43_netbsd32_sigblock); 71 SYS_DEF(compat_43_netbsd32_sigsetmask); 72 #undef SYS_DEF 73 74 static void 75 netbsd32_from_stat(const struct stat *sb, struct netbsd32_stat43 *sp32) 76 { 77 78 sp32->st_dev = sb->st_dev; 79 sp32->st_ino = sb->st_ino; 80 sp32->st_mode = sb->st_mode; 81 sp32->st_nlink = sb->st_nlink; 82 sp32->st_uid = sb->st_uid; 83 sp32->st_gid = sb->st_gid; 84 sp32->st_rdev = sb->st_rdev; 85 sp32->st_size = sb->st_size < (quad_t)1 << 32 ? sb->st_size : -2; 86 sp32->st_atimespec.tv_sec = sb->st_atimespec.tv_sec; 87 sp32->st_atimespec.tv_nsec = sb->st_atimespec.tv_nsec; 88 sp32->st_mtimespec.tv_sec = sb->st_mtimespec.tv_sec; 89 sp32->st_mtimespec.tv_nsec = sb->st_mtimespec.tv_nsec; 90 sp32->st_ctimespec.tv_sec = sb->st_ctimespec.tv_sec; 91 sp32->st_ctimespec.tv_nsec = sb->st_ctimespec.tv_nsec; 92 sp32->st_blksize = sb->st_blksize; 93 sp32->st_blocks = sb->st_blocks; 94 sp32->st_flags = sb->st_flags; 95 sp32->st_gen = sb->st_gen; 96 } 97 98 /* file system syscalls */ 99 int 100 compat_43_netbsd32_ocreat(struct lwp *l, const struct compat_43_netbsd32_ocreat_args *uap, register_t *retval) 101 { 102 /* { 103 syscallarg(const netbsd32_charp) path; 104 syscallarg(mode_t) mode; 105 } */ 106 struct sys_open_args ua; 107 108 NETBSD32TOP_UAP(path, const char); 109 NETBSD32TO64_UAP(mode); 110 SCARG(&ua, flags) = O_WRONLY | O_CREAT | O_TRUNC; 111 112 return (sys_open(l, &ua, retval)); 113 } 114 115 int 116 compat_43_netbsd32_olseek(struct lwp *l, const struct compat_43_netbsd32_olseek_args *uap, register_t *retval) 117 { 118 /* { 119 syscallarg(int) fd; 120 syscallarg(netbsd32_long) offset; 121 syscallarg(int) whence; 122 } */ 123 struct sys_lseek_args ua; 124 125 SCARG(&ua, fd) = SCARG(uap, fd); 126 NETBSD32TOX_UAP(offset, long); 127 NETBSD32TO64_UAP(whence); 128 /* Maybe offsets > 2^32 should generate an error ? */ 129 return sys_lseek(l, &ua, retval); 130 } 131 132 int 133 compat_43_netbsd32_stat43(struct lwp *l, const struct compat_43_netbsd32_stat43_args *uap, register_t *retval) 134 { 135 /* { 136 syscallarg(const netbsd32_charp) path; 137 syscallarg(netbsd32_stat43p_t) ub; 138 } */ 139 struct stat sb; 140 struct netbsd32_stat43 sb32; 141 int error; 142 143 error = do_sys_stat(SCARG_P32(uap, path), FOLLOW, &sb); 144 if (error == 0) { 145 netbsd32_from_stat(&sb, &sb32); 146 error = copyout(&sb32, SCARG_P32(uap, ub), sizeof(sb32)); 147 } 148 return error; 149 } 150 151 int 152 compat_43_netbsd32_lstat43(struct lwp *l, const struct compat_43_netbsd32_lstat43_args *uap, register_t *retval) 153 { 154 /* { 155 syscallarg(const netbsd32_charp) path; 156 syscallarg(netbsd32_stat43p_t) ub; 157 } */ 158 struct stat sb; 159 struct netbsd32_stat43 sb32; 160 int error; 161 162 error = do_sys_stat(SCARG_P32(uap, path), NOFOLLOW, &sb); 163 if (error == 0) { 164 netbsd32_from_stat(&sb, &sb32); 165 error = copyout(&sb32, SCARG_P32(uap, ub), sizeof(sb32)); 166 } 167 return error; 168 } 169 170 int 171 compat_43_netbsd32_fstat43(struct lwp *l, const struct compat_43_netbsd32_fstat43_args *uap, register_t *retval) 172 { 173 /* { 174 syscallarg(int) fd; 175 syscallarg(netbsd32_stat43p_t) sb; 176 } */ 177 struct stat sb; 178 struct netbsd32_stat43 sb32; 179 int error; 180 181 error = do_sys_fstat(SCARG(uap, fd), &sb); 182 if (error == 0) { 183 netbsd32_from_stat(&sb, &sb32); 184 error = copyout(&sb32, SCARG_P32(uap, sb), sizeof(sb32)); 185 } 186 return error; 187 } 188 189 int 190 compat_43_netbsd32_otruncate(struct lwp *l, const struct compat_43_netbsd32_otruncate_args *uap, register_t *retval) 191 { 192 /* { 193 syscallarg(const netbsd32_charp) path; 194 syscallarg(netbsd32_long) length; 195 } */ 196 struct sys_truncate_args ua; 197 198 NETBSD32TOP_UAP(path, const char); 199 NETBSD32TO64_UAP(length); 200 return (sys_truncate(l, &ua, retval)); 201 } 202 203 int 204 compat_43_netbsd32_oftruncate(struct lwp *l, const struct compat_43_netbsd32_oftruncate_args *uap, register_t *retval) 205 { 206 /* { 207 syscallarg(int) fd; 208 syscallarg(netbsd32_long) length; 209 } */ 210 struct sys_ftruncate_args ua; 211 212 NETBSD32TO64_UAP(fd); 213 NETBSD32TO64_UAP(length); 214 return (sys_ftruncate(l, &ua, retval)); 215 } 216 217 int 218 compat_43_netbsd32_ogetdirentries(struct lwp *l, const struct compat_43_netbsd32_ogetdirentries_args *uap, register_t *retval) 219 { 220 /* { 221 syscallarg(int) fd; 222 syscallarg(netbsd32_charp) buf; 223 syscallarg(u_int) count; 224 syscallarg(netbsd32_longp) basep; 225 } */ 226 struct compat_43_sys_getdirentries_args ua; 227 228 NETBSD32TO64_UAP(fd); 229 NETBSD32TOP_UAP(buf, char); 230 NETBSD32TO64_UAP(count); 231 NETBSD32TOP_UAP(basep, long); 232 return (compat_43_sys_getdirentries(l, &ua, retval)); 233 } 234 235 /* kernel syscalls */ 236 int 237 compat_43_netbsd32_ogetkerninfo(struct lwp *l, const struct compat_43_netbsd32_ogetkerninfo_args *uap, register_t *retval) 238 { 239 /* { 240 syscallarg(int) op; 241 syscallarg(netbsd32_charp) where; 242 syscallarg(netbsd32_intp) size; 243 syscallarg(int) arg; 244 } */ 245 struct compat_43_sys_getkerninfo_args ua; 246 247 NETBSD32TO64_UAP(op); 248 NETBSD32TOP_UAP(where, char); 249 NETBSD32TOP_UAP(size, int); 250 NETBSD32TO64_UAP(arg); 251 return (compat_43_sys_getkerninfo(l, &ua, retval)); 252 } 253 254 int 255 compat_43_netbsd32_ogethostname(struct lwp *l, const struct compat_43_netbsd32_ogethostname_args *uap, register_t *retval) 256 { 257 /* { 258 syscallarg(netbsd32_charp) hostname; 259 syscallarg(u_int) len; 260 } */ 261 int name[2]; 262 size_t sz; 263 264 name[0] = CTL_KERN; 265 name[1] = KERN_HOSTNAME; 266 sz = SCARG(uap, len); 267 return (old_sysctl(&name[0], 2, 268 SCARG_P32(uap, hostname), &sz, 0, 0, l)); 269 } 270 271 int 272 compat_43_netbsd32_osethostname(struct lwp *l, const struct compat_43_netbsd32_osethostname_args *uap, register_t *retval) 273 { 274 /* { 275 syscallarg(netbsd32_charp) hostname; 276 syscallarg(u_int) len; 277 } */ 278 int name[2]; 279 280 name[0] = CTL_KERN; 281 name[1] = KERN_HOSTNAME; 282 return old_sysctl(&name[0], 2, 0, 0, (char *)SCARG_P32(uap, 283 hostname), SCARG(uap, len), l); 284 } 285 286 int 287 compat_43_netbsd32_sethostid(struct lwp *l, const struct compat_43_netbsd32_sethostid_args *uap, register_t *retval) 288 { 289 /* { 290 syscallarg(int32_t) hostid; 291 } */ 292 struct compat_43_sys_sethostid_args ua; 293 294 NETBSD32TO64_UAP(hostid); 295 return (compat_43_sys_sethostid(l, &ua, retval)); 296 } 297 298 int 299 compat_43_netbsd32_ogetrlimit(struct lwp *l, const struct compat_43_netbsd32_ogetrlimit_args *uap, register_t *retval) 300 { 301 /* { 302 syscallarg(int) which; 303 syscallarg(netbsd32_orlimitp_t) rlp; 304 } */ 305 struct compat_43_sys_getrlimit_args ua; 306 307 NETBSD32TO64_UAP(which); 308 NETBSD32TOP_UAP(rlp, struct orlimit); 309 return (compat_43_sys_getrlimit(l, &ua, retval)); 310 } 311 312 int 313 compat_43_netbsd32_osetrlimit(struct lwp *l, const struct compat_43_netbsd32_osetrlimit_args *uap, register_t *retval) 314 { 315 /* { 316 syscallarg(int) which; 317 syscallarg(netbsd32_orlimitp_t) rlp; 318 } */ 319 struct compat_43_sys_setrlimit_args ua; 320 321 NETBSD32TO64_UAP(which); 322 NETBSD32TOP_UAP(rlp, struct orlimit); 323 return (compat_43_sys_setrlimit(l, &ua, retval)); 324 } 325 326 int 327 compat_43_netbsd32_killpg(struct lwp *l, const struct compat_43_netbsd32_killpg_args *uap, register_t *retval) 328 { 329 /* { 330 syscallarg(int) pgid; 331 syscallarg(int) signum; 332 } */ 333 struct compat_43_sys_killpg_args ua; 334 335 NETBSD32TO64_UAP(pgid); 336 NETBSD32TO64_UAP(signum); 337 return (compat_43_sys_killpg(l, &ua, retval)); 338 } 339 340 /* virtual memory syscalls */ 341 int 342 compat_43_netbsd32_ommap(struct lwp *l, const struct compat_43_netbsd32_ommap_args *uap, register_t *retval) 343 { 344 /* { 345 syscallarg(netbsd32_voidp) addr; 346 syscallarg(netbsd32_size_t) len; 347 syscallarg(int) prot; 348 syscallarg(int) flags; 349 syscallarg(int) fd; 350 syscallarg(netbsd32_long) pos; 351 } */ 352 struct compat_43_sys_mmap_args ua; 353 354 NETBSD32TOP_UAP(addr, void *); 355 NETBSD32TOX_UAP(len, size_t); 356 NETBSD32TO64_UAP(prot); 357 NETBSD32TO64_UAP(flags); 358 NETBSD32TO64_UAP(fd); 359 NETBSD32TOX_UAP(pos, long); 360 return (compat_43_sys_mmap(l, &ua, retval)); 361 } 362 363 /* network syscalls */ 364 int 365 compat_43_netbsd32_oaccept(struct lwp *l, const struct compat_43_netbsd32_oaccept_args *uap, register_t *retval) 366 { 367 /* { 368 syscallarg(int) s; 369 syscallarg(netbsd32_voidp) name; 370 syscallarg(netbsd32_intp) anamelen; 371 } */ 372 struct compat_43_sys_accept_args ua; 373 374 NETBSD32TOX_UAP(s, int); 375 NETBSD32TOP_UAP(name, void *); 376 NETBSD32TOP_UAP(anamelen, int); 377 return (compat_43_sys_accept(l, &ua, retval)); 378 } 379 380 int 381 compat_43_netbsd32_osend(struct lwp *l, const struct compat_43_netbsd32_osend_args *uap, register_t *retval) 382 { 383 /* { 384 syscallarg(int) s; 385 syscallarg(netbsd32_voidp) buf; 386 syscallarg(int) len; 387 syscallarg(int) flags; 388 } */ 389 struct compat_43_sys_send_args ua; 390 391 NETBSD32TO64_UAP(s); 392 NETBSD32TOP_UAP(buf, void *); 393 NETBSD32TO64_UAP(len); 394 NETBSD32TO64_UAP(flags); 395 return (compat_43_sys_send(l, &ua, retval)); 396 } 397 398 int 399 compat_43_netbsd32_orecv(struct lwp *l, const struct compat_43_netbsd32_orecv_args *uap, register_t *retval) 400 { 401 /* { 402 syscallarg(int) s; 403 syscallarg(netbsd32_voidp) buf; 404 syscallarg(int) len; 405 syscallarg(int) flags; 406 } */ 407 struct compat_43_sys_recv_args ua; 408 409 NETBSD32TO64_UAP(s); 410 NETBSD32TOP_UAP(buf, void *); 411 NETBSD32TO64_UAP(len); 412 NETBSD32TO64_UAP(flags); 413 return (compat_43_sys_recv(l, &ua, retval)); 414 } 415 416 /* 417 * This is a brutal clone of compat_43_sys_recvmsg(). 418 */ 419 int 420 compat_43_netbsd32_orecvmsg(struct lwp *l, const struct compat_43_netbsd32_orecvmsg_args *uap, register_t *retval) 421 { 422 /* { 423 syscallarg(int) s; 424 syscallarg(netbsd32_omsghdrp_t) msg; 425 syscallarg(int) flags; 426 } */ 427 struct netbsd32_omsghdr omsg; 428 struct msghdr msg; 429 struct mbuf *from, *control; 430 struct iovec *iov, aiov[UIO_SMALLIOV]; 431 int error; 432 433 error = copyin(SCARG_P32(uap, msg), &omsg, sizeof (struct omsghdr)); 434 if (error) 435 return (error); 436 437 if (NETBSD32PTR64(omsg.msg_accrights) == NULL) 438 omsg.msg_accrightslen = 0; 439 /* it was this way in 4.4BSD */ 440 if (omsg.msg_accrightslen > MLEN) 441 return EINVAL; 442 443 iov = netbsd32_get_iov(NETBSD32PTR64(omsg.msg_iov), omsg.msg_iovlen, 444 aiov, __arraycount(aiov)); 445 if (iov == NULL) 446 return EFAULT; 447 448 msg.msg_name = NETBSD32PTR64(omsg.msg_name); 449 msg.msg_namelen = omsg.msg_namelen; 450 msg.msg_iovlen = omsg.msg_iovlen; 451 msg.msg_iov = iov; 452 msg.msg_flags = SCARG(uap, flags) & MSG_USERFLAGS; 453 454 error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from, 455 NETBSD32PTR64(omsg.msg_accrights) != NULL ? &control : NULL, 456 retval); 457 if (error != 0) 458 goto out; 459 460 /* 461 * If there is any control information and it's SCM_RIGHTS, 462 * pass it back to the program. 463 * XXX: maybe there can be more than one chunk of control data? 464 */ 465 if (NETBSD32PTR64(omsg.msg_accrights) != NULL && control != NULL) { 466 struct cmsghdr *cmsg = mtod(control, void *); 467 468 if (cmsg->cmsg_level == SOL_SOCKET 469 && cmsg->cmsg_type == SCM_RIGHTS 470 && cmsg->cmsg_len < omsg.msg_accrightslen 471 && copyout(CMSG_DATA(cmsg), 472 NETBSD32PTR64(omsg.msg_accrights), 473 cmsg->cmsg_len) == 0) { 474 omsg.msg_accrightslen = cmsg->cmsg_len; 475 free_control_mbuf(l, control, control->m_next); 476 } else { 477 omsg.msg_accrightslen = 0; 478 free_control_mbuf(l, control, control); 479 } 480 } else 481 omsg.msg_accrightslen = 0; 482 483 if (from != NULL) 484 /* convert from sockaddr sa_family to osockaddr one here */ 485 mtod(from, struct osockaddr *)->sa_family = 486 mtod(from, struct sockaddr *)->sa_family; 487 488 error = copyout_sockname(NETBSD32PTR64(omsg.msg_name), 489 &omsg.msg_namelen, 0, from); 490 if (from != NULL) 491 m_free(from); 492 493 if (error != 0) 494 error = copyout(&omsg, SCARG_P32(uap, msg), sizeof(omsg)); 495 out: 496 if (iov != aiov) { 497 kmem_free(iov, omsg.msg_iovlen * sizeof(*iov)); 498 } 499 return error; 500 } 501 502 int 503 compat_43_netbsd32_osendmsg(struct lwp *l, const struct compat_43_netbsd32_osendmsg_args *uap, register_t *retval) 504 { 505 /* { 506 syscallarg(int) s; 507 syscallarg(netbsd32_voidp) msg; 508 syscallarg(int) flags; 509 } */ 510 struct iovec *iov, aiov[UIO_SMALLIOV]; 511 struct netbsd32_omsghdr omsg; 512 struct msghdr msg; 513 struct mbuf *nam; 514 struct osockaddr *osa; 515 struct sockaddr *sa; 516 int error; 517 518 error = copyin(SCARG_P32(uap, msg), &omsg, sizeof (struct omsghdr)); 519 if (error != 0) 520 return (error); 521 522 iov = netbsd32_get_iov(NETBSD32PTR64(omsg.msg_iov), omsg.msg_iovlen, 523 aiov, __arraycount(aiov)); 524 if (iov == NULL) 525 return EFAULT; 526 527 msg.msg_iovlen = omsg.msg_iovlen; 528 msg.msg_iov = iov; 529 msg.msg_flags = MSG_NAMEMBUF; 530 531 error = sockargs(&nam, NETBSD32PTR64(omsg.msg_name), omsg.msg_namelen, 532 MT_SONAME); 533 if (error != 0) 534 goto out; 535 536 sa = mtod(nam, void *); 537 osa = mtod(nam, void *); 538 sa->sa_family = osa->sa_family; 539 sa->sa_len = omsg.msg_namelen; 540 541 msg.msg_name = nam; 542 msg.msg_namelen = omsg.msg_namelen; 543 error = compat43_set_accrights(&msg, NETBSD32PTR64(omsg.msg_accrights), 544 omsg.msg_accrightslen); 545 if (error != 0) { 546 m_free(nam); 547 goto out; 548 } 549 550 error = do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags), retval); 551 552 out: 553 if (iov != aiov) 554 kmem_free(iov, omsg.msg_iovlen * sizeof(*iov)); 555 return (error); 556 } 557 558 int 559 compat_43_netbsd32_orecvfrom(struct lwp *l, const struct compat_43_netbsd32_orecvfrom_args *uap, register_t *retval) 560 { 561 /* { 562 syscallarg(int) s; 563 syscallarg(netbsd32_voidp) buf; 564 syscallarg(netbsd32_size_t) len; 565 syscallarg(int) flags; 566 syscallarg(netbsd32_voidp) from; 567 syscallarg(netbsd32_intp) fromlenaddr; 568 } */ 569 struct compat_43_sys_recvfrom_args ua; 570 571 NETBSD32TO64_UAP(s); 572 NETBSD32TOP_UAP(buf, void *); 573 NETBSD32TOX_UAP(len, size_t); 574 NETBSD32TO64_UAP(flags); 575 NETBSD32TOP_UAP(from, void *); 576 NETBSD32TOP_UAP(fromlenaddr, int); 577 return (compat_43_sys_recvfrom(l, &ua, retval)); 578 } 579 580 int 581 compat_43_netbsd32_ogetsockname(struct lwp *l, const struct compat_43_netbsd32_ogetsockname_args *uap, register_t *retval) 582 { 583 /* { 584 syscallarg(int) fdec; 585 syscallarg(netbsd32_voidp) asa; 586 syscallarg(netbsd32_intp) alen; 587 } */ 588 struct compat_43_sys_getsockname_args ua; 589 590 NETBSD32TO64_UAP(fdec); 591 NETBSD32TOP_UAP(asa, void *); 592 NETBSD32TOP_UAP(alen, int *); 593 return (compat_43_sys_getsockname(l, &ua, retval)); 594 } 595 596 int 597 compat_43_netbsd32_ogetpeername(struct lwp *l, const struct compat_43_netbsd32_ogetpeername_args *uap, register_t *retval) 598 { 599 /* { 600 syscallarg(int) fdes; 601 syscallarg(netbsd32_voidp) asa; 602 syscallarg(netbsd32_intp) alen; 603 } */ 604 struct compat_43_sys_getpeername_args ua; 605 606 NETBSD32TO64_UAP(fdes); 607 NETBSD32TOP_UAP(asa, void *); 608 NETBSD32TOP_UAP(alen, int *); 609 return (compat_43_sys_getpeername(l, &ua, retval)); 610 } 611 612 /* signal syscalls */ 613 int 614 compat_43_netbsd32_osigvec(struct lwp *l, const struct compat_43_netbsd32_osigvec_args *uap, register_t *retval) 615 { 616 /* { 617 syscallarg(int) signum; 618 syscallarg(netbsd32_sigvecp_t) nsv; 619 syscallarg(netbsd32_sigvecp_t) osv; 620 } */ 621 struct netbsd32_sigvec sv32; 622 struct sigaction nsa, osa; 623 int error; 624 625 if (SCARG(uap, signum) >= 32) 626 return EINVAL; 627 628 if (SCARG_P32(uap, nsv)) { 629 error = copyin(SCARG_P32(uap, nsv), &sv32, sizeof(sv32)); 630 if (error) 631 return error; 632 nsa.sa_handler = NETBSD32PTR64(sv32.sv_handler); 633 nsa.sa_mask.__bits[0] = sv32.sv_mask; 634 nsa.sa_mask.__bits[1] = 0; 635 nsa.sa_mask.__bits[2] = 0; 636 nsa.sa_mask.__bits[3] = 0; 637 nsa.sa_flags = sv32.sv_flags ^ SA_RESTART; 638 error = sigaction1(l, SCARG(uap, signum), &nsa, &osa, NULL, 0); 639 } else 640 error = sigaction1(l, SCARG(uap, signum), NULL, &osa, NULL, 0); 641 if (error) 642 return error; 643 644 if (SCARG_P32(uap, osv)) { 645 NETBSD32PTR32(sv32.sv_handler, osa.sa_handler); 646 sv32.sv_mask = osa.sa_mask.__bits[0]; 647 sv32.sv_flags = osa.sa_flags ^ SA_RESTART; 648 error = copyout(&sv32, SCARG_P32(uap, osv), sizeof(sv32)); 649 } 650 651 return error; 652 } 653 654 int 655 compat_43_netbsd32_sigblock(struct lwp *l, const struct compat_43_netbsd32_sigblock_args *uap, register_t *retval) 656 { 657 /* { 658 syscallarg(int) mask; 659 } */ 660 struct compat_43_sys_sigblock_args ua; 661 662 NETBSD32TO64_UAP(mask); 663 return (compat_43_sys_sigblock(l, &ua, retval)); 664 } 665 666 int 667 compat_43_netbsd32_sigsetmask(struct lwp *l, const struct compat_43_netbsd32_sigsetmask_args *uap, register_t *retval) 668 { 669 /* { 670 syscallarg(int) mask; 671 } */ 672 struct compat_43_sys_sigsetmask_args ua; 673 674 NETBSD32TO64_UAP(mask); 675 return (compat_43_sys_sigsetmask(l, &ua, retval)); 676 } 677 678 int 679 compat_43_netbsd32_osigstack(struct lwp *l, const struct compat_43_netbsd32_osigstack_args *uap, register_t *retval) 680 { 681 /* { 682 syscallarg(netbsd32_sigstackp_t) nss; 683 syscallarg(netbsd32_sigstackp_t) oss; 684 } */ 685 struct netbsd32_sigstack ss32; 686 struct sigaltstack nsa, osa; 687 int error; 688 689 if (SCARG_P32(uap, nss)) { 690 error = copyin(SCARG_P32(uap, nss), &ss32, sizeof(ss32)); 691 if (error) 692 return error; 693 nsa.ss_sp = NETBSD32PTR64(ss32.ss_sp); 694 nsa.ss_size = SIGSTKSZ; /* Use the recommended size */ 695 nsa.ss_flags = ss32.ss_onstack ? SS_ONSTACK : 0; 696 error = sigaltstack1(l, &nsa, &osa); 697 } else 698 error = sigaltstack1(l, NULL, &osa); 699 if (error) 700 return error; 701 702 if (SCARG_P32(uap, oss)) { 703 NETBSD32PTR32(ss32.ss_sp, osa.ss_sp); 704 ss32.ss_onstack = (osa.ss_flags & SS_ONSTACK) != 0; 705 error = copyout(&ss32, SCARG_P32(uap, oss), sizeof(ss32)); 706 } 707 708 return error; 709 } 710