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