1 /* 2 * Copyright (C) 2005 David Xu <davidxu@freebsd.org>. 3 * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>. 4 * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. 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(s), this list of conditions and the following disclaimer as 12 * the first lines of this file unmodified other than the possible 13 * addition of one or more copyright notices. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice(s), this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 26 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 28 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 29 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 * 31 * $FreeBSD$ 32 */ 33 34 /* 35 * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> 36 * All rights reserved. 37 * 38 * Redistribution and use in source and binary forms, with or without 39 * modification, are permitted provided that the following conditions 40 * are met: 41 * 1. Redistributions of source code must retain the above copyright 42 * notice, this list of conditions and the following disclaimer. 43 * 2. Redistributions in binary form must reproduce the above copyright 44 * notice, this list of conditions and the following disclaimer in the 45 * documentation and/or other materials provided with the distribution. 46 * 3. Neither the name of the author nor the names of any co-contributors 47 * may be used to endorse or promote products derived from this software 48 * without specific prior written permission. 49 * 50 * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND 51 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 53 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 54 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 55 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 56 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 58 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 59 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 60 * SUCH DAMAGE. 61 * 62 */ 63 64 #include "namespace.h" 65 #include <sys/types.h> 66 #include <sys/mman.h> 67 #include <sys/param.h> 68 #include <sys/select.h> 69 #include <sys/signalvar.h> 70 #include <sys/socket.h> 71 #include <sys/stat.h> 72 #include <sys/time.h> 73 #include <sys/uio.h> 74 #include <sys/wait.h> 75 #include <aio.h> 76 #include <dirent.h> 77 #include <errno.h> 78 #include <fcntl.h> 79 #include <poll.h> 80 #include <signal.h> 81 #include <stdarg.h> 82 #include <stdio.h> 83 #include <stdlib.h> 84 #include <string.h> 85 #include <termios.h> 86 #include <unistd.h> 87 #include <pthread.h> 88 #include "un-namespace.h" 89 90 #include "thr_private.h" 91 92 extern int __creat(const char *, mode_t); 93 extern int __pselect(int, fd_set *, fd_set *, fd_set *, 94 const struct timespec *, const sigset_t *); 95 extern unsigned __sleep(unsigned int); 96 extern int __system(const char *); 97 extern int __tcdrain(int); 98 extern int __usleep(useconds_t); 99 extern pid_t __wait(int *); 100 extern pid_t __waitpid(pid_t, int *, int); 101 extern int __sys_aio_suspend(const struct aiocb * const[], int, 102 const struct timespec *); 103 extern int __sys_accept(int, struct sockaddr *, socklen_t *); 104 extern int __sys_accept4(int, struct sockaddr *, socklen_t *, int); 105 extern int __sys_connect(int, const struct sockaddr *, socklen_t); 106 extern int __sys_fsync(int); 107 extern int __sys_msync(void *, size_t, int); 108 extern int __sys_pselect(int, fd_set *, fd_set *, fd_set *, 109 const struct timespec *, const sigset_t *); 110 extern int __sys_poll(struct pollfd *, unsigned, int); 111 extern ssize_t __sys_recv(int, void *, size_t, int); 112 extern ssize_t __sys_recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *); 113 extern ssize_t __sys_recvmsg(int, struct msghdr *, int); 114 extern int __sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *); 115 extern int __sys_sendfile(int, int, off_t, size_t, struct sf_hdtr *, 116 off_t *, int); 117 extern ssize_t __sys_sendmsg(int, const struct msghdr *, int); 118 extern ssize_t __sys_sendto(int, const void *,size_t, int, const struct sockaddr *, socklen_t); 119 extern ssize_t __sys_readv(int, const struct iovec *, int); 120 extern pid_t __sys_wait4(pid_t, int *, int, struct rusage *); 121 extern ssize_t __sys_writev(int, const struct iovec *, int); 122 123 int ___creat(const char *, mode_t); 124 int ___pselect(int, fd_set *, fd_set *, fd_set *, 125 const struct timespec *, const sigset_t *); 126 unsigned ___sleep(unsigned); 127 int ___system(const char *); 128 int ___tcdrain(int); 129 int ___usleep(useconds_t useconds); 130 pid_t ___wait(int *); 131 pid_t ___waitpid(pid_t, int *, int); 132 int __accept(int, struct sockaddr *, socklen_t *); 133 int __accept4(int, struct sockaddr *, socklen_t *, int); 134 int __aio_suspend(const struct aiocb * const iocbs[], int, 135 const struct timespec *); 136 int __close(int); 137 int __connect(int, const struct sockaddr *, socklen_t); 138 int __fcntl(int, int,...); 139 #ifdef SYSCALL_COMPAT 140 extern int __fcntl_compat(int, int,...); 141 #endif 142 int __fsync(int); 143 int __msync(void *, size_t, int); 144 int __nanosleep(const struct timespec *, struct timespec *); 145 int __open(const char *, int,...); 146 int __openat(int, const char *, int,...); 147 int __poll(struct pollfd *, unsigned int, int); 148 ssize_t __read(int, void *buf, size_t); 149 ssize_t __readv(int, const struct iovec *, int); 150 ssize_t __recvfrom(int, void *, size_t, int f, struct sockaddr *, socklen_t *); 151 ssize_t __recvmsg(int, struct msghdr *, int); 152 int __select(int, fd_set *, fd_set *, fd_set *, struct timeval *); 153 ssize_t __sendmsg(int, const struct msghdr *, int); 154 ssize_t __sendto(int, const void *, size_t, int, 155 const struct sockaddr *, socklen_t); 156 pid_t __wait3(int *, int, struct rusage *); 157 pid_t __wait4(pid_t, int *, int, struct rusage *); 158 ssize_t __write(int, const void *, size_t); 159 ssize_t __writev(int, const struct iovec *, int); 160 161 __weak_reference(__accept, accept); 162 163 /* 164 * Cancellation behavior: 165 * If thread is canceled, no socket is created. 166 */ 167 int 168 __accept(int s, struct sockaddr *addr, socklen_t *addrlen) 169 { 170 struct pthread *curthread; 171 int ret; 172 173 curthread = _get_curthread(); 174 _thr_cancel_enter(curthread); 175 ret = __sys_accept(s, addr, addrlen); 176 _thr_cancel_leave(curthread, ret == -1); 177 178 return (ret); 179 } 180 181 __weak_reference(__accept4, accept4); 182 183 /* 184 * Cancellation behavior: 185 * If thread is canceled, no socket is created. 186 */ 187 int 188 __accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags) 189 { 190 struct pthread *curthread; 191 int ret; 192 193 curthread = _get_curthread(); 194 _thr_cancel_enter(curthread); 195 ret = __sys_accept4(s, addr, addrlen, flags); 196 _thr_cancel_leave(curthread, ret == -1); 197 198 return (ret); 199 } 200 201 __weak_reference(__aio_suspend, aio_suspend); 202 203 int 204 __aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct 205 timespec *timeout) 206 { 207 struct pthread *curthread = _get_curthread(); 208 int ret; 209 210 _thr_cancel_enter(curthread); 211 ret = __sys_aio_suspend(iocbs, niocb, timeout); 212 _thr_cancel_leave(curthread, 1); 213 214 return (ret); 215 } 216 217 __weak_reference(__close, close); 218 219 /* 220 * Cancellation behavior: 221 * According to manual of close(), the file descriptor is always deleted. 222 * Here, thread is only canceled after the system call, so the file 223 * descriptor is always deleted despite whether the thread is canceled 224 * or not. 225 */ 226 int 227 __close(int fd) 228 { 229 struct pthread *curthread = _get_curthread(); 230 int ret; 231 232 _thr_cancel_enter2(curthread, 0); 233 ret = __sys_close(fd); 234 _thr_cancel_leave(curthread, 1); 235 236 return (ret); 237 } 238 239 __weak_reference(__connect, connect); 240 241 /* 242 * Cancellation behavior: 243 * If the thread is canceled, connection is not made. 244 */ 245 int 246 __connect(int fd, const struct sockaddr *name, socklen_t namelen) 247 { 248 struct pthread *curthread = _get_curthread(); 249 int ret; 250 251 _thr_cancel_enter(curthread); 252 ret = __sys_connect(fd, name, namelen); 253 _thr_cancel_leave(curthread, ret == -1); 254 255 return (ret); 256 } 257 258 __weak_reference(___creat, creat); 259 260 /* 261 * Cancellation behavior: 262 * If thread is canceled, file is not created. 263 */ 264 int 265 ___creat(const char *path, mode_t mode) 266 { 267 struct pthread *curthread = _get_curthread(); 268 int ret; 269 270 _thr_cancel_enter(curthread); 271 ret = __creat(path, mode); 272 _thr_cancel_leave(curthread, ret == -1); 273 274 return ret; 275 } 276 277 __weak_reference(__fcntl, fcntl); 278 279 /* 280 * Cancellation behavior: 281 * According to specification, only F_SETLKW is a cancellation point. 282 * Thread is only canceled at start, or canceled if the system call 283 * is failure, this means the function does not generate side effect 284 * if it is canceled. 285 */ 286 int 287 __fcntl(int fd, int cmd,...) 288 { 289 struct pthread *curthread = _get_curthread(); 290 int ret; 291 va_list ap; 292 293 va_start(ap, cmd); 294 if (cmd == F_OSETLKW || cmd == F_SETLKW) { 295 _thr_cancel_enter(curthread); 296 #ifdef SYSCALL_COMPAT 297 ret = __fcntl_compat(fd, cmd, va_arg(ap, void *)); 298 #else 299 ret = __sys_fcntl(fd, cmd, va_arg(ap, void *)); 300 #endif 301 _thr_cancel_leave(curthread, ret == -1); 302 } else { 303 #ifdef SYSCALL_COMPAT 304 ret = __fcntl_compat(fd, cmd, va_arg(ap, void *)); 305 #else 306 ret = __sys_fcntl(fd, cmd, va_arg(ap, void *)); 307 #endif 308 } 309 va_end(ap); 310 311 return (ret); 312 } 313 314 __weak_reference(__fsync, fsync); 315 316 /* 317 * Cancellation behavior: 318 * Thread may be canceled after system call. 319 */ 320 int 321 __fsync(int fd) 322 { 323 struct pthread *curthread = _get_curthread(); 324 int ret; 325 326 _thr_cancel_enter2(curthread, 0); 327 ret = __sys_fsync(fd); 328 _thr_cancel_leave(curthread, 1); 329 330 return (ret); 331 } 332 333 __weak_reference(__msync, msync); 334 335 /* 336 * Cancellation behavior: 337 * Thread may be canceled after system call. 338 */ 339 int 340 __msync(void *addr, size_t len, int flags) 341 { 342 struct pthread *curthread = _get_curthread(); 343 int ret; 344 345 _thr_cancel_enter2(curthread, 0); 346 ret = __sys_msync(addr, len, flags); 347 _thr_cancel_leave(curthread, 1); 348 349 return ret; 350 } 351 352 __weak_reference(__nanosleep, nanosleep); 353 354 int 355 __nanosleep(const struct timespec *time_to_sleep, 356 struct timespec *time_remaining) 357 { 358 struct pthread *curthread = _get_curthread(); 359 int ret; 360 361 _thr_cancel_enter(curthread); 362 ret = __sys_nanosleep(time_to_sleep, time_remaining); 363 _thr_cancel_leave(curthread, 1); 364 365 return (ret); 366 } 367 368 __weak_reference(__open, open); 369 370 /* 371 * Cancellation behavior: 372 * If the thread is canceled, file is not opened. 373 */ 374 int 375 __open(const char *path, int flags,...) 376 { 377 struct pthread *curthread = _get_curthread(); 378 int ret; 379 int mode = 0; 380 va_list ap; 381 382 /* Check if the file is being created: */ 383 if (flags & O_CREAT) { 384 /* Get the creation mode: */ 385 va_start(ap, flags); 386 mode = va_arg(ap, int); 387 va_end(ap); 388 } 389 390 _thr_cancel_enter(curthread); 391 ret = __sys_open(path, flags, mode); 392 _thr_cancel_leave(curthread, ret == -1); 393 394 return ret; 395 } 396 397 __weak_reference(__openat, openat); 398 399 /* 400 * Cancellation behavior: 401 * If the thread is canceled, file is not opened. 402 */ 403 int 404 __openat(int fd, const char *path, int flags, ...) 405 { 406 struct pthread *curthread = _get_curthread(); 407 int ret; 408 int mode = 0; 409 va_list ap; 410 411 412 /* Check if the file is being created: */ 413 if (flags & O_CREAT) { 414 /* Get the creation mode: */ 415 va_start(ap, flags); 416 mode = va_arg(ap, int); 417 va_end(ap); 418 } 419 420 _thr_cancel_enter(curthread); 421 ret = __sys_openat(fd, path, flags, mode); 422 _thr_cancel_leave(curthread, ret == -1); 423 424 return ret; 425 } 426 427 __weak_reference(__poll, poll); 428 429 /* 430 * Cancellation behavior: 431 * Thread may be canceled at start, but if the system call returns something, 432 * the thread is not canceled. 433 */ 434 int 435 __poll(struct pollfd *fds, unsigned int nfds, int timeout) 436 { 437 struct pthread *curthread = _get_curthread(); 438 int ret; 439 440 _thr_cancel_enter(curthread); 441 ret = __sys_poll(fds, nfds, timeout); 442 _thr_cancel_leave(curthread, ret == -1); 443 444 return ret; 445 } 446 447 __weak_reference(___pselect, pselect); 448 449 /* 450 * Cancellation behavior: 451 * Thread may be canceled at start, but if the system call returns something, 452 * the thread is not canceled. 453 */ 454 int 455 ___pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds, 456 const struct timespec *timo, const sigset_t *mask) 457 { 458 struct pthread *curthread = _get_curthread(); 459 int ret; 460 461 _thr_cancel_enter(curthread); 462 ret = __sys_pselect(count, rfds, wfds, efds, timo, mask); 463 _thr_cancel_leave(curthread, ret == -1); 464 465 return (ret); 466 } 467 468 __weak_reference(__read, read); 469 470 /* 471 * Cancellation behavior: 472 * Thread may be canceled at start, but if the system call got some data, 473 * the thread is not canceled. 474 */ 475 ssize_t 476 __read(int fd, void *buf, size_t nbytes) 477 { 478 struct pthread *curthread = _get_curthread(); 479 ssize_t ret; 480 481 _thr_cancel_enter(curthread); 482 ret = __sys_read(fd, buf, nbytes); 483 _thr_cancel_leave(curthread, ret == -1); 484 485 return ret; 486 } 487 488 __weak_reference(__readv, readv); 489 490 /* 491 * Cancellation behavior: 492 * Thread may be canceled at start, but if the system call got some data, 493 * the thread is not canceled. 494 */ 495 ssize_t 496 __readv(int fd, const struct iovec *iov, int iovcnt) 497 { 498 struct pthread *curthread = _get_curthread(); 499 ssize_t ret; 500 501 _thr_cancel_enter(curthread); 502 ret = __sys_readv(fd, iov, iovcnt); 503 _thr_cancel_leave(curthread, ret == -1); 504 return ret; 505 } 506 507 __weak_reference(__recvfrom, recvfrom); 508 509 /* 510 * Cancellation behavior: 511 * Thread may be canceled at start, but if the system call got some data, 512 * the thread is not canceled. 513 */ 514 ssize_t 515 __recvfrom(int s, void *b, size_t l, int f, struct sockaddr *from, 516 socklen_t *fl) 517 { 518 struct pthread *curthread = _get_curthread(); 519 ssize_t ret; 520 521 _thr_cancel_enter(curthread); 522 ret = __sys_recvfrom(s, b, l, f, from, fl); 523 _thr_cancel_leave(curthread, ret == -1); 524 return (ret); 525 } 526 527 __weak_reference(__recvmsg, recvmsg); 528 529 /* 530 * Cancellation behavior: 531 * Thread may be canceled at start, but if the system call got some data, 532 * the thread is not canceled. 533 */ 534 ssize_t 535 __recvmsg(int s, struct msghdr *m, int f) 536 { 537 struct pthread *curthread = _get_curthread(); 538 ssize_t ret; 539 540 _thr_cancel_enter(curthread); 541 ret = __sys_recvmsg(s, m, f); 542 _thr_cancel_leave(curthread, ret == -1); 543 return (ret); 544 } 545 546 __weak_reference(__select, select); 547 548 /* 549 * Cancellation behavior: 550 * Thread may be canceled at start, but if the system call returns something, 551 * the thread is not canceled. 552 */ 553 int 554 __select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, 555 struct timeval *timeout) 556 { 557 struct pthread *curthread = _get_curthread(); 558 int ret; 559 560 _thr_cancel_enter(curthread); 561 ret = __sys_select(numfds, readfds, writefds, exceptfds, timeout); 562 _thr_cancel_leave(curthread, ret == -1); 563 return ret; 564 } 565 566 __weak_reference(__sendmsg, sendmsg); 567 568 /* 569 * Cancellation behavior: 570 * Thread may be canceled at start, but if the system call sent 571 * data, the thread is not canceled. 572 */ 573 ssize_t 574 __sendmsg(int s, const struct msghdr *m, int f) 575 { 576 struct pthread *curthread = _get_curthread(); 577 ssize_t ret; 578 579 _thr_cancel_enter(curthread); 580 ret = __sys_sendmsg(s, m, f); 581 _thr_cancel_leave(curthread, ret <= 0); 582 return (ret); 583 } 584 585 __weak_reference(__sendto, sendto); 586 587 /* 588 * Cancellation behavior: 589 * Thread may be canceled at start, but if the system call sent some 590 * data, the thread is not canceled. 591 */ 592 ssize_t 593 __sendto(int s, const void *m, size_t l, int f, const struct sockaddr *t, 594 socklen_t tl) 595 { 596 struct pthread *curthread = _get_curthread(); 597 ssize_t ret; 598 599 _thr_cancel_enter(curthread); 600 ret = __sys_sendto(s, m, l, f, t, tl); 601 _thr_cancel_leave(curthread, ret <= 0); 602 return (ret); 603 } 604 605 __weak_reference(___sleep, sleep); 606 607 unsigned int 608 ___sleep(unsigned int seconds) 609 { 610 struct pthread *curthread = _get_curthread(); 611 unsigned int ret; 612 613 _thr_cancel_enter(curthread); 614 ret = __sleep(seconds); 615 _thr_cancel_leave(curthread, 1); 616 617 return (ret); 618 } 619 620 __weak_reference(___system, system); 621 622 int 623 ___system(const char *string) 624 { 625 struct pthread *curthread = _get_curthread(); 626 int ret; 627 628 _thr_cancel_enter(curthread); 629 ret = __system(string); 630 _thr_cancel_leave(curthread, 1); 631 632 return ret; 633 } 634 635 __weak_reference(___tcdrain, tcdrain); 636 637 /* 638 * Cancellation behavior: 639 * If thread is canceled, the system call is not completed, 640 * this means not all bytes were drained. 641 */ 642 int 643 ___tcdrain(int fd) 644 { 645 struct pthread *curthread = _get_curthread(); 646 int ret; 647 648 _thr_cancel_enter(curthread); 649 ret = __tcdrain(fd); 650 _thr_cancel_leave(curthread, ret == -1); 651 return (ret); 652 } 653 654 __weak_reference(___usleep, usleep); 655 656 int 657 ___usleep(useconds_t useconds) 658 { 659 struct pthread *curthread = _get_curthread(); 660 int ret; 661 662 _thr_cancel_enter(curthread); 663 ret = __usleep(useconds); 664 _thr_cancel_leave(curthread, 1); 665 666 return (ret); 667 } 668 669 __weak_reference(___wait, wait); 670 671 /* 672 * Cancellation behavior: 673 * Thread may be canceled at start, but if the system call returns 674 * a child pid, the thread is not canceled. 675 */ 676 pid_t 677 ___wait(int *istat) 678 { 679 struct pthread *curthread = _get_curthread(); 680 pid_t ret; 681 682 _thr_cancel_enter(curthread); 683 ret = __wait(istat); 684 _thr_cancel_leave(curthread, ret <= 0); 685 686 return ret; 687 } 688 689 __weak_reference(__wait3, wait3); 690 691 /* 692 * Cancellation behavior: 693 * Thread may be canceled at start, but if the system call returns 694 * a child pid, the thread is not canceled. 695 */ 696 pid_t 697 __wait3(int *status, int options, struct rusage *rusage) 698 { 699 struct pthread *curthread = _get_curthread(); 700 pid_t ret; 701 702 _thr_cancel_enter(curthread); 703 ret = _wait4(WAIT_ANY, status, options, rusage); 704 _thr_cancel_leave(curthread, ret <= 0); 705 706 return (ret); 707 } 708 709 __weak_reference(__wait4, wait4); 710 711 /* 712 * Cancellation behavior: 713 * Thread may be canceled at start, but if the system call returns 714 * a child pid, the thread is not canceled. 715 */ 716 pid_t 717 __wait4(pid_t pid, int *status, int options, struct rusage *rusage) 718 { 719 struct pthread *curthread = _get_curthread(); 720 pid_t ret; 721 722 _thr_cancel_enter(curthread); 723 ret = __sys_wait4(pid, status, options, rusage); 724 _thr_cancel_leave(curthread, ret <= 0); 725 726 return ret; 727 } 728 729 __weak_reference(___waitpid, waitpid); 730 731 /* 732 * Cancellation behavior: 733 * Thread may be canceled at start, but if the system call returns 734 * a child pid, the thread is not canceled. 735 */ 736 pid_t 737 ___waitpid(pid_t wpid, int *status, int options) 738 { 739 struct pthread *curthread = _get_curthread(); 740 pid_t ret; 741 742 _thr_cancel_enter(curthread); 743 ret = __waitpid(wpid, status, options); 744 _thr_cancel_leave(curthread, ret <= 0); 745 746 return ret; 747 } 748 749 __weak_reference(__write, write); 750 751 /* 752 * Cancellation behavior: 753 * Thread may be canceled at start, but if the thread wrote some data, 754 * it is not canceled. 755 */ 756 ssize_t 757 __write(int fd, const void *buf, size_t nbytes) 758 { 759 struct pthread *curthread = _get_curthread(); 760 ssize_t ret; 761 762 _thr_cancel_enter(curthread); 763 ret = __sys_write(fd, buf, nbytes); 764 _thr_cancel_leave(curthread, (ret <= 0)); 765 return ret; 766 } 767 768 __weak_reference(__writev, writev); 769 770 /* 771 * Cancellation behavior: 772 * Thread may be canceled at start, but if the thread wrote some data, 773 * it is not canceled. 774 */ 775 ssize_t 776 __writev(int fd, const struct iovec *iov, int iovcnt) 777 { 778 struct pthread *curthread = _get_curthread(); 779 ssize_t ret; 780 781 _thr_cancel_enter(curthread); 782 ret = __sys_writev(fd, iov, iovcnt); 783 _thr_cancel_leave(curthread, (ret <= 0)); 784 return ret; 785 } 786