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