1 /* SPDX-License-Identifier: LGPL-2.1 OR MIT */ 2 /* 3 * Syscall definitions for NOLIBC (those in man(2)) 4 * Copyright (C) 2017-2021 Willy Tarreau <w@1wt.eu> 5 */ 6 7 /* make sure to include all global symbols */ 8 #include "nolibc.h" 9 10 #ifndef _NOLIBC_SYS_H 11 #define _NOLIBC_SYS_H 12 13 #include "std.h" 14 15 /* system includes */ 16 #include <linux/unistd.h> 17 #include <linux/signal.h> /* for SIGCHLD */ 18 #include <linux/termios.h> 19 #include <linux/mman.h> 20 #include <linux/fs.h> 21 #include <linux/loop.h> 22 #include <linux/time.h> 23 #include <linux/auxvec.h> 24 #include <linux/fcntl.h> /* for O_* and AT_* */ 25 #include <linux/sched.h> /* for CLONE_* */ 26 #include <linux/stat.h> /* for statx() */ 27 28 #include "errno.h" 29 #include "stdarg.h" 30 #include "types.h" 31 32 33 /* Syscall return helper: takes the syscall value in argument and checks for an 34 * error in it. This may only be used with signed returns (int or long), but 35 * not with pointers. An error is any value < 0. When an error is encountered, 36 * -ret is set into errno and -1 is returned. Otherwise the returned value is 37 * passed as-is with its type preserved. 38 */ 39 40 #define __sysret(arg) \ 41 ({ \ 42 __typeof__(arg) __sysret_arg = (arg); \ 43 (__sysret_arg < 0) /* error ? */ \ 44 ? (({ SET_ERRNO(-__sysret_arg); }), -1) /* ret -1 with errno = -arg */ \ 45 : __sysret_arg; /* return original value */ \ 46 }) 47 48 /* Syscall ENOSYS helper: Avoids unused-parameter warnings, provides compile 49 * time validation and a debugging hook. 50 */ 51 52 #if defined(NOLIBC_COMPILE_TIME_ENOSYS) 53 static __inline__ int __nolibc_enosys(const char *syscall, ...) 54 { 55 (void)syscall; 56 return -ENOSYS; 57 } 58 59 #elif __nolibc_has_attribute(error) 60 __attribute__((error("system call not implemented"))) 61 extern int __nolibc_enosys(const char *syscall, ...); 62 63 #else 64 static __inline__ int __nolibc_enosys(const char *syscall, ...) 65 { 66 extern int __nolibc_enosys_error; 67 (void)syscall; 68 69 return __nolibc_enosys_error; 70 } 71 #endif 72 73 /* Functions in this file only describe syscalls. They're declared static so 74 * that the compiler usually decides to inline them while still being allowed 75 * to pass a pointer to one of their instances. Each syscall exists in two 76 * versions: 77 * - the "internal" ones, which matches the raw syscall interface at the 78 * kernel level, which may sometimes slightly differ from the documented 79 * libc-level ones. For example most of them return either a valid value 80 * or -errno. All of these are prefixed with "_sys_". They may be called 81 * by non-portable applications if desired. 82 * 83 * - the "exported" ones, whose interface must closely match the one 84 * documented in man(2), that applications are supposed to expect. These 85 * ones rely on the internal ones, and set errno. 86 * 87 * Each syscall will be defined with the two functions, sorted in alphabetical 88 * order applied to the exported names. 89 * 90 * In case of doubt about the relevance of a function here, only those which 91 * set errno should be defined here. Wrappers like those appearing in man(3) 92 * should not be placed here. 93 */ 94 95 96 /* 97 * int brk(void *addr); 98 * void *sbrk(intptr_t inc) 99 */ 100 101 static __attribute__((unused)) 102 void *_sys_brk(void *addr) 103 { 104 return (void *)(unsigned long)__nolibc_syscall1(__NR_brk, addr); 105 } 106 107 static __attribute__((unused)) 108 int brk(void *addr) 109 { 110 void *ret = _sys_brk(addr); 111 112 if (!ret) { 113 SET_ERRNO(ENOMEM); 114 return -1; 115 } 116 return 0; 117 } 118 119 static __attribute__((unused)) 120 void *sbrk(intptr_t inc) 121 { 122 /* first call to find current end */ 123 void *ret = _sys_brk(NULL); 124 125 if (ret && _sys_brk(ret + inc) == ret + inc) 126 return ret + inc; 127 128 SET_ERRNO(ENOMEM); 129 return (void *)-1; 130 } 131 132 133 /* 134 * int chdir(const char *path); 135 * int fchdir(int fildes); 136 */ 137 138 static __attribute__((unused)) 139 int _sys_chdir(const char *path) 140 { 141 return __nolibc_syscall1(__NR_chdir, path); 142 } 143 144 static __attribute__((unused)) 145 int chdir(const char *path) 146 { 147 return __sysret(_sys_chdir(path)); 148 } 149 150 static __attribute__((unused)) 151 int _sys_fchdir(int fildes) 152 { 153 return __nolibc_syscall1(__NR_fchdir, fildes); 154 } 155 156 static __attribute__((unused)) 157 int fchdir(int fildes) 158 { 159 return __sysret(_sys_fchdir(fildes)); 160 } 161 162 163 /* 164 * int chmod(const char *path, mode_t mode); 165 */ 166 167 static __attribute__((unused)) 168 int _sys_chmod(const char *path, mode_t mode) 169 { 170 #if defined(__NR_fchmodat) 171 return __nolibc_syscall4(__NR_fchmodat, AT_FDCWD, path, mode, 0); 172 #else 173 return __nolibc_syscall2(__NR_chmod, path, mode); 174 #endif 175 } 176 177 static __attribute__((unused)) 178 int chmod(const char *path, mode_t mode) 179 { 180 return __sysret(_sys_chmod(path, mode)); 181 } 182 183 184 /* 185 * int chown(const char *path, uid_t owner, gid_t group); 186 */ 187 188 static __attribute__((unused)) 189 int _sys_chown(const char *path, uid_t owner, gid_t group) 190 { 191 #if defined(__NR_fchownat) 192 return __nolibc_syscall5(__NR_fchownat, AT_FDCWD, path, owner, group, 0); 193 #else 194 return __nolibc_syscall3(__NR_chown, path, owner, group); 195 #endif 196 } 197 198 static __attribute__((unused)) 199 int chown(const char *path, uid_t owner, gid_t group) 200 { 201 return __sysret(_sys_chown(path, owner, group)); 202 } 203 204 205 /* 206 * int chroot(const char *path); 207 */ 208 209 static __attribute__((unused)) 210 int _sys_chroot(const char *path) 211 { 212 return __nolibc_syscall1(__NR_chroot, path); 213 } 214 215 static __attribute__((unused)) 216 int chroot(const char *path) 217 { 218 return __sysret(_sys_chroot(path)); 219 } 220 221 222 /* 223 * int close(int fd); 224 */ 225 226 static __attribute__((unused)) 227 int _sys_close(int fd) 228 { 229 return __nolibc_syscall1(__NR_close, fd); 230 } 231 232 static __attribute__((unused)) 233 int close(int fd) 234 { 235 return __sysret(_sys_close(fd)); 236 } 237 238 239 /* 240 * int dup(int fd); 241 */ 242 243 static __attribute__((unused)) 244 int _sys_dup(int fd) 245 { 246 return __nolibc_syscall1(__NR_dup, fd); 247 } 248 249 static __attribute__((unused)) 250 int dup(int fd) 251 { 252 return __sysret(_sys_dup(fd)); 253 } 254 255 256 /* 257 * int dup2(int old, int new); 258 */ 259 260 static __attribute__((unused)) 261 int _sys_dup2(int old, int new) 262 { 263 #if defined(__NR_dup3) 264 int ret, nr_fcntl; 265 266 #ifdef __NR_fcntl64 267 nr_fcntl = __NR_fcntl64; 268 #else 269 nr_fcntl = __NR_fcntl; 270 #endif 271 272 if (old == new) { 273 ret = __nolibc_syscall2(nr_fcntl, old, F_GETFD); 274 return ret < 0 ? ret : old; 275 } 276 277 return __nolibc_syscall3(__NR_dup3, old, new, 0); 278 #else 279 return __nolibc_syscall2(__NR_dup2, old, new); 280 #endif 281 } 282 283 static __attribute__((unused)) 284 int dup2(int old, int new) 285 { 286 return __sysret(_sys_dup2(old, new)); 287 } 288 289 290 /* 291 * int dup3(int old, int new, int flags); 292 */ 293 294 #if defined(__NR_dup3) 295 static __attribute__((unused)) 296 int _sys_dup3(int old, int new, int flags) 297 { 298 return __nolibc_syscall3(__NR_dup3, old, new, flags); 299 } 300 301 static __attribute__((unused)) 302 int dup3(int old, int new, int flags) 303 { 304 return __sysret(_sys_dup3(old, new, flags)); 305 } 306 #endif 307 308 309 /* 310 * int execve(const char *filename, char *const argv[], char *const envp[]); 311 */ 312 313 static __attribute__((unused)) 314 int _sys_execve(const char *filename, char *const argv[], char *const envp[]) 315 { 316 return __nolibc_syscall3(__NR_execve, filename, argv, envp); 317 } 318 319 static __attribute__((unused)) 320 int execve(const char *filename, char *const argv[], char *const envp[]) 321 { 322 return __sysret(_sys_execve(filename, argv, envp)); 323 } 324 325 326 /* 327 * void exit(int status); 328 */ 329 330 static __attribute__((noreturn,unused)) 331 void _sys_exit(int status) 332 { 333 __nolibc_syscall1(__NR_exit, status & 255); 334 while(1); /* shut the "noreturn" warnings. */ 335 } 336 337 static __attribute__((noreturn,unused)) 338 void _exit(int status) 339 { 340 _sys_exit(status); 341 } 342 343 static __attribute__((noreturn,unused)) 344 void exit(int status) 345 { 346 _exit(status); 347 } 348 349 350 /* 351 * pid_t fork(void); 352 */ 353 354 #ifndef _sys_fork 355 static __attribute__((unused)) 356 pid_t _sys_fork(void) 357 { 358 #if defined(__NR_clone) 359 /* note: some archs only have clone() and not fork(). Different archs 360 * have a different API, but most archs have the flags on first arg and 361 * will not use the rest with no other flag. 362 */ 363 return __nolibc_syscall5(__NR_clone, SIGCHLD, 0, 0, 0, 0); 364 #else 365 return __nolibc_syscall0(__NR_fork); 366 #endif 367 } 368 #endif 369 370 static __attribute__((unused)) 371 pid_t fork(void) 372 { 373 return __sysret(_sys_fork()); 374 } 375 376 #ifndef _sys_vfork 377 static __attribute__((unused)) 378 pid_t _sys_vfork(void) 379 { 380 #if defined(__NR_clone) 381 /* See the note in _sys_fork(). */ 382 return __nolibc_syscall5(__NR_clone, CLONE_VM | CLONE_VFORK | SIGCHLD, 0, 0, 0, 0); 383 #elif defined(__NR_vfork) 384 return __nolibc_syscall0(__NR_vfork); 385 #endif 386 } 387 #endif 388 389 static __attribute__((unused)) 390 pid_t vfork(void) 391 { 392 return __sysret(_sys_vfork()); 393 } 394 395 /* 396 * int fsync(int fd); 397 */ 398 399 static __attribute__((unused)) 400 int _sys_fsync(int fd) 401 { 402 return __nolibc_syscall1(__NR_fsync, fd); 403 } 404 405 static __attribute__((unused)) 406 int fsync(int fd) 407 { 408 return __sysret(_sys_fsync(fd)); 409 } 410 411 412 /* 413 * int getdents64(int fd, struct linux_dirent64 *dirp, int count); 414 */ 415 416 static __attribute__((unused)) 417 int _sys_getdents64(int fd, struct linux_dirent64 *dirp, int count) 418 { 419 return __nolibc_syscall3(__NR_getdents64, fd, dirp, count); 420 } 421 422 static __attribute__((unused)) 423 int getdents64(int fd, struct linux_dirent64 *dirp, int count) 424 { 425 return __sysret(_sys_getdents64(fd, dirp, count)); 426 } 427 428 429 /* 430 * uid_t geteuid(void); 431 */ 432 433 static __attribute__((unused)) 434 uid_t _sys_geteuid(void) 435 { 436 #if defined(__NR_geteuid32) 437 return __nolibc_syscall0(__NR_geteuid32); 438 #else 439 return __nolibc_syscall0(__NR_geteuid); 440 #endif 441 } 442 443 static __attribute__((unused)) 444 uid_t geteuid(void) 445 { 446 return _sys_geteuid(); 447 } 448 449 450 /* 451 * pid_t getpgid(pid_t pid); 452 */ 453 454 static __attribute__((unused)) 455 pid_t _sys_getpgid(pid_t pid) 456 { 457 return __nolibc_syscall1(__NR_getpgid, pid); 458 } 459 460 static __attribute__((unused)) 461 pid_t getpgid(pid_t pid) 462 { 463 return __sysret(_sys_getpgid(pid)); 464 } 465 466 467 /* 468 * pid_t getpgrp(void); 469 */ 470 471 static __attribute__((unused)) 472 pid_t _sys_getpgrp(void) 473 { 474 return _sys_getpgid(0); 475 } 476 477 static __attribute__((unused)) 478 pid_t getpgrp(void) 479 { 480 return _sys_getpgrp(); 481 } 482 483 484 /* 485 * pid_t getpid(void); 486 */ 487 488 static __attribute__((unused)) 489 pid_t _sys_getpid(void) 490 { 491 return __nolibc_syscall0(__NR_getpid); 492 } 493 494 static __attribute__((unused)) 495 pid_t getpid(void) 496 { 497 return _sys_getpid(); 498 } 499 500 501 /* 502 * pid_t getppid(void); 503 */ 504 505 static __attribute__((unused)) 506 pid_t _sys_getppid(void) 507 { 508 return __nolibc_syscall0(__NR_getppid); 509 } 510 511 static __attribute__((unused)) 512 pid_t getppid(void) 513 { 514 return _sys_getppid(); 515 } 516 517 518 /* 519 * pid_t gettid(void); 520 */ 521 522 static __attribute__((unused)) 523 pid_t _sys_gettid(void) 524 { 525 return __nolibc_syscall0(__NR_gettid); 526 } 527 528 static __attribute__((unused)) 529 pid_t gettid(void) 530 { 531 return _sys_gettid(); 532 } 533 534 #ifndef NOLIBC_NO_RUNTIME 535 static unsigned long getauxval(unsigned long key); 536 537 /* 538 * int getpagesize(void); 539 */ 540 541 static __attribute__((unused)) 542 int getpagesize(void) 543 { 544 return __sysret((int)getauxval(AT_PAGESZ) ?: -ENOENT); 545 } 546 #endif /* NOLIBC_NO_RUNTIME */ 547 548 /* 549 * uid_t getuid(void); 550 */ 551 552 static __attribute__((unused)) 553 uid_t _sys_getuid(void) 554 { 555 #if defined(__NR_getuid32) 556 return __nolibc_syscall0(__NR_getuid32); 557 #else 558 return __nolibc_syscall0(__NR_getuid); 559 #endif 560 } 561 562 static __attribute__((unused)) 563 uid_t getuid(void) 564 { 565 return _sys_getuid(); 566 } 567 568 569 /* 570 * int kill(pid_t pid, int signal); 571 */ 572 573 static __attribute__((unused)) 574 int _sys_kill(pid_t pid, int signal) 575 { 576 return __nolibc_syscall2(__NR_kill, pid, signal); 577 } 578 579 static __attribute__((unused)) 580 int kill(pid_t pid, int signal) 581 { 582 return __sysret(_sys_kill(pid, signal)); 583 } 584 585 586 /* 587 * int link(const char *old, const char *new); 588 */ 589 590 static __attribute__((unused)) 591 int _sys_link(const char *old, const char *new) 592 { 593 #if defined(__NR_linkat) 594 return __nolibc_syscall5(__NR_linkat, AT_FDCWD, old, AT_FDCWD, new, 0); 595 #else 596 return __nolibc_syscall2(__NR_link, old, new); 597 #endif 598 } 599 600 static __attribute__((unused)) 601 int link(const char *old, const char *new) 602 { 603 return __sysret(_sys_link(old, new)); 604 } 605 606 607 /* 608 * off_t lseek(int fd, off_t offset, int whence); 609 */ 610 611 static __attribute__((unused)) 612 off_t _sys_lseek(int fd, off_t offset, int whence) 613 { 614 #if defined(__NR_llseek) || defined(__NR__llseek) 615 __kernel_loff_t loff = 0; 616 int ret, nr_llseek; 617 off_t result; 618 619 #if defined(__NR_llseek) 620 nr_llseek = __NR_llseek; 621 #else 622 nr_llseek = __NR__llseek; 623 #endif 624 625 ret = __nolibc_syscall5(nr_llseek, fd, offset >> 32, (uint32_t)offset, &loff, whence); 626 if (ret < 0) 627 result = ret; 628 else 629 result = loff; 630 631 return result; 632 #else 633 return __nolibc_syscall3(__NR_lseek, fd, offset, whence); 634 #endif 635 } 636 637 static __attribute__((unused)) 638 off_t lseek(int fd, off_t offset, int whence) 639 { 640 return __sysret(_sys_lseek(fd, offset, whence)); 641 } 642 643 644 /* 645 * int mkdir(const char *path, mode_t mode); 646 */ 647 648 static __attribute__((unused)) 649 int _sys_mkdir(const char *path, mode_t mode) 650 { 651 #if defined(__NR_mkdirat) 652 return __nolibc_syscall3(__NR_mkdirat, AT_FDCWD, path, mode); 653 #else 654 return __nolibc_syscall2(__NR_mkdir, path, mode); 655 #endif 656 } 657 658 static __attribute__((unused)) 659 int mkdir(const char *path, mode_t mode) 660 { 661 return __sysret(_sys_mkdir(path, mode)); 662 } 663 664 /* 665 * int rmdir(const char *path); 666 */ 667 668 static __attribute__((unused)) 669 int _sys_rmdir(const char *path) 670 { 671 #if defined(__NR_rmdir) 672 return __nolibc_syscall1(__NR_rmdir, path); 673 #else 674 return __nolibc_syscall3(__NR_unlinkat, AT_FDCWD, path, AT_REMOVEDIR); 675 #endif 676 } 677 678 static __attribute__((unused)) 679 int rmdir(const char *path) 680 { 681 return __sysret(_sys_rmdir(path)); 682 } 683 684 685 /* 686 * int mknod(const char *path, mode_t mode, dev_t dev); 687 */ 688 689 static __attribute__((unused)) 690 long _sys_mknod(const char *path, mode_t mode, dev_t dev) 691 { 692 #if defined(__NR_mknodat) 693 return __nolibc_syscall4(__NR_mknodat, AT_FDCWD, path, mode, dev); 694 #else 695 return __nolibc_syscall3(__NR_mknod, path, mode, dev); 696 #endif 697 } 698 699 static __attribute__((unused)) 700 int mknod(const char *path, mode_t mode, dev_t dev) 701 { 702 return __sysret(_sys_mknod(path, mode, dev)); 703 } 704 705 706 /* 707 * int pipe2(int pipefd[2], int flags); 708 * int pipe(int pipefd[2]); 709 */ 710 711 static __attribute__((unused)) 712 int _sys_pipe2(int pipefd[2], int flags) 713 { 714 return __nolibc_syscall2(__NR_pipe2, pipefd, flags); 715 } 716 717 static __attribute__((unused)) 718 int pipe2(int pipefd[2], int flags) 719 { 720 return __sysret(_sys_pipe2(pipefd, flags)); 721 } 722 723 static __attribute__((unused)) 724 int pipe(int pipefd[2]) 725 { 726 return pipe2(pipefd, 0); 727 } 728 729 730 /* 731 * int pivot_root(const char *new, const char *old); 732 */ 733 734 static __attribute__((unused)) 735 int _sys_pivot_root(const char *new, const char *old) 736 { 737 return __nolibc_syscall2(__NR_pivot_root, new, old); 738 } 739 740 static __attribute__((unused)) 741 int pivot_root(const char *new, const char *old) 742 { 743 return __sysret(_sys_pivot_root(new, old)); 744 } 745 746 747 /* 748 * ssize_t read(int fd, void *buf, size_t count); 749 */ 750 751 static __attribute__((unused)) 752 ssize_t _sys_read(int fd, void *buf, size_t count) 753 { 754 return __nolibc_syscall3(__NR_read, fd, buf, count); 755 } 756 757 static __attribute__((unused)) 758 ssize_t read(int fd, void *buf, size_t count) 759 { 760 return __sysret(_sys_read(fd, buf, count)); 761 } 762 763 764 /* 765 * int sched_yield(void); 766 */ 767 768 static __attribute__((unused)) 769 int _sys_sched_yield(void) 770 { 771 return __nolibc_syscall0(__NR_sched_yield); 772 } 773 774 static __attribute__((unused)) 775 int sched_yield(void) 776 { 777 return __sysret(_sys_sched_yield()); 778 } 779 780 781 /* 782 * int setpgid(pid_t pid, pid_t pgid); 783 */ 784 785 static __attribute__((unused)) 786 int _sys_setpgid(pid_t pid, pid_t pgid) 787 { 788 return __nolibc_syscall2(__NR_setpgid, pid, pgid); 789 } 790 791 static __attribute__((unused)) 792 int setpgid(pid_t pid, pid_t pgid) 793 { 794 return __sysret(_sys_setpgid(pid, pgid)); 795 } 796 797 /* 798 * pid_t setpgrp(void) 799 */ 800 801 static __attribute__((unused)) 802 pid_t setpgrp(void) 803 { 804 return setpgid(0, 0); 805 } 806 807 808 /* 809 * pid_t setsid(void); 810 */ 811 812 static __attribute__((unused)) 813 pid_t _sys_setsid(void) 814 { 815 return __nolibc_syscall0(__NR_setsid); 816 } 817 818 static __attribute__((unused)) 819 pid_t setsid(void) 820 { 821 return __sysret(_sys_setsid()); 822 } 823 824 825 /* 826 * int symlink(const char *old, const char *new); 827 */ 828 829 static __attribute__((unused)) 830 int _sys_symlink(const char *old, const char *new) 831 { 832 #if defined(__NR_symlinkat) 833 return __nolibc_syscall3(__NR_symlinkat, old, AT_FDCWD, new); 834 #else 835 return __nolibc_syscall2(__NR_symlink, old, new); 836 #endif 837 } 838 839 static __attribute__((unused)) 840 int symlink(const char *old, const char *new) 841 { 842 return __sysret(_sys_symlink(old, new)); 843 } 844 845 846 /* 847 * mode_t umask(mode_t mode); 848 */ 849 850 static __attribute__((unused)) 851 mode_t _sys_umask(mode_t mode) 852 { 853 return __nolibc_syscall1(__NR_umask, mode); 854 } 855 856 static __attribute__((unused)) 857 mode_t umask(mode_t mode) 858 { 859 return _sys_umask(mode); 860 } 861 862 863 /* 864 * int umount2(const char *path, int flags); 865 */ 866 867 static __attribute__((unused)) 868 int _sys_umount2(const char *path, int flags) 869 { 870 return __nolibc_syscall2(__NR_umount2, path, flags); 871 } 872 873 static __attribute__((unused)) 874 int umount2(const char *path, int flags) 875 { 876 return __sysret(_sys_umount2(path, flags)); 877 } 878 879 880 /* 881 * int unlink(const char *path); 882 */ 883 884 static __attribute__((unused)) 885 int _sys_unlink(const char *path) 886 { 887 #if defined(__NR_unlinkat) 888 return __nolibc_syscall3(__NR_unlinkat, AT_FDCWD, path, 0); 889 #else 890 return __nolibc_syscall1(__NR_unlink, path); 891 #endif 892 } 893 894 static __attribute__((unused)) 895 int unlink(const char *path) 896 { 897 return __sysret(_sys_unlink(path)); 898 } 899 900 901 /* 902 * ssize_t write(int fd, const void *buf, size_t count); 903 */ 904 905 static __attribute__((unused)) 906 ssize_t _sys_write(int fd, const void *buf, size_t count) 907 { 908 return __nolibc_syscall3(__NR_write, fd, buf, count); 909 } 910 911 static __attribute__((unused)) 912 ssize_t write(int fd, const void *buf, size_t count) 913 { 914 return __sysret(_sys_write(fd, buf, count)); 915 } 916 917 918 /* 919 * int memfd_create(const char *name, unsigned int flags); 920 */ 921 922 static __attribute__((unused)) 923 int _sys_memfd_create(const char *name, unsigned int flags) 924 { 925 return __nolibc_syscall2(__NR_memfd_create, name, flags); 926 } 927 928 static __attribute__((unused)) 929 int memfd_create(const char *name, unsigned int flags) 930 { 931 return __sysret(_sys_memfd_create(name, flags)); 932 } 933 934 #endif /* _NOLIBC_SYS_H */ 935