sys.h 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264
  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. #ifndef _NOLIBC_SYS_H
  7. #define _NOLIBC_SYS_H
  8. #include "std.h"
  9. /* system includes */
  10. #include <asm/unistd.h>
  11. #include <asm/signal.h> /* for SIGCHLD */
  12. #include <asm/ioctls.h>
  13. #include <asm/mman.h>
  14. #include <linux/fs.h>
  15. #include <linux/loop.h>
  16. #include <linux/time.h>
  17. #include <linux/auxvec.h>
  18. #include <linux/fcntl.h> /* for O_* and AT_* */
  19. #include <linux/stat.h> /* for statx() */
  20. #include <linux/prctl.h>
  21. #include <linux/resource.h>
  22. #include <linux/utsname.h>
  23. #include "arch.h"
  24. #include "errno.h"
  25. #include "stdarg.h"
  26. #include "types.h"
  27. /* Syscall return helper: takes the syscall value in argument and checks for an
  28. * error in it. This may only be used with signed returns (int or long), but
  29. * not with pointers. An error is any value < 0. When an error is encountered,
  30. * -ret is set into errno and -1 is returned. Otherwise the returned value is
  31. * passed as-is with its type preserved.
  32. */
  33. #define __sysret(arg) \
  34. ({ \
  35. __typeof__(arg) __sysret_arg = (arg); \
  36. (__sysret_arg < 0) /* error ? */ \
  37. ? (({ SET_ERRNO(-__sysret_arg); }), -1) /* ret -1 with errno = -arg */ \
  38. : __sysret_arg; /* return original value */ \
  39. })
  40. /* Syscall ENOSYS helper: Avoids unused-parameter warnings and provides a
  41. * debugging hook.
  42. */
  43. static __inline__ int __nolibc_enosys(const char *syscall, ...)
  44. {
  45. (void)syscall;
  46. return -ENOSYS;
  47. }
  48. /* Functions in this file only describe syscalls. They're declared static so
  49. * that the compiler usually decides to inline them while still being allowed
  50. * to pass a pointer to one of their instances. Each syscall exists in two
  51. * versions:
  52. * - the "internal" ones, which matches the raw syscall interface at the
  53. * kernel level, which may sometimes slightly differ from the documented
  54. * libc-level ones. For example most of them return either a valid value
  55. * or -errno. All of these are prefixed with "sys_". They may be called
  56. * by non-portable applications if desired.
  57. *
  58. * - the "exported" ones, whose interface must closely match the one
  59. * documented in man(2), that applications are supposed to expect. These
  60. * ones rely on the internal ones, and set errno.
  61. *
  62. * Each syscall will be defined with the two functions, sorted in alphabetical
  63. * order applied to the exported names.
  64. *
  65. * In case of doubt about the relevance of a function here, only those which
  66. * set errno should be defined here. Wrappers like those appearing in man(3)
  67. * should not be placed here.
  68. */
  69. /*
  70. * int brk(void *addr);
  71. * void *sbrk(intptr_t inc)
  72. */
  73. static __attribute__((unused))
  74. void *sys_brk(void *addr)
  75. {
  76. return (void *)my_syscall1(__NR_brk, addr);
  77. }
  78. static __attribute__((unused))
  79. int brk(void *addr)
  80. {
  81. void *ret = sys_brk(addr);
  82. if (!ret) {
  83. SET_ERRNO(ENOMEM);
  84. return -1;
  85. }
  86. return 0;
  87. }
  88. static __attribute__((unused))
  89. void *sbrk(intptr_t inc)
  90. {
  91. /* first call to find current end */
  92. void *ret = sys_brk(0);
  93. if (ret && sys_brk(ret + inc) == ret + inc)
  94. return ret + inc;
  95. SET_ERRNO(ENOMEM);
  96. return (void *)-1;
  97. }
  98. /*
  99. * int chdir(const char *path);
  100. */
  101. static __attribute__((unused))
  102. int sys_chdir(const char *path)
  103. {
  104. return my_syscall1(__NR_chdir, path);
  105. }
  106. static __attribute__((unused))
  107. int chdir(const char *path)
  108. {
  109. return __sysret(sys_chdir(path));
  110. }
  111. /*
  112. * int chmod(const char *path, mode_t mode);
  113. */
  114. static __attribute__((unused))
  115. int sys_chmod(const char *path, mode_t mode)
  116. {
  117. #ifdef __NR_fchmodat
  118. return my_syscall4(__NR_fchmodat, AT_FDCWD, path, mode, 0);
  119. #elif defined(__NR_chmod)
  120. return my_syscall2(__NR_chmod, path, mode);
  121. #else
  122. return __nolibc_enosys(__func__, path, mode);
  123. #endif
  124. }
  125. static __attribute__((unused))
  126. int chmod(const char *path, mode_t mode)
  127. {
  128. return __sysret(sys_chmod(path, mode));
  129. }
  130. /*
  131. * int chown(const char *path, uid_t owner, gid_t group);
  132. */
  133. static __attribute__((unused))
  134. int sys_chown(const char *path, uid_t owner, gid_t group)
  135. {
  136. #ifdef __NR_fchownat
  137. return my_syscall5(__NR_fchownat, AT_FDCWD, path, owner, group, 0);
  138. #elif defined(__NR_chown)
  139. return my_syscall3(__NR_chown, path, owner, group);
  140. #else
  141. return __nolibc_enosys(__func__, path, owner, group);
  142. #endif
  143. }
  144. static __attribute__((unused))
  145. int chown(const char *path, uid_t owner, gid_t group)
  146. {
  147. return __sysret(sys_chown(path, owner, group));
  148. }
  149. /*
  150. * int chroot(const char *path);
  151. */
  152. static __attribute__((unused))
  153. int sys_chroot(const char *path)
  154. {
  155. return my_syscall1(__NR_chroot, path);
  156. }
  157. static __attribute__((unused))
  158. int chroot(const char *path)
  159. {
  160. return __sysret(sys_chroot(path));
  161. }
  162. /*
  163. * int close(int fd);
  164. */
  165. static __attribute__((unused))
  166. int sys_close(int fd)
  167. {
  168. return my_syscall1(__NR_close, fd);
  169. }
  170. static __attribute__((unused))
  171. int close(int fd)
  172. {
  173. return __sysret(sys_close(fd));
  174. }
  175. /*
  176. * int dup(int fd);
  177. */
  178. static __attribute__((unused))
  179. int sys_dup(int fd)
  180. {
  181. return my_syscall1(__NR_dup, fd);
  182. }
  183. static __attribute__((unused))
  184. int dup(int fd)
  185. {
  186. return __sysret(sys_dup(fd));
  187. }
  188. /*
  189. * int dup2(int old, int new);
  190. */
  191. static __attribute__((unused))
  192. int sys_dup2(int old, int new)
  193. {
  194. #ifdef __NR_dup3
  195. return my_syscall3(__NR_dup3, old, new, 0);
  196. #elif defined(__NR_dup2)
  197. return my_syscall2(__NR_dup2, old, new);
  198. #else
  199. return __nolibc_enosys(__func__, old, new);
  200. #endif
  201. }
  202. static __attribute__((unused))
  203. int dup2(int old, int new)
  204. {
  205. return __sysret(sys_dup2(old, new));
  206. }
  207. /*
  208. * int dup3(int old, int new, int flags);
  209. */
  210. #ifdef __NR_dup3
  211. static __attribute__((unused))
  212. int sys_dup3(int old, int new, int flags)
  213. {
  214. return my_syscall3(__NR_dup3, old, new, flags);
  215. }
  216. static __attribute__((unused))
  217. int dup3(int old, int new, int flags)
  218. {
  219. return __sysret(sys_dup3(old, new, flags));
  220. }
  221. #endif
  222. /*
  223. * int execve(const char *filename, char *const argv[], char *const envp[]);
  224. */
  225. static __attribute__((unused))
  226. int sys_execve(const char *filename, char *const argv[], char *const envp[])
  227. {
  228. return my_syscall3(__NR_execve, filename, argv, envp);
  229. }
  230. static __attribute__((unused))
  231. int execve(const char *filename, char *const argv[], char *const envp[])
  232. {
  233. return __sysret(sys_execve(filename, argv, envp));
  234. }
  235. /*
  236. * void exit(int status);
  237. */
  238. static __attribute__((noreturn,unused))
  239. void sys_exit(int status)
  240. {
  241. my_syscall1(__NR_exit, status & 255);
  242. while(1); /* shut the "noreturn" warnings. */
  243. }
  244. static __attribute__((noreturn,unused))
  245. void exit(int status)
  246. {
  247. sys_exit(status);
  248. }
  249. /*
  250. * pid_t fork(void);
  251. */
  252. #ifndef sys_fork
  253. static __attribute__((unused))
  254. pid_t sys_fork(void)
  255. {
  256. #ifdef __NR_clone
  257. /* note: some archs only have clone() and not fork(). Different archs
  258. * have a different API, but most archs have the flags on first arg and
  259. * will not use the rest with no other flag.
  260. */
  261. return my_syscall5(__NR_clone, SIGCHLD, 0, 0, 0, 0);
  262. #elif defined(__NR_fork)
  263. return my_syscall0(__NR_fork);
  264. #else
  265. return __nolibc_enosys(__func__);
  266. #endif
  267. }
  268. #endif
  269. static __attribute__((unused))
  270. pid_t fork(void)
  271. {
  272. return __sysret(sys_fork());
  273. }
  274. /*
  275. * int fsync(int fd);
  276. */
  277. static __attribute__((unused))
  278. int sys_fsync(int fd)
  279. {
  280. return my_syscall1(__NR_fsync, fd);
  281. }
  282. static __attribute__((unused))
  283. int fsync(int fd)
  284. {
  285. return __sysret(sys_fsync(fd));
  286. }
  287. /*
  288. * int getdents64(int fd, struct linux_dirent64 *dirp, int count);
  289. */
  290. static __attribute__((unused))
  291. int sys_getdents64(int fd, struct linux_dirent64 *dirp, int count)
  292. {
  293. return my_syscall3(__NR_getdents64, fd, dirp, count);
  294. }
  295. static __attribute__((unused))
  296. int getdents64(int fd, struct linux_dirent64 *dirp, int count)
  297. {
  298. return __sysret(sys_getdents64(fd, dirp, count));
  299. }
  300. /*
  301. * uid_t geteuid(void);
  302. */
  303. static __attribute__((unused))
  304. uid_t sys_geteuid(void)
  305. {
  306. #ifdef __NR_geteuid32
  307. return my_syscall0(__NR_geteuid32);
  308. #else
  309. return my_syscall0(__NR_geteuid);
  310. #endif
  311. }
  312. static __attribute__((unused))
  313. uid_t geteuid(void)
  314. {
  315. return sys_geteuid();
  316. }
  317. /*
  318. * pid_t getpgid(pid_t pid);
  319. */
  320. static __attribute__((unused))
  321. pid_t sys_getpgid(pid_t pid)
  322. {
  323. return my_syscall1(__NR_getpgid, pid);
  324. }
  325. static __attribute__((unused))
  326. pid_t getpgid(pid_t pid)
  327. {
  328. return __sysret(sys_getpgid(pid));
  329. }
  330. /*
  331. * pid_t getpgrp(void);
  332. */
  333. static __attribute__((unused))
  334. pid_t sys_getpgrp(void)
  335. {
  336. return sys_getpgid(0);
  337. }
  338. static __attribute__((unused))
  339. pid_t getpgrp(void)
  340. {
  341. return sys_getpgrp();
  342. }
  343. /*
  344. * pid_t getpid(void);
  345. */
  346. static __attribute__((unused))
  347. pid_t sys_getpid(void)
  348. {
  349. return my_syscall0(__NR_getpid);
  350. }
  351. static __attribute__((unused))
  352. pid_t getpid(void)
  353. {
  354. return sys_getpid();
  355. }
  356. /*
  357. * pid_t getppid(void);
  358. */
  359. static __attribute__((unused))
  360. pid_t sys_getppid(void)
  361. {
  362. return my_syscall0(__NR_getppid);
  363. }
  364. static __attribute__((unused))
  365. pid_t getppid(void)
  366. {
  367. return sys_getppid();
  368. }
  369. /*
  370. * pid_t gettid(void);
  371. */
  372. static __attribute__((unused))
  373. pid_t sys_gettid(void)
  374. {
  375. return my_syscall0(__NR_gettid);
  376. }
  377. static __attribute__((unused))
  378. pid_t gettid(void)
  379. {
  380. return sys_gettid();
  381. }
  382. static unsigned long getauxval(unsigned long key);
  383. /*
  384. * int getpagesize(void);
  385. */
  386. static __attribute__((unused))
  387. int getpagesize(void)
  388. {
  389. return __sysret((int)getauxval(AT_PAGESZ) ?: -ENOENT);
  390. }
  391. /*
  392. * int gettimeofday(struct timeval *tv, struct timezone *tz);
  393. */
  394. static __attribute__((unused))
  395. int sys_gettimeofday(struct timeval *tv, struct timezone *tz)
  396. {
  397. #ifdef __NR_gettimeofday
  398. return my_syscall2(__NR_gettimeofday, tv, tz);
  399. #else
  400. return __nolibc_enosys(__func__, tv, tz);
  401. #endif
  402. }
  403. static __attribute__((unused))
  404. int gettimeofday(struct timeval *tv, struct timezone *tz)
  405. {
  406. return __sysret(sys_gettimeofday(tv, tz));
  407. }
  408. /*
  409. * uid_t getuid(void);
  410. */
  411. static __attribute__((unused))
  412. uid_t sys_getuid(void)
  413. {
  414. #ifdef __NR_getuid32
  415. return my_syscall0(__NR_getuid32);
  416. #else
  417. return my_syscall0(__NR_getuid);
  418. #endif
  419. }
  420. static __attribute__((unused))
  421. uid_t getuid(void)
  422. {
  423. return sys_getuid();
  424. }
  425. /*
  426. * int ioctl(int fd, unsigned long req, void *value);
  427. */
  428. static __attribute__((unused))
  429. int sys_ioctl(int fd, unsigned long req, void *value)
  430. {
  431. return my_syscall3(__NR_ioctl, fd, req, value);
  432. }
  433. static __attribute__((unused))
  434. int ioctl(int fd, unsigned long req, void *value)
  435. {
  436. return __sysret(sys_ioctl(fd, req, value));
  437. }
  438. /*
  439. * int kill(pid_t pid, int signal);
  440. */
  441. static __attribute__((unused))
  442. int sys_kill(pid_t pid, int signal)
  443. {
  444. return my_syscall2(__NR_kill, pid, signal);
  445. }
  446. static __attribute__((unused))
  447. int kill(pid_t pid, int signal)
  448. {
  449. return __sysret(sys_kill(pid, signal));
  450. }
  451. /*
  452. * int link(const char *old, const char *new);
  453. */
  454. static __attribute__((unused))
  455. int sys_link(const char *old, const char *new)
  456. {
  457. #ifdef __NR_linkat
  458. return my_syscall5(__NR_linkat, AT_FDCWD, old, AT_FDCWD, new, 0);
  459. #elif defined(__NR_link)
  460. return my_syscall2(__NR_link, old, new);
  461. #else
  462. return __nolibc_enosys(__func__, old, new);
  463. #endif
  464. }
  465. static __attribute__((unused))
  466. int link(const char *old, const char *new)
  467. {
  468. return __sysret(sys_link(old, new));
  469. }
  470. /*
  471. * off_t lseek(int fd, off_t offset, int whence);
  472. */
  473. static __attribute__((unused))
  474. off_t sys_lseek(int fd, off_t offset, int whence)
  475. {
  476. #ifdef __NR_lseek
  477. return my_syscall3(__NR_lseek, fd, offset, whence);
  478. #else
  479. return __nolibc_enosys(__func__, fd, offset, whence);
  480. #endif
  481. }
  482. static __attribute__((unused))
  483. off_t lseek(int fd, off_t offset, int whence)
  484. {
  485. return __sysret(sys_lseek(fd, offset, whence));
  486. }
  487. /*
  488. * int mkdir(const char *path, mode_t mode);
  489. */
  490. static __attribute__((unused))
  491. int sys_mkdir(const char *path, mode_t mode)
  492. {
  493. #ifdef __NR_mkdirat
  494. return my_syscall3(__NR_mkdirat, AT_FDCWD, path, mode);
  495. #elif defined(__NR_mkdir)
  496. return my_syscall2(__NR_mkdir, path, mode);
  497. #else
  498. return __nolibc_enosys(__func__, path, mode);
  499. #endif
  500. }
  501. static __attribute__((unused))
  502. int mkdir(const char *path, mode_t mode)
  503. {
  504. return __sysret(sys_mkdir(path, mode));
  505. }
  506. /*
  507. * int rmdir(const char *path);
  508. */
  509. static __attribute__((unused))
  510. int sys_rmdir(const char *path)
  511. {
  512. #ifdef __NR_rmdir
  513. return my_syscall1(__NR_rmdir, path);
  514. #elif defined(__NR_unlinkat)
  515. return my_syscall3(__NR_unlinkat, AT_FDCWD, path, AT_REMOVEDIR);
  516. #else
  517. return __nolibc_enosys(__func__, path);
  518. #endif
  519. }
  520. static __attribute__((unused))
  521. int rmdir(const char *path)
  522. {
  523. return __sysret(sys_rmdir(path));
  524. }
  525. /*
  526. * int mknod(const char *path, mode_t mode, dev_t dev);
  527. */
  528. static __attribute__((unused))
  529. long sys_mknod(const char *path, mode_t mode, dev_t dev)
  530. {
  531. #ifdef __NR_mknodat
  532. return my_syscall4(__NR_mknodat, AT_FDCWD, path, mode, dev);
  533. #elif defined(__NR_mknod)
  534. return my_syscall3(__NR_mknod, path, mode, dev);
  535. #else
  536. return __nolibc_enosys(__func__, path, mode, dev);
  537. #endif
  538. }
  539. static __attribute__((unused))
  540. int mknod(const char *path, mode_t mode, dev_t dev)
  541. {
  542. return __sysret(sys_mknod(path, mode, dev));
  543. }
  544. #ifndef sys_mmap
  545. static __attribute__((unused))
  546. void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd,
  547. off_t offset)
  548. {
  549. int n;
  550. #if defined(__NR_mmap2)
  551. n = __NR_mmap2;
  552. offset >>= 12;
  553. #else
  554. n = __NR_mmap;
  555. #endif
  556. return (void *)my_syscall6(n, addr, length, prot, flags, fd, offset);
  557. }
  558. #endif
  559. /* Note that on Linux, MAP_FAILED is -1 so we can use the generic __sysret()
  560. * which returns -1 upon error and still satisfy user land that checks for
  561. * MAP_FAILED.
  562. */
  563. static __attribute__((unused))
  564. void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
  565. {
  566. void *ret = sys_mmap(addr, length, prot, flags, fd, offset);
  567. if ((unsigned long)ret >= -4095UL) {
  568. SET_ERRNO(-(long)ret);
  569. ret = MAP_FAILED;
  570. }
  571. return ret;
  572. }
  573. static __attribute__((unused))
  574. int sys_munmap(void *addr, size_t length)
  575. {
  576. return my_syscall2(__NR_munmap, addr, length);
  577. }
  578. static __attribute__((unused))
  579. int munmap(void *addr, size_t length)
  580. {
  581. return __sysret(sys_munmap(addr, length));
  582. }
  583. /*
  584. * int mount(const char *source, const char *target,
  585. * const char *fstype, unsigned long flags,
  586. * const void *data);
  587. */
  588. static __attribute__((unused))
  589. int sys_mount(const char *src, const char *tgt, const char *fst,
  590. unsigned long flags, const void *data)
  591. {
  592. return my_syscall5(__NR_mount, src, tgt, fst, flags, data);
  593. }
  594. static __attribute__((unused))
  595. int mount(const char *src, const char *tgt,
  596. const char *fst, unsigned long flags,
  597. const void *data)
  598. {
  599. return __sysret(sys_mount(src, tgt, fst, flags, data));
  600. }
  601. /*
  602. * int open(const char *path, int flags[, mode_t mode]);
  603. */
  604. static __attribute__((unused))
  605. int sys_open(const char *path, int flags, mode_t mode)
  606. {
  607. #ifdef __NR_openat
  608. return my_syscall4(__NR_openat, AT_FDCWD, path, flags, mode);
  609. #elif defined(__NR_open)
  610. return my_syscall3(__NR_open, path, flags, mode);
  611. #else
  612. return __nolibc_enosys(__func__, path, flags, mode);
  613. #endif
  614. }
  615. static __attribute__((unused))
  616. int open(const char *path, int flags, ...)
  617. {
  618. mode_t mode = 0;
  619. if (flags & O_CREAT) {
  620. va_list args;
  621. va_start(args, flags);
  622. mode = va_arg(args, int);
  623. va_end(args);
  624. }
  625. return __sysret(sys_open(path, flags, mode));
  626. }
  627. /*
  628. * int pipe2(int pipefd[2], int flags);
  629. * int pipe(int pipefd[2]);
  630. */
  631. static __attribute__((unused))
  632. int sys_pipe2(int pipefd[2], int flags)
  633. {
  634. return my_syscall2(__NR_pipe2, pipefd, flags);
  635. }
  636. static __attribute__((unused))
  637. int pipe2(int pipefd[2], int flags)
  638. {
  639. return __sysret(sys_pipe2(pipefd, flags));
  640. }
  641. static __attribute__((unused))
  642. int pipe(int pipefd[2])
  643. {
  644. return pipe2(pipefd, 0);
  645. }
  646. /*
  647. * int prctl(int option, unsigned long arg2, unsigned long arg3,
  648. * unsigned long arg4, unsigned long arg5);
  649. */
  650. static __attribute__((unused))
  651. int sys_prctl(int option, unsigned long arg2, unsigned long arg3,
  652. unsigned long arg4, unsigned long arg5)
  653. {
  654. return my_syscall5(__NR_prctl, option, arg2, arg3, arg4, arg5);
  655. }
  656. static __attribute__((unused))
  657. int prctl(int option, unsigned long arg2, unsigned long arg3,
  658. unsigned long arg4, unsigned long arg5)
  659. {
  660. return __sysret(sys_prctl(option, arg2, arg3, arg4, arg5));
  661. }
  662. /*
  663. * int pivot_root(const char *new, const char *old);
  664. */
  665. static __attribute__((unused))
  666. int sys_pivot_root(const char *new, const char *old)
  667. {
  668. return my_syscall2(__NR_pivot_root, new, old);
  669. }
  670. static __attribute__((unused))
  671. int pivot_root(const char *new, const char *old)
  672. {
  673. return __sysret(sys_pivot_root(new, old));
  674. }
  675. /*
  676. * int poll(struct pollfd *fds, int nfds, int timeout);
  677. */
  678. static __attribute__((unused))
  679. int sys_poll(struct pollfd *fds, int nfds, int timeout)
  680. {
  681. #if defined(__NR_ppoll)
  682. struct timespec t;
  683. if (timeout >= 0) {
  684. t.tv_sec = timeout / 1000;
  685. t.tv_nsec = (timeout % 1000) * 1000000;
  686. }
  687. return my_syscall5(__NR_ppoll, fds, nfds, (timeout >= 0) ? &t : NULL, NULL, 0);
  688. #elif defined(__NR_poll)
  689. return my_syscall3(__NR_poll, fds, nfds, timeout);
  690. #else
  691. return __nolibc_enosys(__func__, fds, nfds, timeout);
  692. #endif
  693. }
  694. static __attribute__((unused))
  695. int poll(struct pollfd *fds, int nfds, int timeout)
  696. {
  697. return __sysret(sys_poll(fds, nfds, timeout));
  698. }
  699. /*
  700. * ssize_t read(int fd, void *buf, size_t count);
  701. */
  702. static __attribute__((unused))
  703. ssize_t sys_read(int fd, void *buf, size_t count)
  704. {
  705. return my_syscall3(__NR_read, fd, buf, count);
  706. }
  707. static __attribute__((unused))
  708. ssize_t read(int fd, void *buf, size_t count)
  709. {
  710. return __sysret(sys_read(fd, buf, count));
  711. }
  712. /*
  713. * int reboot(int cmd);
  714. * <cmd> is among LINUX_REBOOT_CMD_*
  715. */
  716. static __attribute__((unused))
  717. ssize_t sys_reboot(int magic1, int magic2, int cmd, void *arg)
  718. {
  719. return my_syscall4(__NR_reboot, magic1, magic2, cmd, arg);
  720. }
  721. static __attribute__((unused))
  722. int reboot(int cmd)
  723. {
  724. return __sysret(sys_reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, 0));
  725. }
  726. /*
  727. * int getrlimit(int resource, struct rlimit *rlim);
  728. * int setrlimit(int resource, const struct rlimit *rlim);
  729. */
  730. static __attribute__((unused))
  731. int sys_prlimit64(pid_t pid, int resource,
  732. const struct rlimit64 *new_limit, struct rlimit64 *old_limit)
  733. {
  734. return my_syscall4(__NR_prlimit64, pid, resource, new_limit, old_limit);
  735. }
  736. static __attribute__((unused))
  737. int getrlimit(int resource, struct rlimit *rlim)
  738. {
  739. struct rlimit64 rlim64;
  740. int ret;
  741. ret = __sysret(sys_prlimit64(0, resource, NULL, &rlim64));
  742. rlim->rlim_cur = rlim64.rlim_cur;
  743. rlim->rlim_max = rlim64.rlim_max;
  744. return ret;
  745. }
  746. static __attribute__((unused))
  747. int setrlimit(int resource, const struct rlimit *rlim)
  748. {
  749. struct rlimit64 rlim64 = {
  750. .rlim_cur = rlim->rlim_cur,
  751. .rlim_max = rlim->rlim_max,
  752. };
  753. return __sysret(sys_prlimit64(0, resource, &rlim64, NULL));
  754. }
  755. /*
  756. * int sched_yield(void);
  757. */
  758. static __attribute__((unused))
  759. int sys_sched_yield(void)
  760. {
  761. return my_syscall0(__NR_sched_yield);
  762. }
  763. static __attribute__((unused))
  764. int sched_yield(void)
  765. {
  766. return __sysret(sys_sched_yield());
  767. }
  768. /*
  769. * int select(int nfds, fd_set *read_fds, fd_set *write_fds,
  770. * fd_set *except_fds, struct timeval *timeout);
  771. */
  772. static __attribute__((unused))
  773. int sys_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout)
  774. {
  775. #if defined(__ARCH_WANT_SYS_OLD_SELECT) && !defined(__NR__newselect)
  776. struct sel_arg_struct {
  777. unsigned long n;
  778. fd_set *r, *w, *e;
  779. struct timeval *t;
  780. } arg = { .n = nfds, .r = rfds, .w = wfds, .e = efds, .t = timeout };
  781. return my_syscall1(__NR_select, &arg);
  782. #elif defined(__NR__newselect)
  783. return my_syscall5(__NR__newselect, nfds, rfds, wfds, efds, timeout);
  784. #elif defined(__NR_select)
  785. return my_syscall5(__NR_select, nfds, rfds, wfds, efds, timeout);
  786. #elif defined(__NR_pselect6)
  787. struct timespec t;
  788. if (timeout) {
  789. t.tv_sec = timeout->tv_sec;
  790. t.tv_nsec = timeout->tv_usec * 1000;
  791. }
  792. return my_syscall6(__NR_pselect6, nfds, rfds, wfds, efds, timeout ? &t : NULL, NULL);
  793. #else
  794. return __nolibc_enosys(__func__, nfds, rfds, wfds, efds, timeout);
  795. #endif
  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. * int setpgid(pid_t pid, pid_t pgid);
  804. */
  805. static __attribute__((unused))
  806. int sys_setpgid(pid_t pid, pid_t pgid)
  807. {
  808. return my_syscall2(__NR_setpgid, pid, pgid);
  809. }
  810. static __attribute__((unused))
  811. int setpgid(pid_t pid, pid_t pgid)
  812. {
  813. return __sysret(sys_setpgid(pid, pgid));
  814. }
  815. /*
  816. * pid_t setsid(void);
  817. */
  818. static __attribute__((unused))
  819. pid_t sys_setsid(void)
  820. {
  821. return my_syscall0(__NR_setsid);
  822. }
  823. static __attribute__((unused))
  824. pid_t setsid(void)
  825. {
  826. return __sysret(sys_setsid());
  827. }
  828. /*
  829. * int statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf);
  830. * int stat(const char *path, struct stat *buf);
  831. */
  832. static __attribute__((unused))
  833. int sys_statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf)
  834. {
  835. #ifdef __NR_statx
  836. return my_syscall5(__NR_statx, fd, path, flags, mask, buf);
  837. #else
  838. return __nolibc_enosys(__func__, fd, path, flags, mask, buf);
  839. #endif
  840. }
  841. static __attribute__((unused))
  842. int statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf)
  843. {
  844. return __sysret(sys_statx(fd, path, flags, mask, buf));
  845. }
  846. static __attribute__((unused))
  847. int stat(const char *path, struct stat *buf)
  848. {
  849. struct statx statx;
  850. long ret;
  851. ret = __sysret(sys_statx(AT_FDCWD, path, AT_NO_AUTOMOUNT, STATX_BASIC_STATS, &statx));
  852. if (ret == -1)
  853. return ret;
  854. buf->st_dev = ((statx.stx_dev_minor & 0xff)
  855. | (statx.stx_dev_major << 8)
  856. | ((statx.stx_dev_minor & ~0xff) << 12));
  857. buf->st_ino = statx.stx_ino;
  858. buf->st_mode = statx.stx_mode;
  859. buf->st_nlink = statx.stx_nlink;
  860. buf->st_uid = statx.stx_uid;
  861. buf->st_gid = statx.stx_gid;
  862. buf->st_rdev = ((statx.stx_rdev_minor & 0xff)
  863. | (statx.stx_rdev_major << 8)
  864. | ((statx.stx_rdev_minor & ~0xff) << 12));
  865. buf->st_size = statx.stx_size;
  866. buf->st_blksize = statx.stx_blksize;
  867. buf->st_blocks = statx.stx_blocks;
  868. buf->st_atim.tv_sec = statx.stx_atime.tv_sec;
  869. buf->st_atim.tv_nsec = statx.stx_atime.tv_nsec;
  870. buf->st_mtim.tv_sec = statx.stx_mtime.tv_sec;
  871. buf->st_mtim.tv_nsec = statx.stx_mtime.tv_nsec;
  872. buf->st_ctim.tv_sec = statx.stx_ctime.tv_sec;
  873. buf->st_ctim.tv_nsec = statx.stx_ctime.tv_nsec;
  874. return 0;
  875. }
  876. /*
  877. * int symlink(const char *old, const char *new);
  878. */
  879. static __attribute__((unused))
  880. int sys_symlink(const char *old, const char *new)
  881. {
  882. #ifdef __NR_symlinkat
  883. return my_syscall3(__NR_symlinkat, old, AT_FDCWD, new);
  884. #elif defined(__NR_symlink)
  885. return my_syscall2(__NR_symlink, old, new);
  886. #else
  887. return __nolibc_enosys(__func__, old, new);
  888. #endif
  889. }
  890. static __attribute__((unused))
  891. int symlink(const char *old, const char *new)
  892. {
  893. return __sysret(sys_symlink(old, new));
  894. }
  895. /*
  896. * mode_t umask(mode_t mode);
  897. */
  898. static __attribute__((unused))
  899. mode_t sys_umask(mode_t mode)
  900. {
  901. return my_syscall1(__NR_umask, mode);
  902. }
  903. static __attribute__((unused))
  904. mode_t umask(mode_t mode)
  905. {
  906. return sys_umask(mode);
  907. }
  908. /*
  909. * int umount2(const char *path, int flags);
  910. */
  911. static __attribute__((unused))
  912. int sys_umount2(const char *path, int flags)
  913. {
  914. return my_syscall2(__NR_umount2, path, flags);
  915. }
  916. static __attribute__((unused))
  917. int umount2(const char *path, int flags)
  918. {
  919. return __sysret(sys_umount2(path, flags));
  920. }
  921. /*
  922. * int uname(struct utsname *buf);
  923. */
  924. struct utsname {
  925. char sysname[65];
  926. char nodename[65];
  927. char release[65];
  928. char version[65];
  929. char machine[65];
  930. char domainname[65];
  931. };
  932. static __attribute__((unused))
  933. int sys_uname(struct utsname *buf)
  934. {
  935. return my_syscall1(__NR_uname, buf);
  936. }
  937. static __attribute__((unused))
  938. int uname(struct utsname *buf)
  939. {
  940. return __sysret(sys_uname(buf));
  941. }
  942. /*
  943. * int unlink(const char *path);
  944. */
  945. static __attribute__((unused))
  946. int sys_unlink(const char *path)
  947. {
  948. #ifdef __NR_unlinkat
  949. return my_syscall3(__NR_unlinkat, AT_FDCWD, path, 0);
  950. #elif defined(__NR_unlink)
  951. return my_syscall1(__NR_unlink, path);
  952. #else
  953. return __nolibc_enosys(__func__, path);
  954. #endif
  955. }
  956. static __attribute__((unused))
  957. int unlink(const char *path)
  958. {
  959. return __sysret(sys_unlink(path));
  960. }
  961. /*
  962. * pid_t wait(int *status);
  963. * pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage);
  964. * pid_t waitpid(pid_t pid, int *status, int options);
  965. */
  966. static __attribute__((unused))
  967. pid_t sys_wait4(pid_t pid, int *status, int options, struct rusage *rusage)
  968. {
  969. #ifdef __NR_wait4
  970. return my_syscall4(__NR_wait4, pid, status, options, rusage);
  971. #else
  972. return __nolibc_enosys(__func__, pid, status, options, rusage);
  973. #endif
  974. }
  975. static __attribute__((unused))
  976. pid_t wait(int *status)
  977. {
  978. return __sysret(sys_wait4(-1, status, 0, NULL));
  979. }
  980. static __attribute__((unused))
  981. pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage)
  982. {
  983. return __sysret(sys_wait4(pid, status, options, rusage));
  984. }
  985. static __attribute__((unused))
  986. pid_t waitpid(pid_t pid, int *status, int options)
  987. {
  988. return __sysret(sys_wait4(pid, status, options, NULL));
  989. }
  990. /*
  991. * ssize_t write(int fd, const void *buf, size_t count);
  992. */
  993. static __attribute__((unused))
  994. ssize_t sys_write(int fd, const void *buf, size_t count)
  995. {
  996. return my_syscall3(__NR_write, fd, buf, count);
  997. }
  998. static __attribute__((unused))
  999. ssize_t write(int fd, const void *buf, size_t count)
  1000. {
  1001. return __sysret(sys_write(fd, buf, count));
  1002. }
  1003. /*
  1004. * int memfd_create(const char *name, unsigned int flags);
  1005. */
  1006. static __attribute__((unused))
  1007. int sys_memfd_create(const char *name, unsigned int flags)
  1008. {
  1009. return my_syscall2(__NR_memfd_create, name, flags);
  1010. }
  1011. static __attribute__((unused))
  1012. int memfd_create(const char *name, unsigned int flags)
  1013. {
  1014. return __sysret(sys_memfd_create(name, flags));
  1015. }
  1016. /* make sure to include all global symbols */
  1017. #include "nolibc.h"
  1018. #endif /* _NOLIBC_SYS_H */