System.cpp 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087
  1. /*
  2. * Copyright (c) 2021-2022, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2021, Kenneth Myhra <kennethmyhra@gmail.com>
  4. * Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
  5. * Copyright (c) 2022, Matthias Zimmerman <matthias291999@gmail.com>
  6. *
  7. * SPDX-License-Identifier: BSD-2-Clause
  8. */
  9. #include <AK/StdLibExtras.h>
  10. #include <AK/String.h>
  11. #include <AK/Vector.h>
  12. #include <LibCore/System.h>
  13. #include <LibSystem/syscall.h>
  14. #include <limits.h>
  15. #include <stdarg.h>
  16. #include <stdlib.h>
  17. #include <sys/ioctl.h>
  18. #include <sys/mman.h>
  19. #include <sys/ptrace.h>
  20. #include <sys/time.h>
  21. #include <termios.h>
  22. #include <unistd.h>
  23. #ifdef __serenity__
  24. # include <serenity.h>
  25. #endif
  26. #if defined(__linux__) && !defined(MFD_CLOEXEC)
  27. # include <linux/memfd.h>
  28. # include <sys/syscall.h>
  29. static int memfd_create(const char* name, unsigned int flags)
  30. {
  31. return syscall(SYS_memfd_create, name, flags);
  32. }
  33. #endif
  34. #if defined(__APPLE__)
  35. # include <sys/mman.h>
  36. #endif
  37. #define HANDLE_SYSCALL_RETURN_VALUE(syscall_name, rc, success_value) \
  38. if ((rc) < 0) { \
  39. return Error::from_syscall(syscall_name, rc); \
  40. } \
  41. return success_value;
  42. namespace Core::System {
  43. #ifndef HOST_NAME_MAX
  44. # ifdef __APPLE__
  45. # define HOST_NAME_MAX 255
  46. # else
  47. # define HOST_NAME_MAX 64
  48. # endif
  49. #endif
  50. #ifdef __serenity__
  51. ErrorOr<void> beep()
  52. {
  53. auto rc = ::sysbeep();
  54. if (rc < 0)
  55. return Error::from_syscall("beep"sv, -errno);
  56. return {};
  57. }
  58. ErrorOr<void> pledge(StringView promises, StringView execpromises)
  59. {
  60. Syscall::SC_pledge_params params {
  61. { promises.characters_without_null_termination(), promises.length() },
  62. { execpromises.characters_without_null_termination(), execpromises.length() },
  63. };
  64. int rc = syscall(SC_pledge, &params);
  65. HANDLE_SYSCALL_RETURN_VALUE("pledge"sv, rc, {});
  66. }
  67. ErrorOr<void> unveil(StringView path, StringView permissions)
  68. {
  69. Syscall::SC_unveil_params params {
  70. { path.characters_without_null_termination(), path.length() },
  71. { permissions.characters_without_null_termination(), permissions.length() },
  72. };
  73. int rc = syscall(SC_unveil, &params);
  74. HANDLE_SYSCALL_RETURN_VALUE("unveil"sv, rc, {});
  75. }
  76. ErrorOr<void> sendfd(int sockfd, int fd)
  77. {
  78. if (::sendfd(sockfd, fd) < 0)
  79. return Error::from_syscall("sendfd"sv, -errno);
  80. return {};
  81. }
  82. ErrorOr<int> recvfd(int sockfd, int options)
  83. {
  84. auto fd = ::recvfd(sockfd, options);
  85. if (fd < 0)
  86. return Error::from_syscall("recvfd"sv, -errno);
  87. return fd;
  88. }
  89. ErrorOr<void> ptrace_peekbuf(pid_t tid, void const* tracee_addr, Bytes destination_buf)
  90. {
  91. Syscall::SC_ptrace_buf_params buf_params {
  92. { destination_buf.data(), destination_buf.size() }
  93. };
  94. Syscall::SC_ptrace_params params {
  95. PT_PEEKBUF,
  96. tid,
  97. const_cast<void*>(tracee_addr),
  98. (FlatPtr)&buf_params,
  99. };
  100. int rc = syscall(SC_ptrace, &params);
  101. HANDLE_SYSCALL_RETURN_VALUE("ptrace_peekbuf", rc, {});
  102. }
  103. ErrorOr<void> setgroups(Span<gid_t const> gids)
  104. {
  105. if (::setgroups(gids.size(), gids.data()) < 0)
  106. return Error::from_syscall("setgroups"sv, -errno);
  107. return {};
  108. }
  109. ErrorOr<void> mount(int source_fd, StringView target, StringView fs_type, int flags)
  110. {
  111. if (target.is_null() || fs_type.is_null())
  112. return Error::from_errno(EFAULT);
  113. Syscall::SC_mount_params params {
  114. { target.characters_without_null_termination(), target.length() },
  115. { fs_type.characters_without_null_termination(), fs_type.length() },
  116. source_fd,
  117. flags
  118. };
  119. int rc = syscall(SC_mount, &params);
  120. HANDLE_SYSCALL_RETURN_VALUE("mount", rc, {});
  121. }
  122. ErrorOr<void> umount(StringView mount_point)
  123. {
  124. if (mount_point.is_null())
  125. return Error::from_errno(EFAULT);
  126. int rc = syscall(SC_umount, mount_point.characters_without_null_termination(), mount_point.length());
  127. HANDLE_SYSCALL_RETURN_VALUE("umount", rc, {});
  128. }
  129. ErrorOr<long> ptrace(int request, pid_t tid, void* address, void* data)
  130. {
  131. auto rc = ::ptrace(request, tid, address, data);
  132. if (rc < 0)
  133. return Error::from_syscall("ptrace"sv, -errno);
  134. return rc;
  135. }
  136. ErrorOr<void> disown(pid_t pid)
  137. {
  138. int rc = ::disown(pid);
  139. HANDLE_SYSCALL_RETURN_VALUE("disown", rc, {});
  140. }
  141. ErrorOr<void> profiling_enable(pid_t pid, u64 event_mask)
  142. {
  143. int rc = ::profiling_enable(pid, event_mask);
  144. HANDLE_SYSCALL_RETURN_VALUE("profiling_enable", rc, {});
  145. }
  146. ErrorOr<void> profiling_disable(pid_t pid)
  147. {
  148. int rc = ::profiling_disable(pid);
  149. HANDLE_SYSCALL_RETURN_VALUE("profiling_disable", rc, {});
  150. }
  151. ErrorOr<void> profiling_free_buffer(pid_t pid)
  152. {
  153. int rc = ::profiling_free_buffer(pid);
  154. HANDLE_SYSCALL_RETURN_VALUE("profiling_free_buffer", rc, {});
  155. }
  156. #endif
  157. #ifndef AK_OS_BSD_GENERIC
  158. ErrorOr<Optional<struct spwd>> getspent()
  159. {
  160. errno = 0;
  161. if (auto* spwd = ::getspent())
  162. return *spwd;
  163. if (errno)
  164. return Error::from_syscall("getspent"sv, -errno);
  165. return Optional<struct spwd> {};
  166. }
  167. ErrorOr<Optional<struct spwd>> getspnam(StringView name)
  168. {
  169. errno = 0;
  170. ::setspent();
  171. while (auto* spwd = ::getspent()) {
  172. if (spwd->sp_namp == name)
  173. return *spwd;
  174. }
  175. if (errno)
  176. return Error::from_syscall("getspnam"sv, -errno);
  177. return Optional<struct spwd> {};
  178. }
  179. #endif
  180. #ifndef AK_OS_MACOS
  181. ErrorOr<int> accept4(int sockfd, sockaddr* address, socklen_t* address_length, int flags)
  182. {
  183. auto fd = ::accept4(sockfd, address, address_length, flags);
  184. if (fd < 0)
  185. return Error::from_syscall("accept4"sv, -errno);
  186. return fd;
  187. }
  188. #endif
  189. ErrorOr<void> sigaction(int signal, struct sigaction const* action, struct sigaction* old_action)
  190. {
  191. if (::sigaction(signal, action, old_action) < 0)
  192. return Error::from_syscall("sigaction"sv, -errno);
  193. return {};
  194. }
  195. #if defined(__APPLE__) || defined(__OpenBSD__) || defined(__FreeBSD__)
  196. ErrorOr<sig_t> signal(int signal, sig_t handler)
  197. #else
  198. ErrorOr<sighandler_t> signal(int signal, sighandler_t handler)
  199. #endif
  200. {
  201. auto old_handler = ::signal(signal, handler);
  202. if (old_handler == SIG_ERR)
  203. return Error::from_syscall("signal"sv, -errno);
  204. return old_handler;
  205. }
  206. ErrorOr<struct stat> fstat(int fd)
  207. {
  208. struct stat st = {};
  209. if (::fstat(fd, &st) < 0)
  210. return Error::from_syscall("fstat"sv, -errno);
  211. return st;
  212. }
  213. ErrorOr<int> fcntl(int fd, int command, ...)
  214. {
  215. va_list ap;
  216. va_start(ap, command);
  217. u32 extra_arg = va_arg(ap, u32);
  218. int rc = ::fcntl(fd, command, extra_arg);
  219. va_end(ap);
  220. if (rc < 0)
  221. return Error::from_syscall("fcntl"sv, -errno);
  222. return rc;
  223. }
  224. ErrorOr<void*> mmap(void* address, size_t size, int protection, int flags, int fd, off_t offset, [[maybe_unused]] size_t alignment, [[maybe_unused]] StringView name)
  225. {
  226. #ifdef __serenity__
  227. Syscall::SC_mmap_params params { address, size, alignment, protection, flags, fd, offset, { name.characters_without_null_termination(), name.length() } };
  228. ptrdiff_t rc = syscall(SC_mmap, &params);
  229. if (rc < 0 && rc > -EMAXERRNO)
  230. return Error::from_syscall("mmap"sv, rc);
  231. return reinterpret_cast<void*>(rc);
  232. #else
  233. // NOTE: Regular POSIX mmap() doesn't support custom alignment requests.
  234. VERIFY(!alignment);
  235. auto* ptr = ::mmap(address, size, protection, flags, fd, offset);
  236. if (ptr == MAP_FAILED)
  237. return Error::from_syscall("mmap"sv, -errno);
  238. return ptr;
  239. #endif
  240. }
  241. ErrorOr<void> munmap(void* address, size_t size)
  242. {
  243. if (::munmap(address, size) < 0)
  244. return Error::from_syscall("munmap"sv, -errno);
  245. return {};
  246. }
  247. ErrorOr<int> anon_create([[maybe_unused]] size_t size, [[maybe_unused]] int options)
  248. {
  249. int fd = -1;
  250. #if defined(__serenity__)
  251. fd = ::anon_create(round_up_to_power_of_two(size, PAGE_SIZE), options);
  252. #elif defined(__linux__)
  253. // FIXME: Support more options on Linux.
  254. auto linux_options = ((options & O_CLOEXEC) > 0) ? MFD_CLOEXEC : 0;
  255. fd = memfd_create("", linux_options);
  256. if (fd < 0)
  257. return Error::from_errno(errno);
  258. if (::ftruncate(fd, size) < 0) {
  259. auto saved_errno = errno;
  260. TRY(close(fd));
  261. return Error::from_errno(saved_errno);
  262. }
  263. #elif defined(__APPLE__)
  264. struct timespec time;
  265. clock_gettime(CLOCK_REALTIME, &time);
  266. auto name = String::formatted("/shm-{}{}", (unsigned long)time.tv_sec, (unsigned long)time.tv_nsec);
  267. fd = shm_open(name.characters(), O_RDWR | O_CREAT | options, 0600);
  268. if (shm_unlink(name.characters()) == -1) {
  269. auto saved_errno = errno;
  270. TRY(close(fd));
  271. return Error::from_errno(saved_errno);
  272. }
  273. if (fd < 0)
  274. return Error::from_errno(errno);
  275. if (::ftruncate(fd, size) < 0) {
  276. auto saved_errno = errno;
  277. TRY(close(fd));
  278. return Error::from_errno(saved_errno);
  279. }
  280. void* addr = ::mmap(NULL, size, PROT_WRITE, MAP_SHARED, fd, 0);
  281. if (addr == MAP_FAILED) {
  282. auto saved_errno = errno;
  283. TRY(close(fd));
  284. return Error::from_errno(saved_errno);
  285. }
  286. #endif
  287. if (fd < 0)
  288. return Error::from_errno(errno);
  289. return fd;
  290. }
  291. ErrorOr<int> open(StringView path, int options, ...)
  292. {
  293. if (!path.characters_without_null_termination())
  294. return Error::from_syscall("open"sv, -EFAULT);
  295. va_list ap;
  296. va_start(ap, options);
  297. auto mode = (mode_t)va_arg(ap, unsigned);
  298. va_end(ap);
  299. #ifdef __serenity__
  300. Syscall::SC_open_params params { AT_FDCWD, { path.characters_without_null_termination(), path.length() }, options, mode };
  301. int rc = syscall(SC_open, &params);
  302. HANDLE_SYSCALL_RETURN_VALUE("open"sv, rc, rc);
  303. #else
  304. // NOTE: We have to ensure that the path is null-terminated.
  305. String path_string = path;
  306. int rc = ::open(path_string.characters(), options, mode);
  307. if (rc < 0)
  308. return Error::from_syscall("open"sv, -errno);
  309. return rc;
  310. #endif
  311. }
  312. ErrorOr<void> close(int fd)
  313. {
  314. if (::close(fd) < 0)
  315. return Error::from_syscall("close"sv, -errno);
  316. return {};
  317. }
  318. ErrorOr<void> ftruncate(int fd, off_t length)
  319. {
  320. if (::ftruncate(fd, length) < 0)
  321. return Error::from_syscall("ftruncate"sv, -errno);
  322. return {};
  323. }
  324. ErrorOr<struct stat> stat(StringView path)
  325. {
  326. if (!path.characters_without_null_termination())
  327. return Error::from_syscall("stat"sv, -EFAULT);
  328. struct stat st = {};
  329. #ifdef __serenity__
  330. Syscall::SC_stat_params params { { path.characters_without_null_termination(), path.length() }, &st, AT_FDCWD, true };
  331. int rc = syscall(SC_stat, &params);
  332. HANDLE_SYSCALL_RETURN_VALUE("stat"sv, rc, st);
  333. #else
  334. String path_string = path;
  335. if (::stat(path_string.characters(), &st) < 0)
  336. return Error::from_syscall("stat"sv, -errno);
  337. return st;
  338. #endif
  339. }
  340. ErrorOr<struct stat> lstat(StringView path)
  341. {
  342. if (!path.characters_without_null_termination())
  343. return Error::from_syscall("lstat"sv, -EFAULT);
  344. struct stat st = {};
  345. #ifdef __serenity__
  346. Syscall::SC_stat_params params { { path.characters_without_null_termination(), path.length() }, &st, AT_FDCWD, false };
  347. int rc = syscall(SC_stat, &params);
  348. HANDLE_SYSCALL_RETURN_VALUE("lstat"sv, rc, st);
  349. #else
  350. String path_string = path;
  351. if (::stat(path_string.characters(), &st) < 0)
  352. return Error::from_syscall("lstat"sv, -errno);
  353. return st;
  354. #endif
  355. }
  356. ErrorOr<ssize_t> read(int fd, Bytes buffer)
  357. {
  358. ssize_t rc = ::read(fd, buffer.data(), buffer.size());
  359. if (rc < 0)
  360. return Error::from_syscall("read"sv, -errno);
  361. return rc;
  362. }
  363. ErrorOr<ssize_t> write(int fd, ReadonlyBytes buffer)
  364. {
  365. ssize_t rc = ::write(fd, buffer.data(), buffer.size());
  366. if (rc < 0)
  367. return Error::from_syscall("write"sv, -errno);
  368. return rc;
  369. }
  370. ErrorOr<void> kill(pid_t pid, int signal)
  371. {
  372. if (::kill(pid, signal) < 0)
  373. return Error::from_syscall("kill"sv, -errno);
  374. return {};
  375. }
  376. ErrorOr<void> killpg(int pgrp, int signal)
  377. {
  378. if (::killpg(pgrp, signal) < 0)
  379. return Error::from_syscall("killpg"sv, -errno);
  380. return {};
  381. }
  382. ErrorOr<int> dup(int source_fd)
  383. {
  384. int fd = ::dup(source_fd);
  385. if (fd < 0)
  386. return Error::from_syscall("dup"sv, -errno);
  387. return fd;
  388. }
  389. ErrorOr<int> dup2(int source_fd, int destination_fd)
  390. {
  391. int fd = ::dup2(source_fd, destination_fd);
  392. if (fd < 0)
  393. return Error::from_syscall("dup2"sv, -errno);
  394. return fd;
  395. }
  396. ErrorOr<String> ptsname(int fd)
  397. {
  398. auto* name = ::ptsname(fd);
  399. if (!name)
  400. return Error::from_syscall("ptsname"sv, -errno);
  401. return String(name);
  402. }
  403. ErrorOr<String> gethostname()
  404. {
  405. char hostname[HOST_NAME_MAX];
  406. int rc = ::gethostname(hostname, sizeof(hostname));
  407. if (rc < 0)
  408. return Error::from_syscall("gethostname"sv, -errno);
  409. return String(&hostname[0]);
  410. }
  411. ErrorOr<void> sethostname(StringView hostname)
  412. {
  413. int rc = ::sethostname(hostname.characters_without_null_termination(), hostname.length());
  414. if (rc < 0)
  415. return Error::from_syscall("sethostname"sv, -errno);
  416. return {};
  417. }
  418. ErrorOr<String> getcwd()
  419. {
  420. auto* cwd = ::getcwd(nullptr, 0);
  421. if (!cwd)
  422. return Error::from_syscall("getcwd"sv, -errno);
  423. String string_cwd(cwd);
  424. free(cwd);
  425. return string_cwd;
  426. }
  427. ErrorOr<void> ioctl(int fd, unsigned request, ...)
  428. {
  429. va_list ap;
  430. va_start(ap, request);
  431. FlatPtr arg = va_arg(ap, FlatPtr);
  432. va_end(ap);
  433. if (::ioctl(fd, request, arg) < 0)
  434. return Error::from_syscall("ioctl"sv, -errno);
  435. return {};
  436. }
  437. ErrorOr<struct termios> tcgetattr(int fd)
  438. {
  439. struct termios ios = {};
  440. if (::tcgetattr(fd, &ios) < 0)
  441. return Error::from_syscall("tcgetattr"sv, -errno);
  442. return ios;
  443. }
  444. ErrorOr<void> tcsetattr(int fd, int optional_actions, struct termios const& ios)
  445. {
  446. if (::tcsetattr(fd, optional_actions, &ios) < 0)
  447. return Error::from_syscall("tcsetattr"sv, -errno);
  448. return {};
  449. }
  450. ErrorOr<int> tcsetpgrp(int fd, pid_t pgrp)
  451. {
  452. int rc = ::tcsetpgrp(fd, pgrp);
  453. if (rc < 0)
  454. return Error::from_syscall("tcsetpgrp"sv, -errno);
  455. return { rc };
  456. }
  457. ErrorOr<void> chmod(StringView pathname, mode_t mode)
  458. {
  459. if (!pathname.characters_without_null_termination())
  460. return Error::from_syscall("chmod"sv, -EFAULT);
  461. #ifdef __serenity__
  462. Syscall::SC_chmod_params params {
  463. AT_FDCWD,
  464. { pathname.characters_without_null_termination(), pathname.length() },
  465. mode,
  466. true
  467. };
  468. int rc = syscall(SC_chmod, &params);
  469. HANDLE_SYSCALL_RETURN_VALUE("chmod"sv, rc, {});
  470. #else
  471. String path = pathname;
  472. if (::chmod(path.characters(), mode) < 0)
  473. return Error::from_syscall("chmod"sv, -errno);
  474. return {};
  475. #endif
  476. }
  477. ErrorOr<void> fchmod(int fd, mode_t mode)
  478. {
  479. if (::fchmod(fd, mode) < 0)
  480. return Error::from_syscall("fchmod"sv, -errno);
  481. return {};
  482. }
  483. ErrorOr<void> fchown(int fd, uid_t uid, gid_t gid)
  484. {
  485. if (::fchown(fd, uid, gid) < 0)
  486. return Error::from_syscall("fchown"sv, -errno);
  487. return {};
  488. }
  489. ErrorOr<void> lchown(StringView pathname, uid_t uid, gid_t gid)
  490. {
  491. if (!pathname.characters_without_null_termination())
  492. return Error::from_syscall("chown"sv, -EFAULT);
  493. #ifdef __serenity__
  494. Syscall::SC_chown_params params = { { pathname.characters_without_null_termination(), pathname.length() }, uid, gid, AT_FDCWD, false };
  495. int rc = syscall(SC_chown, &params);
  496. HANDLE_SYSCALL_RETURN_VALUE("chown"sv, rc, {});
  497. #else
  498. String path = pathname;
  499. if (::chown(path.characters(), uid, gid) < 0)
  500. return Error::from_syscall("chown"sv, -errno);
  501. return {};
  502. #endif
  503. }
  504. ErrorOr<void> chown(StringView pathname, uid_t uid, gid_t gid)
  505. {
  506. if (!pathname.characters_without_null_termination())
  507. return Error::from_syscall("chown"sv, -EFAULT);
  508. #ifdef __serenity__
  509. Syscall::SC_chown_params params = { { pathname.characters_without_null_termination(), pathname.length() }, uid, gid, AT_FDCWD, true };
  510. int rc = syscall(SC_chown, &params);
  511. HANDLE_SYSCALL_RETURN_VALUE("chown"sv, rc, {});
  512. #else
  513. String path = pathname;
  514. if (::lchown(path.characters(), uid, gid) < 0)
  515. return Error::from_syscall("lchown"sv, -errno);
  516. return {};
  517. #endif
  518. }
  519. ErrorOr<Optional<struct passwd>> getpwuid(uid_t uid)
  520. {
  521. errno = 0;
  522. if (auto* pwd = ::getpwuid(uid))
  523. return *pwd;
  524. if (errno)
  525. return Error::from_syscall("getpwuid"sv, -errno);
  526. return Optional<struct passwd> {};
  527. }
  528. ErrorOr<Optional<struct group>> getgrgid(gid_t gid)
  529. {
  530. errno = 0;
  531. if (auto* grp = ::getgrgid(gid))
  532. return *grp;
  533. if (errno)
  534. return Error::from_syscall("getgrgid"sv, -errno);
  535. return Optional<struct group> {};
  536. }
  537. ErrorOr<Optional<struct passwd>> getpwnam(StringView name)
  538. {
  539. errno = 0;
  540. ::setpwent();
  541. if (errno)
  542. return Error::from_syscall("getpwnam"sv, -errno);
  543. while (auto* pw = ::getpwent()) {
  544. if (errno)
  545. return Error::from_syscall("getpwnam"sv, -errno);
  546. if (pw->pw_name == name)
  547. return *pw;
  548. }
  549. if (errno)
  550. return Error::from_syscall("getpwnam"sv, -errno);
  551. else
  552. return Optional<struct passwd> {};
  553. }
  554. ErrorOr<Optional<struct group>> getgrnam(StringView name)
  555. {
  556. errno = 0;
  557. ::setgrent();
  558. if (errno)
  559. return Error::from_syscall("getgrnam"sv, -errno);
  560. while (auto* gr = ::getgrent()) {
  561. if (errno)
  562. return Error::from_syscall("getgrnam"sv, -errno);
  563. if (gr->gr_name == name)
  564. return *gr;
  565. }
  566. if (errno)
  567. return Error::from_syscall("getgrnam"sv, -errno);
  568. else
  569. return Optional<struct group> {};
  570. }
  571. ErrorOr<void> clock_settime(clockid_t clock_id, struct timespec* ts)
  572. {
  573. #ifdef __serenity__
  574. int rc = syscall(SC_clock_settime, clock_id, ts);
  575. HANDLE_SYSCALL_RETURN_VALUE("clocksettime"sv, rc, {});
  576. #else
  577. if (::clock_settime(clock_id, ts) < 0)
  578. return Error::from_syscall("clocksettime"sv, -errno);
  579. return {};
  580. #endif
  581. }
  582. ErrorOr<pid_t> posix_spawnp(StringView const path, posix_spawn_file_actions_t* const file_actions, posix_spawnattr_t* const attr, char* const arguments[], char* const envp[])
  583. {
  584. pid_t child_pid;
  585. if ((errno = ::posix_spawnp(&child_pid, path.to_string().characters(), file_actions, attr, arguments, envp)))
  586. return Error::from_syscall("posix_spawnp"sv, -errno);
  587. return child_pid;
  588. }
  589. ErrorOr<off_t> lseek(int fd, off_t offset, int whence)
  590. {
  591. off_t rc = ::lseek(fd, offset, whence);
  592. if (rc < 0)
  593. return Error::from_syscall("lseek", -errno);
  594. return rc;
  595. }
  596. ErrorOr<WaitPidResult> waitpid(pid_t waitee, int options)
  597. {
  598. int wstatus;
  599. pid_t pid = ::waitpid(waitee, &wstatus, options);
  600. if (pid < 0)
  601. return Error::from_syscall("waitpid"sv, -errno);
  602. return WaitPidResult { pid, wstatus };
  603. }
  604. ErrorOr<void> setuid(uid_t uid)
  605. {
  606. if (::setuid(uid) < 0)
  607. return Error::from_syscall("setuid"sv, -errno);
  608. return {};
  609. }
  610. ErrorOr<void> seteuid(uid_t uid)
  611. {
  612. if (::seteuid(uid) < 0)
  613. return Error::from_syscall("seteuid"sv, -errno);
  614. return {};
  615. }
  616. ErrorOr<void> setgid(gid_t gid)
  617. {
  618. if (::setgid(gid) < 0)
  619. return Error::from_syscall("setgid"sv, -errno);
  620. return {};
  621. }
  622. ErrorOr<void> setegid(gid_t gid)
  623. {
  624. if (::setegid(gid) < 0)
  625. return Error::from_syscall("setegid"sv, -errno);
  626. return {};
  627. }
  628. ErrorOr<void> setpgid(pid_t pid, pid_t pgid)
  629. {
  630. if (::setpgid(pid, pgid) < 0)
  631. return Error::from_syscall("setpgid"sv, -errno);
  632. return {};
  633. }
  634. ErrorOr<pid_t> setsid()
  635. {
  636. int rc = ::setsid();
  637. if (rc < 0)
  638. return Error::from_syscall("setsid"sv, -errno);
  639. return rc;
  640. }
  641. ErrorOr<bool> isatty(int fd)
  642. {
  643. int rc = ::isatty(fd);
  644. if (rc < 0)
  645. return Error::from_syscall("isatty"sv, -errno);
  646. return rc == 1;
  647. }
  648. ErrorOr<void> symlink(StringView target, StringView link_path)
  649. {
  650. #ifdef __serenity__
  651. Syscall::SC_symlink_params params {
  652. .target = { target.characters_without_null_termination(), target.length() },
  653. .linkpath = { link_path.characters_without_null_termination(), link_path.length() },
  654. };
  655. int rc = syscall(SC_symlink, &params);
  656. HANDLE_SYSCALL_RETURN_VALUE("symlink"sv, rc, {});
  657. #else
  658. String target_string = target;
  659. String link_path_string = link_path;
  660. if (::symlink(target_string.characters(), link_path_string.characters()) < 0)
  661. return Error::from_syscall("symlink"sv, -errno);
  662. return {};
  663. #endif
  664. }
  665. ErrorOr<void> mkdir(StringView path, mode_t mode)
  666. {
  667. if (path.is_null())
  668. return Error::from_errno(EFAULT);
  669. #ifdef __serenity__
  670. int rc = syscall(SC_mkdir, path.characters_without_null_termination(), path.length(), mode);
  671. HANDLE_SYSCALL_RETURN_VALUE("mkdir"sv, rc, {});
  672. #else
  673. String path_string = path;
  674. if (::mkdir(path_string.characters(), mode) < 0)
  675. return Error::from_syscall("mkdir"sv, -errno);
  676. return {};
  677. #endif
  678. }
  679. ErrorOr<void> chdir(StringView path)
  680. {
  681. if (path.is_null())
  682. return Error::from_errno(EFAULT);
  683. #ifdef __serenity__
  684. int rc = syscall(SC_chdir, path.characters_without_null_termination(), path.length());
  685. HANDLE_SYSCALL_RETURN_VALUE("chdir"sv, rc, {});
  686. #else
  687. String path_string = path;
  688. if (::chdir(path_string.characters()) < 0)
  689. return Error::from_syscall("chdir"sv, -errno);
  690. return {};
  691. #endif
  692. }
  693. ErrorOr<void> rmdir(StringView path)
  694. {
  695. if (path.is_null())
  696. return Error::from_errno(EFAULT);
  697. #ifdef __serenity__
  698. int rc = syscall(SC_rmdir, path.characters_without_null_termination(), path.length());
  699. HANDLE_SYSCALL_RETURN_VALUE("rmdir"sv, rc, {});
  700. #else
  701. String path_string = path;
  702. if (::rmdir(path_string.characters()) < 0)
  703. return Error::from_syscall("rmdir"sv, -errno);
  704. return {};
  705. #endif
  706. }
  707. ErrorOr<pid_t> fork()
  708. {
  709. pid_t pid = ::fork();
  710. if (pid < 0)
  711. return Error::from_syscall("fork"sv, -errno);
  712. return pid;
  713. }
  714. ErrorOr<int> mkstemp(Span<char> pattern)
  715. {
  716. int fd = ::mkstemp(pattern.data());
  717. if (fd < 0)
  718. return Error::from_syscall("mkstemp"sv, -errno);
  719. return fd;
  720. }
  721. ErrorOr<void> rename(StringView old_path, StringView new_path)
  722. {
  723. if (old_path.is_null() || new_path.is_null())
  724. return Error::from_errno(EFAULT);
  725. #ifdef __serenity__
  726. Syscall::SC_rename_params params {
  727. .old_path = { old_path.characters_without_null_termination(), old_path.length() },
  728. .new_path = { new_path.characters_without_null_termination(), new_path.length() },
  729. };
  730. int rc = syscall(SC_rename, &params);
  731. HANDLE_SYSCALL_RETURN_VALUE("rename"sv, rc, {});
  732. #else
  733. String old_path_string = old_path;
  734. String new_path_string = new_path;
  735. if (::rename(old_path_string.characters(), new_path_string.characters()) < 0)
  736. return Error::from_syscall("rename"sv, -errno);
  737. return {};
  738. #endif
  739. }
  740. ErrorOr<void> unlink(StringView path)
  741. {
  742. if (path.is_null())
  743. return Error::from_errno(EFAULT);
  744. #ifdef __serenity__
  745. int rc = syscall(SC_unlink, path.characters_without_null_termination(), path.length());
  746. HANDLE_SYSCALL_RETURN_VALUE("unlink"sv, rc, {});
  747. #else
  748. String path_string = path;
  749. if (::unlink(path_string.characters()) < 0)
  750. return Error::from_syscall("unlink"sv, -errno);
  751. return {};
  752. #endif
  753. }
  754. ErrorOr<void> utime(StringView path, Optional<struct utimbuf> maybe_buf)
  755. {
  756. if (path.is_null())
  757. return Error::from_errno(EFAULT);
  758. struct utimbuf* buf = nullptr;
  759. if (maybe_buf.has_value())
  760. buf = &maybe_buf.value();
  761. #ifdef __serenity__
  762. int rc = syscall(SC_utime, path.characters_without_null_termination(), path.length(), buf);
  763. HANDLE_SYSCALL_RETURN_VALUE("utime"sv, rc, {});
  764. #else
  765. String path_string = path;
  766. if (::utime(path_string.characters(), buf) < 0)
  767. return Error::from_syscall("utime"sv, -errno);
  768. return {};
  769. #endif
  770. }
  771. ErrorOr<struct utsname> uname()
  772. {
  773. utsname uts;
  774. #ifdef __serenity__
  775. int rc = syscall(SC_uname, &uts);
  776. HANDLE_SYSCALL_RETURN_VALUE("uname"sv, rc, uts);
  777. #else
  778. if (::uname(&uts) < 0)
  779. return Error::from_syscall("uname"sv, -errno);
  780. #endif
  781. return uts;
  782. }
  783. ErrorOr<void> adjtime(const struct timeval* delta, struct timeval* old_delta)
  784. {
  785. #ifdef __serenity__
  786. int rc = syscall(SC_adjtime, delta, old_delta);
  787. HANDLE_SYSCALL_RETURN_VALUE("adjtime"sv, rc, {});
  788. #else
  789. if (::adjtime(delta, old_delta) < 0)
  790. return Error::from_syscall("adjtime"sv, -errno);
  791. return {};
  792. #endif
  793. }
  794. ErrorOr<int> socket(int domain, int type, int protocol)
  795. {
  796. auto fd = ::socket(domain, type, protocol);
  797. if (fd < 0)
  798. return Error::from_syscall("socket"sv, -errno);
  799. return fd;
  800. }
  801. ErrorOr<void> bind(int sockfd, struct sockaddr const* address, socklen_t address_length)
  802. {
  803. if (::bind(sockfd, address, address_length) < 0)
  804. return Error::from_syscall("bind"sv, -errno);
  805. return {};
  806. }
  807. ErrorOr<void> listen(int sockfd, int backlog)
  808. {
  809. if (::listen(sockfd, backlog) < 0)
  810. return Error::from_syscall("listen"sv, -errno);
  811. return {};
  812. }
  813. ErrorOr<int> accept(int sockfd, struct sockaddr* address, socklen_t* address_length)
  814. {
  815. auto fd = ::accept(sockfd, address, address_length);
  816. if (fd < 0)
  817. return Error::from_syscall("accept"sv, -errno);
  818. return fd;
  819. }
  820. ErrorOr<void> connect(int sockfd, struct sockaddr const* address, socklen_t address_length)
  821. {
  822. if (::connect(sockfd, address, address_length) < 0)
  823. return Error::from_syscall("connect"sv, -errno);
  824. return {};
  825. }
  826. ErrorOr<void> shutdown(int sockfd, int how)
  827. {
  828. if (::shutdown(sockfd, how) < 0)
  829. return Error::from_syscall("shutdown"sv, -errno);
  830. return {};
  831. }
  832. ErrorOr<ssize_t> send(int sockfd, void const* buffer, size_t buffer_length, int flags)
  833. {
  834. auto sent = ::send(sockfd, buffer, buffer_length, flags);
  835. if (sent < 0)
  836. return Error::from_syscall("send"sv, -errno);
  837. return sent;
  838. }
  839. ErrorOr<ssize_t> sendmsg(int sockfd, const struct msghdr* message, int flags)
  840. {
  841. auto sent = ::sendmsg(sockfd, message, flags);
  842. if (sent < 0)
  843. return Error::from_syscall("sendmsg"sv, -errno);
  844. return sent;
  845. }
  846. ErrorOr<ssize_t> sendto(int sockfd, void const* source, size_t source_length, int flags, struct sockaddr const* destination, socklen_t destination_length)
  847. {
  848. auto sent = ::sendto(sockfd, source, source_length, flags, destination, destination_length);
  849. if (sent < 0)
  850. return Error::from_syscall("sendto"sv, -errno);
  851. return sent;
  852. }
  853. ErrorOr<ssize_t> recv(int sockfd, void* buffer, size_t length, int flags)
  854. {
  855. auto received = ::recv(sockfd, buffer, length, flags);
  856. if (received < 0)
  857. return Error::from_syscall("recv"sv, -errno);
  858. return received;
  859. }
  860. ErrorOr<ssize_t> recvmsg(int sockfd, struct msghdr* message, int flags)
  861. {
  862. auto received = ::recvmsg(sockfd, message, flags);
  863. if (received < 0)
  864. return Error::from_syscall("recvmsg"sv, -errno);
  865. return received;
  866. }
  867. ErrorOr<ssize_t> recvfrom(int sockfd, void* buffer, size_t buffer_length, int flags, struct sockaddr* address, socklen_t* address_length)
  868. {
  869. auto received = ::recvfrom(sockfd, buffer, buffer_length, flags, address, address_length);
  870. if (received < 0)
  871. return Error::from_syscall("recvfrom"sv, -errno);
  872. return received;
  873. }
  874. ErrorOr<void> getsockopt(int sockfd, int level, int option, void* value, socklen_t* value_size)
  875. {
  876. if (::getsockopt(sockfd, level, option, value, value_size) < 0)
  877. return Error::from_syscall("getsockopt"sv, -errno);
  878. return {};
  879. }
  880. ErrorOr<void> setsockopt(int sockfd, int level, int option, void const* value, socklen_t value_size)
  881. {
  882. if (::setsockopt(sockfd, level, option, value, value_size) < 0)
  883. return Error::from_syscall("setsockopt"sv, -errno);
  884. return {};
  885. }
  886. ErrorOr<void> getsockname(int sockfd, struct sockaddr* address, socklen_t* address_length)
  887. {
  888. if (::getsockname(sockfd, address, address_length) < 0)
  889. return Error::from_syscall("getsockname"sv, -errno);
  890. return {};
  891. }
  892. ErrorOr<void> getpeername(int sockfd, struct sockaddr* address, socklen_t* address_length)
  893. {
  894. if (::getpeername(sockfd, address, address_length) < 0)
  895. return Error::from_syscall("getpeername"sv, -errno);
  896. return {};
  897. }
  898. ErrorOr<void> socketpair(int domain, int type, int protocol, int sv[2])
  899. {
  900. if (::socketpair(domain, type, protocol, sv) < 0)
  901. return Error::from_syscall("socketpair"sv, -errno);
  902. return {};
  903. }
  904. ErrorOr<Array<int, 2>> pipe2([[maybe_unused]] int flags)
  905. {
  906. Array<int, 2> fds;
  907. #if defined(__unix__)
  908. if (::pipe2(fds.data(), flags) < 0)
  909. return Error::from_syscall("pipe2"sv, -errno);
  910. #else
  911. if (::pipe(fds.data()) < 0)
  912. return Error::from_syscall("pipe2"sv, -errno);
  913. #endif
  914. return fds;
  915. }
  916. ErrorOr<Vector<gid_t>> getgroups()
  917. {
  918. int count = ::getgroups(0, nullptr);
  919. if (count < 0)
  920. return Error::from_syscall("getgroups"sv, -errno);
  921. if (count == 0)
  922. return Vector<gid_t> {};
  923. Vector<gid_t> groups;
  924. TRY(groups.try_resize(count));
  925. if (::getgroups(count, groups.data()) < 0)
  926. return Error::from_syscall("getgroups"sv, -errno);
  927. return groups;
  928. }
  929. ErrorOr<void> mknod(StringView pathname, mode_t mode, dev_t dev)
  930. {
  931. if (pathname.is_null())
  932. return Error::from_syscall("mknod"sv, -EFAULT);
  933. #ifdef __serenity__
  934. Syscall::SC_mknod_params params { { pathname.characters_without_null_termination(), pathname.length() }, mode, dev };
  935. int rc = syscall(SC_mknod, &params);
  936. HANDLE_SYSCALL_RETURN_VALUE("mknod"sv, rc, {});
  937. #else
  938. String path_string = pathname;
  939. if (::mknod(path_string.characters(), mode, dev) < 0)
  940. return Error::from_syscall("mknod"sv, -errno);
  941. return {};
  942. #endif
  943. }
  944. ErrorOr<void> mkfifo(StringView pathname, mode_t mode)
  945. {
  946. return mknod(pathname, mode | S_IFIFO, 0);
  947. }
  948. ErrorOr<void> setenv(StringView name, StringView value, bool overwrite)
  949. {
  950. #ifdef __serenity__
  951. auto const rc = ::serenity_setenv(name.characters_without_null_termination(), name.length(), value.characters_without_null_termination(), value.length(), overwrite);
  952. #else
  953. String name_string = name;
  954. String value_string = value;
  955. auto const rc = ::setenv(name_string.characters(), value_string.characters(), overwrite);
  956. #endif
  957. if (rc < 0)
  958. return Error::from_syscall("setenv", -errno);
  959. return {};
  960. }
  961. }