sys.h 22 KB

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