System.cpp 55 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840
  1. /*
  2. * Copyright (c) 2021-2022, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2021-2022, Kenneth Myhra <kennethmyhra@serenityos.org>
  4. * Copyright (c) 2021-2023, 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/DeprecatedString.h>
  10. #include <AK/FixedArray.h>
  11. #include <AK/ScopedValueRollback.h>
  12. #include <AK/StdLibExtras.h>
  13. #include <AK/String.h>
  14. #include <AK/Vector.h>
  15. #include <LibCore/SessionManagement.h>
  16. #include <LibCore/System.h>
  17. #include <limits.h>
  18. #include <stdarg.h>
  19. #include <stdlib.h>
  20. #include <sys/ioctl.h>
  21. #include <sys/mman.h>
  22. #include <sys/time.h>
  23. #include <sys/types.h>
  24. #include <termios.h>
  25. #include <unistd.h>
  26. #ifdef AK_OS_SERENITY
  27. # include <Kernel/API/Unveil.h>
  28. # include <LibCore/Account.h>
  29. # include <LibSystem/syscall.h>
  30. # include <serenity.h>
  31. # include <sys/ptrace.h>
  32. # include <sys/sysmacros.h>
  33. #endif
  34. #if defined(AK_OS_LINUX) && !defined(MFD_CLOEXEC)
  35. # include <linux/memfd.h>
  36. # include <sys/syscall.h>
  37. static int memfd_create(char const* name, unsigned int flags)
  38. {
  39. return syscall(SYS_memfd_create, name, flags);
  40. }
  41. #endif
  42. #if defined(AK_OS_MACOS)
  43. # include <crt_externs.h>
  44. # include <mach-o/dyld.h>
  45. # include <sys/mman.h>
  46. #else
  47. extern char** environ;
  48. #endif
  49. #if defined(AK_OS_BSD_GENERIC) && !defined(AK_OS_SOLARIS)
  50. # include <sys/sysctl.h>
  51. #endif
  52. #if defined(AK_OS_GNU_HURD)
  53. extern "C" {
  54. # include <hurd.h>
  55. }
  56. # include <LibCore/File.h>
  57. #endif
  58. #if defined(AK_OS_HAIKU)
  59. # include <image.h>
  60. #endif
  61. #define HANDLE_SYSCALL_RETURN_VALUE(syscall_name, rc, success_value) \
  62. if ((rc) < 0) { \
  63. return Error::from_syscall(syscall_name##sv, rc); \
  64. } \
  65. return success_value;
  66. template<typename T>
  67. concept SupportsReentrantGetpwent = requires(T passwd, T* ptr) {
  68. getpwent_r(&passwd, nullptr, 0, &ptr);
  69. };
  70. // Note: This has to be in the global namespace for the extern declaration to trick the compiler
  71. // into finding a declaration of getpwent_r when it doesn't actually exist.
  72. static ErrorOr<Optional<struct passwd>> getpwent_impl(Span<char> buffer)
  73. {
  74. if constexpr (SupportsReentrantGetpwent<struct passwd>) {
  75. struct passwd passwd;
  76. struct passwd* ptr = nullptr;
  77. extern int getpwent_r(struct passwd*, char*, size_t, struct passwd**);
  78. auto result = getpwent_r(&passwd, buffer.data(), buffer.size(), &ptr);
  79. if (result == 0 && ptr)
  80. return passwd;
  81. if (result != 0 && result != ENOENT)
  82. return Error::from_errno(result);
  83. } else {
  84. errno = 0;
  85. if (auto const* passwd = ::getpwent())
  86. return *passwd;
  87. if (errno)
  88. return Error::from_errno(errno);
  89. }
  90. return Optional<struct passwd> {};
  91. }
  92. template<typename T>
  93. concept SupportsReentrantGetgrent = requires(T group, T* ptr) {
  94. getgrent_r(&group, nullptr, 0, &ptr);
  95. };
  96. // Note: This has to be in the global namespace for the extern declaration to trick the compiler
  97. // into finding a declaration of getgrent_r when it doesn't actually exist.
  98. static ErrorOr<Optional<struct group>> getgrent_impl(Span<char> buffer)
  99. {
  100. if constexpr (SupportsReentrantGetgrent<struct group>) {
  101. struct group group;
  102. struct group* ptr = nullptr;
  103. extern int getgrent_r(struct group*, char*, size_t, struct group**);
  104. auto result = getgrent_r(&group, buffer.data(), buffer.size(), &ptr);
  105. if (result == 0 && ptr)
  106. return group;
  107. if (result != 0 && result != ENOENT)
  108. return Error::from_errno(result);
  109. } else {
  110. errno = 0;
  111. if (auto const* group = ::getgrent())
  112. return *group;
  113. if (errno)
  114. return Error::from_errno(errno);
  115. }
  116. return Optional<struct group> {};
  117. }
  118. namespace Core::System {
  119. #ifndef HOST_NAME_MAX
  120. # ifdef AK_OS_MACOS
  121. # define HOST_NAME_MAX 255
  122. # else
  123. # define HOST_NAME_MAX 64
  124. # endif
  125. #endif
  126. #ifdef AK_OS_SERENITY
  127. ErrorOr<void> beep(Optional<size_t> tone)
  128. {
  129. auto rc = ::sysbeep(tone.value_or(440));
  130. if (rc < 0)
  131. return Error::from_syscall("beep"sv, -errno);
  132. return {};
  133. }
  134. ErrorOr<void> pledge(StringView promises, StringView execpromises)
  135. {
  136. Syscall::SC_pledge_params params {
  137. { promises.characters_without_null_termination(), promises.length() },
  138. { execpromises.characters_without_null_termination(), execpromises.length() },
  139. };
  140. int rc = syscall(SC_pledge, &params);
  141. HANDLE_SYSCALL_RETURN_VALUE("pledge", rc, {});
  142. }
  143. static ErrorOr<void> unveil_dynamic_loader()
  144. {
  145. static bool dynamic_loader_unveiled { false };
  146. if (dynamic_loader_unveiled)
  147. return {};
  148. // FIXME: Try to find a way to not hardcode the dynamic loader path.
  149. constexpr auto dynamic_loader_path = "/usr/lib/Loader.so"sv;
  150. constexpr auto dynamic_loader_permissions = "x"sv;
  151. Syscall::SC_unveil_params params {
  152. static_cast<int>(UnveilFlags::CurrentProgram),
  153. { dynamic_loader_path.characters_without_null_termination(), dynamic_loader_path.length() },
  154. { dynamic_loader_permissions.characters_without_null_termination(), dynamic_loader_permissions.length() },
  155. };
  156. int rc = syscall(SC_unveil, &params);
  157. if (rc < 0) {
  158. return Error::from_syscall("unveil (DynamicLoader @ /usr/lib/Loader.so)"sv, rc);
  159. }
  160. dynamic_loader_unveiled = true;
  161. return {};
  162. }
  163. ErrorOr<void> unveil(StringView path, StringView permissions)
  164. {
  165. auto const parsed_path = TRY(Core::SessionManagement::parse_path_with_sid(path));
  166. if (permissions.contains('x'))
  167. TRY(unveil_dynamic_loader());
  168. Syscall::SC_unveil_params params {
  169. static_cast<int>(UnveilFlags::CurrentProgram),
  170. { parsed_path.characters(), parsed_path.length() },
  171. { permissions.characters_without_null_termination(), permissions.length() },
  172. };
  173. int rc = syscall(SC_unveil, &params);
  174. HANDLE_SYSCALL_RETURN_VALUE("unveil", rc, {});
  175. }
  176. ErrorOr<void> unveil_after_exec(StringView path, StringView permissions)
  177. {
  178. auto const parsed_path = TRY(Core::SessionManagement::parse_path_with_sid(path));
  179. Syscall::SC_unveil_params params {
  180. static_cast<int>(UnveilFlags::AfterExec),
  181. { parsed_path.characters(), parsed_path.length() },
  182. { permissions.characters_without_null_termination(), permissions.length() },
  183. };
  184. int rc = syscall(SC_unveil, &params);
  185. HANDLE_SYSCALL_RETURN_VALUE("unveil", rc, {});
  186. }
  187. ErrorOr<void> sendfd(int sockfd, int fd)
  188. {
  189. if (::sendfd(sockfd, fd) < 0)
  190. return Error::from_syscall("sendfd"sv, -errno);
  191. return {};
  192. }
  193. ErrorOr<int> recvfd(int sockfd, int options)
  194. {
  195. auto fd = ::recvfd(sockfd, options);
  196. if (fd < 0)
  197. return Error::from_syscall("recvfd"sv, -errno);
  198. return fd;
  199. }
  200. ErrorOr<void> ptrace_peekbuf(pid_t tid, void const* tracee_addr, Bytes destination_buf)
  201. {
  202. Syscall::SC_ptrace_buf_params buf_params {
  203. { destination_buf.data(), destination_buf.size() }
  204. };
  205. Syscall::SC_ptrace_params params {
  206. PT_PEEKBUF,
  207. tid,
  208. const_cast<void*>(tracee_addr),
  209. (FlatPtr)&buf_params,
  210. };
  211. int rc = syscall(SC_ptrace, &params);
  212. HANDLE_SYSCALL_RETURN_VALUE("ptrace_peekbuf", rc, {});
  213. }
  214. ErrorOr<void> bindmount(int source_fd, StringView target, int flags)
  215. {
  216. if (target.is_null())
  217. return Error::from_errno(EFAULT);
  218. Syscall::SC_bindmount_params params {
  219. { target.characters_without_null_termination(), target.length() },
  220. source_fd,
  221. flags,
  222. };
  223. int rc = syscall(SC_bindmount, &params);
  224. HANDLE_SYSCALL_RETURN_VALUE("bindmount", rc, {});
  225. }
  226. ErrorOr<void> remount(StringView target, int flags)
  227. {
  228. if (target.is_null())
  229. return Error::from_errno(EFAULT);
  230. Syscall::SC_remount_params params {
  231. { target.characters_without_null_termination(), target.length() },
  232. flags
  233. };
  234. int rc = syscall(SC_remount, &params);
  235. HANDLE_SYSCALL_RETURN_VALUE("remount", rc, {});
  236. }
  237. ErrorOr<void> mount(int source_fd, StringView target, StringView fs_type, int flags)
  238. {
  239. if (target.is_null() || fs_type.is_null())
  240. return Error::from_errno(EFAULT);
  241. if (flags & MS_REMOUNT) {
  242. TRY(remount(target, flags));
  243. return {};
  244. }
  245. if (flags & MS_BIND) {
  246. TRY(bindmount(source_fd, target, flags));
  247. return {};
  248. }
  249. int mount_fd = TRY(fsopen(fs_type, flags));
  250. return fsmount(mount_fd, source_fd, target);
  251. }
  252. ErrorOr<int> fsopen(StringView fs_type, int flags)
  253. {
  254. if (fs_type.is_null())
  255. return Error::from_errno(EFAULT);
  256. Syscall::SC_fsopen_params params {
  257. { fs_type.characters_without_null_termination(), fs_type.length() },
  258. flags,
  259. };
  260. int rc = syscall(SC_fsopen, &params);
  261. HANDLE_SYSCALL_RETURN_VALUE("fsopen", rc, rc);
  262. }
  263. ErrorOr<void> fsmount(int mount_fd, int source_fd, StringView target)
  264. {
  265. if (target.is_null())
  266. return Error::from_errno(EFAULT);
  267. Syscall::SC_fsmount_params params {
  268. mount_fd,
  269. { target.characters_without_null_termination(), target.length() },
  270. source_fd,
  271. };
  272. int rc = syscall(SC_fsmount, &params);
  273. HANDLE_SYSCALL_RETURN_VALUE("fsmount", rc, {});
  274. }
  275. ErrorOr<void> umount(StringView mount_point)
  276. {
  277. if (mount_point.is_null())
  278. return Error::from_errno(EFAULT);
  279. int rc = syscall(SC_umount, mount_point.characters_without_null_termination(), mount_point.length());
  280. HANDLE_SYSCALL_RETURN_VALUE("umount", rc, {});
  281. }
  282. ErrorOr<long> ptrace(int request, pid_t tid, void* address, void* data)
  283. {
  284. auto rc = ::ptrace(request, tid, address, data);
  285. if (rc < 0)
  286. return Error::from_syscall("ptrace"sv, -errno);
  287. return rc;
  288. }
  289. ErrorOr<void> disown(pid_t pid)
  290. {
  291. int rc = ::disown(pid);
  292. HANDLE_SYSCALL_RETURN_VALUE("disown", rc, {});
  293. }
  294. ErrorOr<void> profiling_enable(pid_t pid, u64 event_mask)
  295. {
  296. int rc = ::profiling_enable(pid, event_mask);
  297. HANDLE_SYSCALL_RETURN_VALUE("profiling_enable", rc, {});
  298. }
  299. ErrorOr<void> profiling_disable(pid_t pid)
  300. {
  301. int rc = ::profiling_disable(pid);
  302. HANDLE_SYSCALL_RETURN_VALUE("profiling_disable", rc, {});
  303. }
  304. ErrorOr<void> profiling_free_buffer(pid_t pid)
  305. {
  306. int rc = ::profiling_free_buffer(pid);
  307. HANDLE_SYSCALL_RETURN_VALUE("profiling_free_buffer", rc, {});
  308. }
  309. #endif
  310. #if !defined(AK_OS_BSD_GENERIC) && !defined(AK_OS_ANDROID)
  311. ErrorOr<Optional<struct spwd>> getspent()
  312. {
  313. errno = 0;
  314. if (auto* spwd = ::getspent())
  315. return *spwd;
  316. if (errno)
  317. return Error::from_syscall("getspent"sv, -errno);
  318. return Optional<struct spwd> {};
  319. }
  320. ErrorOr<Optional<struct spwd>> getspnam(StringView name)
  321. {
  322. errno = 0;
  323. ::setspent();
  324. while (auto* spwd = ::getspent()) {
  325. if (spwd->sp_namp == name)
  326. return *spwd;
  327. }
  328. if (errno)
  329. return Error::from_syscall("getspnam"sv, -errno);
  330. return Optional<struct spwd> {};
  331. }
  332. #endif
  333. #if !defined(AK_OS_MACOS) && !defined(AK_OS_HAIKU)
  334. ErrorOr<int> accept4(int sockfd, sockaddr* address, socklen_t* address_length, int flags)
  335. {
  336. auto fd = ::accept4(sockfd, address, address_length, flags);
  337. if (fd < 0)
  338. return Error::from_syscall("accept4"sv, -errno);
  339. return fd;
  340. }
  341. #endif
  342. ErrorOr<void> sigaction(int signal, struct sigaction const* action, struct sigaction* old_action)
  343. {
  344. if (::sigaction(signal, action, old_action) < 0)
  345. return Error::from_syscall("sigaction"sv, -errno);
  346. return {};
  347. }
  348. #if defined(AK_OS_SOLARIS)
  349. ErrorOr<SIG_TYP> signal(int signal, SIG_TYP handler)
  350. #elif defined(AK_OS_BSD_GENERIC)
  351. ErrorOr<sig_t> signal(int signal, sig_t handler)
  352. #else
  353. ErrorOr<sighandler_t> signal(int signal, sighandler_t handler)
  354. #endif
  355. {
  356. auto old_handler = ::signal(signal, handler);
  357. if (old_handler == SIG_ERR)
  358. return Error::from_syscall("signal"sv, -errno);
  359. return old_handler;
  360. }
  361. ErrorOr<struct stat> fstat(int fd)
  362. {
  363. struct stat st = {};
  364. if (::fstat(fd, &st) < 0)
  365. return Error::from_syscall("fstat"sv, -errno);
  366. return st;
  367. }
  368. ErrorOr<struct stat> fstatat(int fd, StringView path, int flags)
  369. {
  370. if (!path.characters_without_null_termination())
  371. return Error::from_syscall("fstatat"sv, -EFAULT);
  372. struct stat st = {};
  373. #ifdef AK_OS_SERENITY
  374. Syscall::SC_stat_params params { { path.characters_without_null_termination(), path.length() }, &st, fd, !(flags & AT_SYMLINK_NOFOLLOW) };
  375. int rc = syscall(SC_stat, &params);
  376. #else
  377. DeprecatedString path_string = path;
  378. int rc = ::fstatat(fd, path_string.characters(), &st, flags);
  379. #endif
  380. HANDLE_SYSCALL_RETURN_VALUE("fstatat", rc, st);
  381. }
  382. ErrorOr<int> fcntl(int fd, int command, ...)
  383. {
  384. va_list ap;
  385. va_start(ap, command);
  386. uintptr_t extra_arg = va_arg(ap, uintptr_t);
  387. int rc = ::fcntl(fd, command, extra_arg);
  388. va_end(ap);
  389. if (rc < 0)
  390. return Error::from_syscall("fcntl"sv, -errno);
  391. return rc;
  392. }
  393. #ifdef AK_OS_SERENITY
  394. ErrorOr<void> create_block_device(StringView name, mode_t mode, unsigned major, unsigned minor)
  395. {
  396. return Core::System::mknod(name, mode | S_IFBLK, makedev(major, minor));
  397. }
  398. ErrorOr<void> create_char_device(StringView name, mode_t mode, unsigned major, unsigned minor)
  399. {
  400. return Core::System::mknod(name, mode | S_IFCHR, makedev(major, minor));
  401. }
  402. #endif
  403. 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)
  404. {
  405. #ifdef AK_OS_SERENITY
  406. Syscall::SC_mmap_params params { address, size, alignment, protection, flags, fd, offset, { name.characters_without_null_termination(), name.length() } };
  407. ptrdiff_t rc = syscall(SC_mmap, &params);
  408. if (rc < 0 && rc > -EMAXERRNO)
  409. return Error::from_syscall("mmap"sv, rc);
  410. return reinterpret_cast<void*>(rc);
  411. #else
  412. // NOTE: Regular POSIX mmap() doesn't support custom alignment requests.
  413. VERIFY(!alignment);
  414. auto* ptr = ::mmap(address, size, protection, flags, fd, offset);
  415. if (ptr == MAP_FAILED)
  416. return Error::from_syscall("mmap"sv, -errno);
  417. return ptr;
  418. #endif
  419. }
  420. ErrorOr<void> munmap(void* address, size_t size)
  421. {
  422. if (::munmap(address, size) < 0)
  423. return Error::from_syscall("munmap"sv, -errno);
  424. return {};
  425. }
  426. ErrorOr<int> anon_create([[maybe_unused]] size_t size, [[maybe_unused]] int options)
  427. {
  428. int fd = -1;
  429. #if defined(AK_OS_SERENITY)
  430. fd = ::anon_create(round_up_to_power_of_two(size, PAGE_SIZE), options);
  431. #elif defined(AK_OS_LINUX) || defined(AK_OS_FREEBSD)
  432. // FIXME: Support more options on Linux.
  433. auto linux_options = ((options & O_CLOEXEC) > 0) ? MFD_CLOEXEC : 0;
  434. fd = memfd_create("", linux_options);
  435. if (fd < 0)
  436. return Error::from_errno(errno);
  437. if (::ftruncate(fd, size) < 0) {
  438. auto saved_errno = errno;
  439. TRY(close(fd));
  440. return Error::from_errno(saved_errno);
  441. }
  442. #elif defined(SHM_ANON)
  443. fd = shm_open(SHM_ANON, O_RDWR | O_CREAT | options, 0600);
  444. if (fd < 0)
  445. return Error::from_errno(errno);
  446. if (::ftruncate(fd, size) < 0) {
  447. auto saved_errno = errno;
  448. TRY(close(fd));
  449. return Error::from_errno(saved_errno);
  450. }
  451. #elif defined(AK_OS_BSD_GENERIC) || defined(AK_OS_EMSCRIPTEN)
  452. struct timespec time;
  453. clock_gettime(CLOCK_REALTIME, &time);
  454. auto name = DeprecatedString::formatted("/shm-{}{}", (unsigned long)time.tv_sec, (unsigned long)time.tv_nsec);
  455. fd = shm_open(name.characters(), O_RDWR | O_CREAT | options, 0600);
  456. if (shm_unlink(name.characters()) == -1) {
  457. auto saved_errno = errno;
  458. TRY(close(fd));
  459. return Error::from_errno(saved_errno);
  460. }
  461. if (fd < 0)
  462. return Error::from_errno(errno);
  463. if (::ftruncate(fd, size) < 0) {
  464. auto saved_errno = errno;
  465. TRY(close(fd));
  466. return Error::from_errno(saved_errno);
  467. }
  468. void* addr = ::mmap(NULL, size, PROT_WRITE, MAP_SHARED, fd, 0);
  469. if (addr == MAP_FAILED) {
  470. auto saved_errno = errno;
  471. TRY(close(fd));
  472. return Error::from_errno(saved_errno);
  473. }
  474. #endif
  475. if (fd < 0)
  476. return Error::from_errno(errno);
  477. return fd;
  478. }
  479. ErrorOr<int> open(StringView path, int options, mode_t mode)
  480. {
  481. return openat(AT_FDCWD, path, options, mode);
  482. }
  483. ErrorOr<int> openat(int fd, StringView path, int options, mode_t mode)
  484. {
  485. if (!path.characters_without_null_termination())
  486. return Error::from_syscall("open"sv, -EFAULT);
  487. #ifdef AK_OS_SERENITY
  488. Syscall::SC_open_params params { fd, { path.characters_without_null_termination(), path.length() }, options, mode };
  489. int rc = syscall(SC_open, &params);
  490. HANDLE_SYSCALL_RETURN_VALUE("open", rc, rc);
  491. #else
  492. // NOTE: We have to ensure that the path is null-terminated.
  493. DeprecatedString path_string = path;
  494. int rc = ::openat(fd, path_string.characters(), options, mode);
  495. if (rc < 0)
  496. return Error::from_syscall("open"sv, -errno);
  497. return rc;
  498. #endif
  499. }
  500. ErrorOr<void> close(int fd)
  501. {
  502. if (::close(fd) < 0)
  503. return Error::from_syscall("close"sv, -errno);
  504. return {};
  505. }
  506. ErrorOr<void> ftruncate(int fd, off_t length)
  507. {
  508. if (::ftruncate(fd, length) < 0)
  509. return Error::from_syscall("ftruncate"sv, -errno);
  510. return {};
  511. }
  512. ErrorOr<struct stat> stat(StringView path)
  513. {
  514. if (!path.characters_without_null_termination())
  515. return Error::from_syscall("stat"sv, -EFAULT);
  516. struct stat st = {};
  517. #ifdef AK_OS_SERENITY
  518. Syscall::SC_stat_params params { { path.characters_without_null_termination(), path.length() }, &st, AT_FDCWD, true };
  519. int rc = syscall(SC_stat, &params);
  520. HANDLE_SYSCALL_RETURN_VALUE("stat", rc, st);
  521. #else
  522. DeprecatedString path_string = path;
  523. if (::stat(path_string.characters(), &st) < 0)
  524. return Error::from_syscall("stat"sv, -errno);
  525. return st;
  526. #endif
  527. }
  528. ErrorOr<struct stat> lstat(StringView path)
  529. {
  530. if (!path.characters_without_null_termination())
  531. return Error::from_syscall("lstat"sv, -EFAULT);
  532. struct stat st = {};
  533. #ifdef AK_OS_SERENITY
  534. Syscall::SC_stat_params params { { path.characters_without_null_termination(), path.length() }, &st, AT_FDCWD, false };
  535. int rc = syscall(SC_stat, &params);
  536. HANDLE_SYSCALL_RETURN_VALUE("lstat", rc, st);
  537. #else
  538. DeprecatedString path_string = path;
  539. if (::lstat(path_string.characters(), &st) < 0)
  540. return Error::from_syscall("lstat"sv, -errno);
  541. return st;
  542. #endif
  543. }
  544. ErrorOr<ssize_t> read(int fd, Bytes buffer)
  545. {
  546. ssize_t rc = ::read(fd, buffer.data(), buffer.size());
  547. if (rc < 0)
  548. return Error::from_syscall("read"sv, -errno);
  549. return rc;
  550. }
  551. ErrorOr<ssize_t> write(int fd, ReadonlyBytes buffer)
  552. {
  553. ssize_t rc = ::write(fd, buffer.data(), buffer.size());
  554. if (rc < 0)
  555. return Error::from_syscall("write"sv, -errno);
  556. return rc;
  557. }
  558. ErrorOr<void> kill(pid_t pid, int signal)
  559. {
  560. if (::kill(pid, signal) < 0)
  561. return Error::from_syscall("kill"sv, -errno);
  562. return {};
  563. }
  564. ErrorOr<void> killpg(int pgrp, int signal)
  565. {
  566. if (::killpg(pgrp, signal) < 0)
  567. return Error::from_syscall("killpg"sv, -errno);
  568. return {};
  569. }
  570. ErrorOr<int> dup(int source_fd)
  571. {
  572. int fd = ::dup(source_fd);
  573. if (fd < 0)
  574. return Error::from_syscall("dup"sv, -errno);
  575. return fd;
  576. }
  577. ErrorOr<int> dup2(int source_fd, int destination_fd)
  578. {
  579. int fd = ::dup2(source_fd, destination_fd);
  580. if (fd < 0)
  581. return Error::from_syscall("dup2"sv, -errno);
  582. return fd;
  583. }
  584. ErrorOr<DeprecatedString> ptsname(int fd)
  585. {
  586. auto* name = ::ptsname(fd);
  587. if (!name)
  588. return Error::from_syscall("ptsname"sv, -errno);
  589. return DeprecatedString(name);
  590. }
  591. ErrorOr<DeprecatedString> gethostname()
  592. {
  593. char hostname[HOST_NAME_MAX];
  594. int rc = ::gethostname(hostname, sizeof(hostname));
  595. if (rc < 0)
  596. return Error::from_syscall("gethostname"sv, -errno);
  597. return DeprecatedString(&hostname[0]);
  598. }
  599. ErrorOr<void> sethostname(StringView hostname)
  600. {
  601. #if defined(AK_OS_SOLARIS)
  602. int rc = ::sethostname(const_cast<char*>(hostname.characters_without_null_termination()), hostname.length());
  603. #else
  604. int rc = ::sethostname(hostname.characters_without_null_termination(), hostname.length());
  605. #endif
  606. if (rc < 0)
  607. return Error::from_syscall("sethostname"sv, -errno);
  608. return {};
  609. }
  610. ErrorOr<DeprecatedString> getcwd()
  611. {
  612. auto* cwd = ::getcwd(nullptr, 0);
  613. if (!cwd)
  614. return Error::from_syscall("getcwd"sv, -errno);
  615. DeprecatedString string_cwd(cwd);
  616. free(cwd);
  617. return string_cwd;
  618. }
  619. ErrorOr<void> ioctl(int fd, unsigned request, ...)
  620. {
  621. va_list ap;
  622. va_start(ap, request);
  623. #ifdef AK_OS_HAIKU
  624. void* arg = va_arg(ap, void*);
  625. #else
  626. FlatPtr arg = va_arg(ap, FlatPtr);
  627. #endif
  628. va_end(ap);
  629. if (::ioctl(fd, request, arg) < 0)
  630. return Error::from_syscall("ioctl"sv, -errno);
  631. return {};
  632. }
  633. ErrorOr<struct termios> tcgetattr(int fd)
  634. {
  635. struct termios ios = {};
  636. if (::tcgetattr(fd, &ios) < 0)
  637. return Error::from_syscall("tcgetattr"sv, -errno);
  638. return ios;
  639. }
  640. ErrorOr<void> tcsetattr(int fd, int optional_actions, struct termios const& ios)
  641. {
  642. if (::tcsetattr(fd, optional_actions, &ios) < 0)
  643. return Error::from_syscall("tcsetattr"sv, -errno);
  644. return {};
  645. }
  646. ErrorOr<int> tcsetpgrp(int fd, pid_t pgrp)
  647. {
  648. int rc = ::tcsetpgrp(fd, pgrp);
  649. if (rc < 0)
  650. return Error::from_syscall("tcsetpgrp"sv, -errno);
  651. return { rc };
  652. }
  653. ErrorOr<void> chmod(StringView pathname, mode_t mode)
  654. {
  655. if (!pathname.characters_without_null_termination())
  656. return Error::from_syscall("chmod"sv, -EFAULT);
  657. #ifdef AK_OS_SERENITY
  658. Syscall::SC_chmod_params params {
  659. AT_FDCWD,
  660. { pathname.characters_without_null_termination(), pathname.length() },
  661. mode,
  662. true
  663. };
  664. int rc = syscall(SC_chmod, &params);
  665. HANDLE_SYSCALL_RETURN_VALUE("chmod", rc, {});
  666. #else
  667. DeprecatedString path = pathname;
  668. if (::chmod(path.characters(), mode) < 0)
  669. return Error::from_syscall("chmod"sv, -errno);
  670. return {};
  671. #endif
  672. }
  673. ErrorOr<void> fchmod(int fd, mode_t mode)
  674. {
  675. if (::fchmod(fd, mode) < 0)
  676. return Error::from_syscall("fchmod"sv, -errno);
  677. return {};
  678. }
  679. ErrorOr<void> fchown(int fd, uid_t uid, gid_t gid)
  680. {
  681. if (::fchown(fd, uid, gid) < 0)
  682. return Error::from_syscall("fchown"sv, -errno);
  683. return {};
  684. }
  685. ErrorOr<void> lchown(StringView pathname, uid_t uid, gid_t gid)
  686. {
  687. if (!pathname.characters_without_null_termination())
  688. return Error::from_syscall("chown"sv, -EFAULT);
  689. #ifdef AK_OS_SERENITY
  690. Syscall::SC_chown_params params = { { pathname.characters_without_null_termination(), pathname.length() }, uid, gid, AT_FDCWD, false };
  691. int rc = syscall(SC_chown, &params);
  692. HANDLE_SYSCALL_RETURN_VALUE("chown", rc, {});
  693. #else
  694. DeprecatedString path = pathname;
  695. if (::chown(path.characters(), uid, gid) < 0)
  696. return Error::from_syscall("chown"sv, -errno);
  697. return {};
  698. #endif
  699. }
  700. ErrorOr<void> chown(StringView pathname, uid_t uid, gid_t gid)
  701. {
  702. if (!pathname.characters_without_null_termination())
  703. return Error::from_syscall("chown"sv, -EFAULT);
  704. #ifdef AK_OS_SERENITY
  705. Syscall::SC_chown_params params = { { pathname.characters_without_null_termination(), pathname.length() }, uid, gid, AT_FDCWD, true };
  706. int rc = syscall(SC_chown, &params);
  707. HANDLE_SYSCALL_RETURN_VALUE("chown", rc, {});
  708. #else
  709. DeprecatedString path = pathname;
  710. if (::lchown(path.characters(), uid, gid) < 0)
  711. return Error::from_syscall("lchown"sv, -errno);
  712. return {};
  713. #endif
  714. }
  715. ErrorOr<Optional<struct passwd>> getpwent(Span<char> buffer)
  716. {
  717. return getpwent_impl(buffer);
  718. }
  719. ErrorOr<Optional<struct passwd>> getpwuid(uid_t uid)
  720. {
  721. errno = 0;
  722. if (auto* pwd = ::getpwuid(uid))
  723. return *pwd;
  724. if (errno)
  725. return Error::from_syscall("getpwuid"sv, -errno);
  726. return Optional<struct passwd> {};
  727. }
  728. ErrorOr<Optional<struct group>> getgrent(Span<char> buffer)
  729. {
  730. return getgrent_impl(buffer);
  731. }
  732. ErrorOr<Optional<struct group>> getgrgid(gid_t gid)
  733. {
  734. errno = 0;
  735. if (auto* grp = ::getgrgid(gid))
  736. return *grp;
  737. if (errno)
  738. return Error::from_syscall("getgrgid"sv, -errno);
  739. return Optional<struct group> {};
  740. }
  741. ErrorOr<Optional<struct passwd>> getpwnam(StringView name)
  742. {
  743. errno = 0;
  744. ::setpwent();
  745. if (errno)
  746. return Error::from_syscall("getpwnam"sv, -errno);
  747. while (auto* pw = ::getpwent()) {
  748. if (errno)
  749. return Error::from_syscall("getpwnam"sv, -errno);
  750. if (pw->pw_name == name)
  751. return *pw;
  752. }
  753. if (errno)
  754. return Error::from_syscall("getpwnam"sv, -errno);
  755. else
  756. return Optional<struct passwd> {};
  757. }
  758. ErrorOr<Optional<struct group>> getgrnam(StringView name)
  759. {
  760. errno = 0;
  761. ::setgrent();
  762. if (errno)
  763. return Error::from_syscall("getgrnam"sv, -errno);
  764. while (auto* gr = ::getgrent()) {
  765. if (errno)
  766. return Error::from_syscall("getgrnam"sv, -errno);
  767. if (gr->gr_name == name)
  768. return *gr;
  769. }
  770. if (errno)
  771. return Error::from_syscall("getgrnam"sv, -errno);
  772. else
  773. return Optional<struct group> {};
  774. }
  775. ErrorOr<void> clock_settime(clockid_t clock_id, struct timespec* ts)
  776. {
  777. #ifdef AK_OS_SERENITY
  778. int rc = syscall(SC_clock_settime, clock_id, ts);
  779. HANDLE_SYSCALL_RETURN_VALUE("clocksettime", rc, {});
  780. #else
  781. if (::clock_settime(clock_id, ts) < 0)
  782. return Error::from_syscall("clocksettime"sv, -errno);
  783. return {};
  784. #endif
  785. }
  786. static ALWAYS_INLINE ErrorOr<pid_t> posix_spawn_wrapper(StringView path, posix_spawn_file_actions_t const* file_actions, posix_spawnattr_t const* attr, char* const arguments[], char* const envp[], StringView function_name, decltype(::posix_spawn) spawn_function)
  787. {
  788. pid_t child_pid;
  789. if ((errno = spawn_function(&child_pid, path.to_deprecated_string().characters(), file_actions, attr, arguments, envp)))
  790. return Error::from_syscall(function_name, -errno);
  791. return child_pid;
  792. }
  793. ErrorOr<pid_t> posix_spawn(StringView path, posix_spawn_file_actions_t const* file_actions, posix_spawnattr_t const* attr, char* const arguments[], char* const envp[])
  794. {
  795. return posix_spawn_wrapper(path, file_actions, attr, arguments, envp, "posix_spawn"sv, ::posix_spawn);
  796. }
  797. ErrorOr<pid_t> posix_spawnp(StringView path, posix_spawn_file_actions_t* const file_actions, posix_spawnattr_t* const attr, char* const arguments[], char* const envp[])
  798. {
  799. return posix_spawn_wrapper(path, file_actions, attr, arguments, envp, "posix_spawnp"sv, ::posix_spawnp);
  800. }
  801. ErrorOr<off_t> lseek(int fd, off_t offset, int whence)
  802. {
  803. off_t rc = ::lseek(fd, offset, whence);
  804. if (rc < 0)
  805. return Error::from_syscall("lseek"sv, -errno);
  806. return rc;
  807. }
  808. ErrorOr<void> endgrent()
  809. {
  810. int old_errno = 0;
  811. swap(old_errno, errno);
  812. ::endgrent();
  813. if (errno != 0)
  814. return Error::from_syscall("endgrent"sv, -errno);
  815. errno = old_errno;
  816. return {};
  817. }
  818. ErrorOr<WaitPidResult> waitpid(pid_t waitee, int options)
  819. {
  820. int wstatus;
  821. pid_t pid = ::waitpid(waitee, &wstatus, options);
  822. if (pid < 0)
  823. return Error::from_syscall("waitpid"sv, -errno);
  824. return WaitPidResult { pid, wstatus };
  825. }
  826. ErrorOr<void> setuid(uid_t uid)
  827. {
  828. if (::setuid(uid) < 0)
  829. return Error::from_syscall("setuid"sv, -errno);
  830. return {};
  831. }
  832. ErrorOr<void> seteuid(uid_t uid)
  833. {
  834. if (::seteuid(uid) < 0)
  835. return Error::from_syscall("seteuid"sv, -errno);
  836. return {};
  837. }
  838. ErrorOr<void> setgid(gid_t gid)
  839. {
  840. if (::setgid(gid) < 0)
  841. return Error::from_syscall("setgid"sv, -errno);
  842. return {};
  843. }
  844. ErrorOr<void> setegid(gid_t gid)
  845. {
  846. if (::setegid(gid) < 0)
  847. return Error::from_syscall("setegid"sv, -errno);
  848. return {};
  849. }
  850. ErrorOr<void> setpgid(pid_t pid, pid_t pgid)
  851. {
  852. if (::setpgid(pid, pgid) < 0)
  853. return Error::from_syscall("setpgid"sv, -errno);
  854. return {};
  855. }
  856. ErrorOr<pid_t> setsid()
  857. {
  858. int rc = ::setsid();
  859. if (rc < 0)
  860. return Error::from_syscall("setsid"sv, -errno);
  861. return rc;
  862. }
  863. ErrorOr<pid_t> getsid(pid_t pid)
  864. {
  865. int rc = ::getsid(pid);
  866. if (rc < 0)
  867. return Error::from_syscall("getsid"sv, -errno);
  868. return rc;
  869. }
  870. ErrorOr<void> drop_privileges()
  871. {
  872. auto gid_result = setgid(getgid());
  873. auto uid_result = setuid(getuid());
  874. if (gid_result.is_error() || uid_result.is_error())
  875. return Error::from_string_literal("Failed to drop privileges");
  876. return {};
  877. }
  878. ErrorOr<bool> isatty(int fd)
  879. {
  880. int rc = ::isatty(fd);
  881. if (rc < 0)
  882. return Error::from_syscall("isatty"sv, -errno);
  883. return rc == 1;
  884. }
  885. ErrorOr<void> link(StringView old_path, StringView new_path)
  886. {
  887. #ifdef AK_OS_SERENITY
  888. Syscall::SC_link_params params {
  889. .old_path = { old_path.characters_without_null_termination(), old_path.length() },
  890. .new_path = { new_path.characters_without_null_termination(), new_path.length() },
  891. };
  892. int rc = syscall(SC_link, &params);
  893. HANDLE_SYSCALL_RETURN_VALUE("link", rc, {});
  894. #else
  895. DeprecatedString old_path_string = old_path;
  896. DeprecatedString new_path_string = new_path;
  897. if (::link(old_path_string.characters(), new_path_string.characters()) < 0)
  898. return Error::from_syscall("link"sv, -errno);
  899. return {};
  900. #endif
  901. }
  902. ErrorOr<void> symlink(StringView target, StringView link_path)
  903. {
  904. #ifdef AK_OS_SERENITY
  905. Syscall::SC_symlink_params params {
  906. .target = { target.characters_without_null_termination(), target.length() },
  907. .linkpath = { link_path.characters_without_null_termination(), link_path.length() },
  908. .dirfd = AT_FDCWD,
  909. };
  910. int rc = syscall(SC_symlink, &params);
  911. HANDLE_SYSCALL_RETURN_VALUE("symlink", rc, {});
  912. #else
  913. DeprecatedString target_string = target;
  914. DeprecatedString link_path_string = link_path;
  915. if (::symlink(target_string.characters(), link_path_string.characters()) < 0)
  916. return Error::from_syscall("symlink"sv, -errno);
  917. return {};
  918. #endif
  919. }
  920. ErrorOr<void> mkdir(StringView path, mode_t mode)
  921. {
  922. if (path.is_null())
  923. return Error::from_errno(EFAULT);
  924. #ifdef AK_OS_SERENITY
  925. int rc = syscall(SC_mkdir, AT_FDCWD, path.characters_without_null_termination(), path.length(), mode);
  926. HANDLE_SYSCALL_RETURN_VALUE("mkdir", rc, {});
  927. #else
  928. DeprecatedString path_string = path;
  929. if (::mkdir(path_string.characters(), mode) < 0)
  930. return Error::from_syscall("mkdir"sv, -errno);
  931. return {};
  932. #endif
  933. }
  934. ErrorOr<void> chdir(StringView path)
  935. {
  936. if (path.is_null())
  937. return Error::from_errno(EFAULT);
  938. #ifdef AK_OS_SERENITY
  939. int rc = syscall(SC_chdir, path.characters_without_null_termination(), path.length());
  940. HANDLE_SYSCALL_RETURN_VALUE("chdir", rc, {});
  941. #else
  942. DeprecatedString path_string = path;
  943. if (::chdir(path_string.characters()) < 0)
  944. return Error::from_syscall("chdir"sv, -errno);
  945. return {};
  946. #endif
  947. }
  948. ErrorOr<void> rmdir(StringView path)
  949. {
  950. if (path.is_null())
  951. return Error::from_errno(EFAULT);
  952. #ifdef AK_OS_SERENITY
  953. int rc = syscall(SC_rmdir, path.characters_without_null_termination(), path.length());
  954. HANDLE_SYSCALL_RETURN_VALUE("rmdir", rc, {});
  955. #else
  956. DeprecatedString path_string = path;
  957. if (::rmdir(path_string.characters()) < 0)
  958. return Error::from_syscall("rmdir"sv, -errno);
  959. return {};
  960. #endif
  961. }
  962. ErrorOr<pid_t> fork()
  963. {
  964. pid_t pid = ::fork();
  965. if (pid < 0)
  966. return Error::from_syscall("fork"sv, -errno);
  967. return pid;
  968. }
  969. ErrorOr<int> mkstemp(Span<char> pattern)
  970. {
  971. int fd = ::mkstemp(pattern.data());
  972. if (fd < 0)
  973. return Error::from_syscall("mkstemp"sv, -errno);
  974. return fd;
  975. }
  976. ErrorOr<String> mkdtemp(Span<char> pattern)
  977. {
  978. auto* path = ::mkdtemp(pattern.data());
  979. if (path == nullptr) {
  980. return Error::from_errno(errno);
  981. }
  982. return String::from_utf8(StringView { path, strlen(path) });
  983. }
  984. ErrorOr<void> rename(StringView old_path, StringView new_path)
  985. {
  986. if (old_path.is_null() || new_path.is_null())
  987. return Error::from_errno(EFAULT);
  988. #ifdef AK_OS_SERENITY
  989. Syscall::SC_rename_params params {
  990. .olddirfd = AT_FDCWD,
  991. .old_path = { old_path.characters_without_null_termination(), old_path.length() },
  992. .newdirfd = AT_FDCWD,
  993. .new_path = { new_path.characters_without_null_termination(), new_path.length() },
  994. };
  995. int rc = syscall(SC_rename, &params);
  996. HANDLE_SYSCALL_RETURN_VALUE("rename", rc, {});
  997. #else
  998. DeprecatedString old_path_string = old_path;
  999. DeprecatedString new_path_string = new_path;
  1000. if (::rename(old_path_string.characters(), new_path_string.characters()) < 0)
  1001. return Error::from_syscall("rename"sv, -errno);
  1002. return {};
  1003. #endif
  1004. }
  1005. ErrorOr<void> unlink(StringView path)
  1006. {
  1007. if (path.is_null())
  1008. return Error::from_errno(EFAULT);
  1009. #ifdef AK_OS_SERENITY
  1010. int rc = syscall(SC_unlink, AT_FDCWD, path.characters_without_null_termination(), path.length(), 0);
  1011. HANDLE_SYSCALL_RETURN_VALUE("unlink", rc, {});
  1012. #else
  1013. DeprecatedString path_string = path;
  1014. if (::unlink(path_string.characters()) < 0)
  1015. return Error::from_syscall("unlink"sv, -errno);
  1016. return {};
  1017. #endif
  1018. }
  1019. ErrorOr<void> utime(StringView path, Optional<struct utimbuf> maybe_buf)
  1020. {
  1021. if (path.is_null())
  1022. return Error::from_errno(EFAULT);
  1023. struct utimbuf* buf = nullptr;
  1024. if (maybe_buf.has_value())
  1025. buf = &maybe_buf.value();
  1026. #ifdef AK_OS_SERENITY
  1027. int rc = syscall(SC_utime, path.characters_without_null_termination(), path.length(), buf);
  1028. HANDLE_SYSCALL_RETURN_VALUE("utime", rc, {});
  1029. #else
  1030. DeprecatedString path_string = path;
  1031. if (::utime(path_string.characters(), buf) < 0)
  1032. return Error::from_syscall("utime"sv, -errno);
  1033. return {};
  1034. #endif
  1035. }
  1036. ErrorOr<void> utimensat(int fd, StringView path, struct timespec const times[2], int flag)
  1037. {
  1038. if (path.is_null())
  1039. return Error::from_errno(EFAULT);
  1040. #ifdef AK_OS_SERENITY
  1041. // POSIX allows AT_SYMLINK_NOFOLLOW flag or no flags.
  1042. if (flag & ~AT_SYMLINK_NOFOLLOW)
  1043. return Error::from_errno(EINVAL);
  1044. // Return early without error since both changes are to be omitted.
  1045. if (times && times[0].tv_nsec == UTIME_OMIT && times[1].tv_nsec == UTIME_OMIT)
  1046. return {};
  1047. // According to POSIX, when times is a nullptr, it's equivalent to setting
  1048. // both last access time and last modification time to the current time.
  1049. // Setting the times argument to nullptr if it matches this case prevents
  1050. // the need to copy it in the kernel.
  1051. if (times && times[0].tv_nsec == UTIME_NOW && times[1].tv_nsec == UTIME_NOW)
  1052. times = nullptr;
  1053. if (times) {
  1054. for (int i = 0; i < 2; ++i) {
  1055. if ((times[i].tv_nsec != UTIME_NOW && times[i].tv_nsec != UTIME_OMIT)
  1056. && (times[i].tv_nsec < 0 || times[i].tv_nsec >= 1'000'000'000L)) {
  1057. return Error::from_errno(EINVAL);
  1058. }
  1059. }
  1060. }
  1061. Syscall::SC_utimensat_params params {
  1062. .dirfd = fd,
  1063. .path = { path.characters_without_null_termination(), path.length() },
  1064. .times = times,
  1065. .flag = flag,
  1066. };
  1067. int rc = syscall(SC_utimensat, &params);
  1068. HANDLE_SYSCALL_RETURN_VALUE("utimensat", rc, {});
  1069. #else
  1070. auto builder = TRY(StringBuilder::create());
  1071. TRY(builder.try_append(path));
  1072. TRY(builder.try_append('\0'));
  1073. // Note the explicit null terminators above.
  1074. if (::utimensat(fd, builder.string_view().characters_without_null_termination(), times, flag) < 0)
  1075. return Error::from_syscall("utimensat"sv, -errno);
  1076. return {};
  1077. #endif
  1078. }
  1079. ErrorOr<struct utsname> uname()
  1080. {
  1081. struct utsname uts;
  1082. #ifdef AK_OS_SERENITY
  1083. int rc = syscall(SC_uname, &uts);
  1084. HANDLE_SYSCALL_RETURN_VALUE("uname", rc, uts);
  1085. #else
  1086. if (::uname(&uts) < 0)
  1087. return Error::from_syscall("uname"sv, -errno);
  1088. #endif
  1089. return uts;
  1090. }
  1091. #if !defined(AK_OS_ANDROID) && !defined(AK_OS_HAIKU)
  1092. ErrorOr<void> adjtime(const struct timeval* delta, struct timeval* old_delta)
  1093. {
  1094. # ifdef AK_OS_SERENITY
  1095. int rc = syscall(SC_adjtime, delta, old_delta);
  1096. HANDLE_SYSCALL_RETURN_VALUE("adjtime", rc, {});
  1097. # else
  1098. if (::adjtime(delta, old_delta) < 0)
  1099. return Error::from_syscall("adjtime"sv, -errno);
  1100. return {};
  1101. # endif
  1102. }
  1103. #endif
  1104. #ifdef AK_OS_SERENITY
  1105. ErrorOr<void> exec_command(Vector<StringView>& command, bool preserve_env)
  1106. {
  1107. Vector<StringView> exec_environment;
  1108. for (size_t i = 0; environ[i]; ++i) {
  1109. StringView env_view { environ[i], strlen(environ[i]) };
  1110. auto maybe_needle = env_view.find('=');
  1111. if (!maybe_needle.has_value())
  1112. continue;
  1113. // FIXME: Allow a custom selection of variables once ArgsParser supports options with optional parameters.
  1114. if (!preserve_env && env_view.substring_view(0, maybe_needle.value()) != "TERM"sv)
  1115. continue;
  1116. exec_environment.append(env_view);
  1117. }
  1118. TRY(Core::System::exec(command.at(0), command, Core::System::SearchInPath::Yes, exec_environment));
  1119. return {};
  1120. }
  1121. ErrorOr<void> join_jail(u64 jail_index)
  1122. {
  1123. Syscall::SC_jail_attach_params params { jail_index };
  1124. int rc = syscall(SC_jail_attach, &params);
  1125. HANDLE_SYSCALL_RETURN_VALUE("jail_attach", rc, {});
  1126. }
  1127. ErrorOr<u64> create_jail(StringView jail_name, JailIsolationFlags flags)
  1128. {
  1129. Syscall::SC_jail_create_params params { 0, { jail_name.characters_without_null_termination(), jail_name.length() }, static_cast<int>(flags) };
  1130. int rc = syscall(SC_jail_create, &params);
  1131. HANDLE_SYSCALL_RETURN_VALUE("jail_create", rc, static_cast<u64>(params.index));
  1132. }
  1133. #endif
  1134. ErrorOr<void> exec(StringView filename, ReadonlySpan<StringView> arguments, SearchInPath search_in_path, Optional<ReadonlySpan<StringView>> environment)
  1135. {
  1136. #ifdef AK_OS_SERENITY
  1137. Syscall::SC_execve_params params;
  1138. auto argument_strings = TRY(FixedArray<Syscall::StringArgument>::create(arguments.size()));
  1139. for (size_t i = 0; i < arguments.size(); ++i) {
  1140. argument_strings[i] = { arguments[i].characters_without_null_termination(), arguments[i].length() };
  1141. }
  1142. params.arguments.strings = argument_strings.data();
  1143. params.arguments.length = argument_strings.size();
  1144. size_t env_count = 0;
  1145. if (environment.has_value()) {
  1146. env_count = environment->size();
  1147. } else {
  1148. for (size_t i = 0; environ[i]; ++i)
  1149. ++env_count;
  1150. }
  1151. auto environment_strings = TRY(FixedArray<Syscall::StringArgument>::create(env_count));
  1152. if (environment.has_value()) {
  1153. for (size_t i = 0; i < env_count; ++i) {
  1154. environment_strings[i] = { environment->at(i).characters_without_null_termination(), environment->at(i).length() };
  1155. }
  1156. } else {
  1157. for (size_t i = 0; i < env_count; ++i) {
  1158. environment_strings[i] = { environ[i], strlen(environ[i]) };
  1159. }
  1160. }
  1161. params.environment.strings = environment_strings.data();
  1162. params.environment.length = environment_strings.size();
  1163. auto run_exec = [](Syscall::SC_execve_params& params) -> ErrorOr<void> {
  1164. int rc = syscall(Syscall::SC_execve, &params);
  1165. if (rc < 0)
  1166. return Error::from_syscall("exec"sv, rc);
  1167. return {};
  1168. };
  1169. StringView exec_filename;
  1170. String resolved_executable_path;
  1171. if (search_in_path == SearchInPath::Yes) {
  1172. auto executable_or_error = resolve_executable_from_environment(filename);
  1173. if (executable_or_error.is_error())
  1174. return executable_or_error.release_error();
  1175. resolved_executable_path = executable_or_error.release_value();
  1176. exec_filename = resolved_executable_path;
  1177. } else {
  1178. exec_filename = filename;
  1179. }
  1180. params.path = { exec_filename.characters_without_null_termination(), exec_filename.length() };
  1181. TRY(run_exec(params));
  1182. VERIFY_NOT_REACHED();
  1183. #else
  1184. DeprecatedString filename_string { filename };
  1185. auto argument_strings = TRY(FixedArray<DeprecatedString>::create(arguments.size()));
  1186. auto argv = TRY(FixedArray<char*>::create(arguments.size() + 1));
  1187. for (size_t i = 0; i < arguments.size(); ++i) {
  1188. argument_strings[i] = arguments[i].to_deprecated_string();
  1189. argv[i] = const_cast<char*>(argument_strings[i].characters());
  1190. }
  1191. argv[arguments.size()] = nullptr;
  1192. int rc = 0;
  1193. if (environment.has_value()) {
  1194. auto environment_strings = TRY(FixedArray<DeprecatedString>::create(environment->size()));
  1195. auto envp = TRY(FixedArray<char*>::create(environment->size() + 1));
  1196. for (size_t i = 0; i < environment->size(); ++i) {
  1197. environment_strings[i] = environment->at(i).to_deprecated_string();
  1198. envp[i] = const_cast<char*>(environment_strings[i].characters());
  1199. }
  1200. envp[environment->size()] = nullptr;
  1201. if (search_in_path == SearchInPath::Yes && !filename.contains('/')) {
  1202. # if defined(AK_OS_MACOS) || defined(AK_OS_FREEBSD) || defined(AK_OS_SOLARIS)
  1203. // These BSDs don't support execvpe(), so we'll have to manually search the PATH.
  1204. ScopedValueRollback errno_rollback(errno);
  1205. auto executable_or_error = resolve_executable_from_environment(filename_string);
  1206. if (executable_or_error.is_error()) {
  1207. errno_rollback.set_override_rollback_value(executable_or_error.error().code());
  1208. return executable_or_error.release_error();
  1209. }
  1210. DeprecatedString executable = executable_or_error.release_value().to_deprecated_string();
  1211. rc = ::execve(executable.characters(), argv.data(), envp.data());
  1212. # else
  1213. rc = ::execvpe(filename_string.characters(), argv.data(), envp.data());
  1214. # endif
  1215. } else {
  1216. rc = ::execve(filename_string.characters(), argv.data(), envp.data());
  1217. }
  1218. } else {
  1219. if (search_in_path == SearchInPath::Yes)
  1220. rc = ::execvp(filename_string.characters(), argv.data());
  1221. else
  1222. rc = ::execv(filename_string.characters(), argv.data());
  1223. }
  1224. if (rc < 0)
  1225. return Error::from_syscall("exec"sv, rc);
  1226. VERIFY_NOT_REACHED();
  1227. #endif
  1228. }
  1229. ErrorOr<int> socket(int domain, int type, int protocol)
  1230. {
  1231. auto fd = ::socket(domain, type, protocol);
  1232. if (fd < 0)
  1233. return Error::from_syscall("socket"sv, -errno);
  1234. return fd;
  1235. }
  1236. ErrorOr<void> bind(int sockfd, struct sockaddr const* address, socklen_t address_length)
  1237. {
  1238. if (::bind(sockfd, address, address_length) < 0)
  1239. return Error::from_syscall("bind"sv, -errno);
  1240. return {};
  1241. }
  1242. ErrorOr<void> listen(int sockfd, int backlog)
  1243. {
  1244. if (::listen(sockfd, backlog) < 0)
  1245. return Error::from_syscall("listen"sv, -errno);
  1246. return {};
  1247. }
  1248. ErrorOr<int> accept(int sockfd, struct sockaddr* address, socklen_t* address_length)
  1249. {
  1250. auto fd = ::accept(sockfd, address, address_length);
  1251. if (fd < 0)
  1252. return Error::from_syscall("accept"sv, -errno);
  1253. return fd;
  1254. }
  1255. ErrorOr<void> connect(int sockfd, struct sockaddr const* address, socklen_t address_length)
  1256. {
  1257. if (::connect(sockfd, address, address_length) < 0)
  1258. return Error::from_syscall("connect"sv, -errno);
  1259. return {};
  1260. }
  1261. ErrorOr<void> shutdown(int sockfd, int how)
  1262. {
  1263. if (::shutdown(sockfd, how) < 0)
  1264. return Error::from_syscall("shutdown"sv, -errno);
  1265. return {};
  1266. }
  1267. ErrorOr<ssize_t> send(int sockfd, void const* buffer, size_t buffer_length, int flags)
  1268. {
  1269. auto sent = ::send(sockfd, buffer, buffer_length, flags);
  1270. if (sent < 0)
  1271. return Error::from_syscall("send"sv, -errno);
  1272. return sent;
  1273. }
  1274. ErrorOr<ssize_t> sendmsg(int sockfd, const struct msghdr* message, int flags)
  1275. {
  1276. auto sent = ::sendmsg(sockfd, message, flags);
  1277. if (sent < 0)
  1278. return Error::from_syscall("sendmsg"sv, -errno);
  1279. return sent;
  1280. }
  1281. ErrorOr<ssize_t> sendto(int sockfd, void const* source, size_t source_length, int flags, struct sockaddr const* destination, socklen_t destination_length)
  1282. {
  1283. auto sent = ::sendto(sockfd, source, source_length, flags, destination, destination_length);
  1284. if (sent < 0)
  1285. return Error::from_syscall("sendto"sv, -errno);
  1286. return sent;
  1287. }
  1288. ErrorOr<ssize_t> recv(int sockfd, void* buffer, size_t length, int flags)
  1289. {
  1290. auto received = ::recv(sockfd, buffer, length, flags);
  1291. if (received < 0)
  1292. return Error::from_syscall("recv"sv, -errno);
  1293. return received;
  1294. }
  1295. ErrorOr<ssize_t> recvmsg(int sockfd, struct msghdr* message, int flags)
  1296. {
  1297. auto received = ::recvmsg(sockfd, message, flags);
  1298. if (received < 0)
  1299. return Error::from_syscall("recvmsg"sv, -errno);
  1300. return received;
  1301. }
  1302. ErrorOr<ssize_t> recvfrom(int sockfd, void* buffer, size_t buffer_length, int flags, struct sockaddr* address, socklen_t* address_length)
  1303. {
  1304. auto received = ::recvfrom(sockfd, buffer, buffer_length, flags, address, address_length);
  1305. if (received < 0)
  1306. return Error::from_syscall("recvfrom"sv, -errno);
  1307. return received;
  1308. }
  1309. ErrorOr<AddressInfoVector> getaddrinfo(char const* nodename, char const* servname, struct addrinfo const& hints)
  1310. {
  1311. struct addrinfo* results = nullptr;
  1312. int const rc = ::getaddrinfo(nodename, servname, &hints, &results);
  1313. if (rc != 0) {
  1314. if (rc == EAI_SYSTEM) {
  1315. return Error::from_syscall("getaddrinfo"sv, -errno);
  1316. }
  1317. auto const* error_string = gai_strerror(rc);
  1318. return Error::from_string_view({ error_string, strlen(error_string) });
  1319. }
  1320. Vector<struct addrinfo> addresses;
  1321. for (auto* result = results; result != nullptr; result = result->ai_next)
  1322. TRY(addresses.try_append(*result));
  1323. return AddressInfoVector { move(addresses), results };
  1324. }
  1325. ErrorOr<void> getsockopt(int sockfd, int level, int option, void* value, socklen_t* value_size)
  1326. {
  1327. if (::getsockopt(sockfd, level, option, value, value_size) < 0)
  1328. return Error::from_syscall("getsockopt"sv, -errno);
  1329. return {};
  1330. }
  1331. ErrorOr<void> setsockopt(int sockfd, int level, int option, void const* value, socklen_t value_size)
  1332. {
  1333. if (::setsockopt(sockfd, level, option, value, value_size) < 0)
  1334. return Error::from_syscall("setsockopt"sv, -errno);
  1335. return {};
  1336. }
  1337. ErrorOr<void> getsockname(int sockfd, struct sockaddr* address, socklen_t* address_length)
  1338. {
  1339. if (::getsockname(sockfd, address, address_length) < 0)
  1340. return Error::from_syscall("getsockname"sv, -errno);
  1341. return {};
  1342. }
  1343. ErrorOr<void> getpeername(int sockfd, struct sockaddr* address, socklen_t* address_length)
  1344. {
  1345. if (::getpeername(sockfd, address, address_length) < 0)
  1346. return Error::from_syscall("getpeername"sv, -errno);
  1347. return {};
  1348. }
  1349. ErrorOr<void> socketpair(int domain, int type, int protocol, int sv[2])
  1350. {
  1351. if (::socketpair(domain, type, protocol, sv) < 0)
  1352. return Error::from_syscall("socketpair"sv, -errno);
  1353. return {};
  1354. }
  1355. ErrorOr<Array<int, 2>> pipe2([[maybe_unused]] int flags)
  1356. {
  1357. Array<int, 2> fds;
  1358. #if defined(__unix__)
  1359. if (::pipe2(fds.data(), flags) < 0)
  1360. return Error::from_syscall("pipe2"sv, -errno);
  1361. #else
  1362. if (::pipe(fds.data()) < 0)
  1363. return Error::from_syscall("pipe2"sv, -errno);
  1364. #endif
  1365. return fds;
  1366. }
  1367. ErrorOr<Vector<gid_t>> getgroups()
  1368. {
  1369. int count = ::getgroups(0, nullptr);
  1370. if (count < 0)
  1371. return Error::from_syscall("getgroups"sv, -errno);
  1372. if (count == 0)
  1373. return Vector<gid_t> {};
  1374. Vector<gid_t> groups;
  1375. TRY(groups.try_resize(count));
  1376. if (::getgroups(count, groups.data()) < 0)
  1377. return Error::from_syscall("getgroups"sv, -errno);
  1378. return groups;
  1379. }
  1380. ErrorOr<void> setgroups(ReadonlySpan<gid_t> gids)
  1381. {
  1382. if (::setgroups(gids.size(), gids.data()) < 0)
  1383. return Error::from_syscall("setgroups"sv, -errno);
  1384. return {};
  1385. }
  1386. ErrorOr<void> mknod(StringView pathname, mode_t mode, dev_t dev)
  1387. {
  1388. if (pathname.is_null())
  1389. return Error::from_syscall("mknod"sv, -EFAULT);
  1390. #ifdef AK_OS_SERENITY
  1391. Syscall::SC_mknod_params params { { pathname.characters_without_null_termination(), pathname.length() }, mode, dev };
  1392. int rc = syscall(SC_mknod, &params);
  1393. HANDLE_SYSCALL_RETURN_VALUE("mknod", rc, {});
  1394. #else
  1395. DeprecatedString path_string = pathname;
  1396. if (::mknod(path_string.characters(), mode, dev) < 0)
  1397. return Error::from_syscall("mknod"sv, -errno);
  1398. return {};
  1399. #endif
  1400. }
  1401. ErrorOr<void> mkfifo(StringView pathname, mode_t mode)
  1402. {
  1403. return mknod(pathname, mode | S_IFIFO, 0);
  1404. }
  1405. ErrorOr<void> setenv(StringView name, StringView value, bool overwrite)
  1406. {
  1407. auto builder = TRY(StringBuilder::create());
  1408. TRY(builder.try_append(name));
  1409. TRY(builder.try_append('\0'));
  1410. TRY(builder.try_append(value));
  1411. TRY(builder.try_append('\0'));
  1412. // Note the explicit null terminators above.
  1413. auto c_name = builder.string_view().characters_without_null_termination();
  1414. auto c_value = c_name + name.length() + 1;
  1415. auto rc = ::setenv(c_name, c_value, overwrite);
  1416. if (rc < 0)
  1417. return Error::from_errno(errno);
  1418. return {};
  1419. }
  1420. ErrorOr<void> putenv(StringView env)
  1421. {
  1422. #ifdef AK_OS_SERENITY
  1423. auto rc = serenity_putenv(env.characters_without_null_termination(), env.length());
  1424. #else
  1425. // Leak somewhat unavoidable here due to the putenv API.
  1426. auto leaked_new_env = strndup(env.characters_without_null_termination(), env.length());
  1427. auto rc = ::putenv(leaked_new_env);
  1428. #endif
  1429. if (rc < 0)
  1430. return Error::from_errno(errno);
  1431. return {};
  1432. }
  1433. ErrorOr<int> posix_openpt(int flags)
  1434. {
  1435. int const rc = ::posix_openpt(flags);
  1436. if (rc < 0)
  1437. return Error::from_syscall("posix_openpt"sv, -errno);
  1438. return rc;
  1439. }
  1440. ErrorOr<void> grantpt(int fildes)
  1441. {
  1442. auto const rc = ::grantpt(fildes);
  1443. if (rc < 0)
  1444. return Error::from_syscall("grantpt"sv, -errno);
  1445. return {};
  1446. }
  1447. ErrorOr<void> unlockpt(int fildes)
  1448. {
  1449. auto const rc = ::unlockpt(fildes);
  1450. if (rc < 0)
  1451. return Error::from_syscall("unlockpt"sv, -errno);
  1452. return {};
  1453. }
  1454. ErrorOr<void> access(StringView pathname, int mode, int flags)
  1455. {
  1456. if (pathname.is_null())
  1457. return Error::from_syscall("access"sv, -EFAULT);
  1458. #ifdef AK_OS_SERENITY
  1459. Syscall::SC_faccessat_params params {
  1460. .dirfd = AT_FDCWD,
  1461. .pathname = { pathname.characters_without_null_termination(), pathname.length() },
  1462. .mode = mode,
  1463. .flags = flags,
  1464. };
  1465. int rc = ::syscall(Syscall::SC_faccessat, &params);
  1466. HANDLE_SYSCALL_RETURN_VALUE("access", rc, {});
  1467. #else
  1468. DeprecatedString path_string = pathname;
  1469. (void)flags;
  1470. if (::access(path_string.characters(), mode) < 0)
  1471. return Error::from_syscall("access"sv, -errno);
  1472. return {};
  1473. #endif
  1474. }
  1475. ErrorOr<DeprecatedString> readlink(StringView pathname)
  1476. {
  1477. // FIXME: Try again with a larger buffer.
  1478. #ifdef AK_OS_SERENITY
  1479. char data[PATH_MAX];
  1480. Syscall::SC_readlink_params small_params {
  1481. .path = { pathname.characters_without_null_termination(), pathname.length() },
  1482. .buffer = { data, sizeof(data) },
  1483. .dirfd = AT_FDCWD,
  1484. };
  1485. int rc = syscall(SC_readlink, &small_params);
  1486. HANDLE_SYSCALL_RETURN_VALUE("readlink", rc, DeprecatedString(data, rc));
  1487. #elif defined(AK_OS_GNU_HURD)
  1488. // PATH_MAX is not defined, nor is there an upper limit on path lengths.
  1489. // Let's do this the right way.
  1490. int fd = TRY(open(pathname, O_READ | O_NOLINK));
  1491. auto file = TRY(File::adopt_fd(fd, File::OpenMode::Read));
  1492. auto buffer = TRY(file->read_until_eof());
  1493. // TODO: Get rid of this copy here.
  1494. return DeprecatedString::copy(buffer);
  1495. #else
  1496. char data[PATH_MAX];
  1497. DeprecatedString path_string = pathname;
  1498. int rc = ::readlink(path_string.characters(), data, sizeof(data));
  1499. if (rc == -1)
  1500. return Error::from_syscall("readlink"sv, -errno);
  1501. return DeprecatedString(data, rc);
  1502. #endif
  1503. }
  1504. ErrorOr<int> poll(Span<struct pollfd> poll_fds, int timeout)
  1505. {
  1506. auto const rc = ::poll(poll_fds.data(), poll_fds.size(), timeout);
  1507. if (rc < 0)
  1508. return Error::from_syscall("poll"sv, -errno);
  1509. return { rc };
  1510. }
  1511. #ifdef AK_OS_SERENITY
  1512. ErrorOr<void> posix_fallocate(int fd, off_t offset, off_t length)
  1513. {
  1514. int rc = ::posix_fallocate(fd, offset, length);
  1515. if (rc != 0)
  1516. return Error::from_syscall("posix_fallocate"sv, -rc);
  1517. return {};
  1518. }
  1519. #endif
  1520. // This constant is copied from LibFileSystem. We cannot use or even include it directly,
  1521. // because that would cause a dependency of LibCore on LibFileSystem, effectively rendering
  1522. // the distinction between these libraries moot.
  1523. static constexpr StringView INTERNAL_DEFAULT_PATH_SV = "/usr/local/sbin:/usr/local/bin:/usr/bin:/bin"sv;
  1524. ErrorOr<String> resolve_executable_from_environment(StringView filename, int flags)
  1525. {
  1526. if (filename.is_empty())
  1527. return Error::from_errno(ENOENT);
  1528. // Paths that aren't just a file name generally count as already resolved.
  1529. if (filename.contains('/')) {
  1530. TRY(Core::System::access(filename, X_OK, flags));
  1531. return TRY(String::from_utf8(filename));
  1532. }
  1533. auto const* path_str = ::getenv("PATH");
  1534. StringView path;
  1535. if (path_str)
  1536. path = { path_str, strlen(path_str) };
  1537. if (path.is_empty())
  1538. path = INTERNAL_DEFAULT_PATH_SV;
  1539. auto directories = path.split_view(':');
  1540. for (auto directory : directories) {
  1541. auto file = TRY(String::formatted("{}/{}", directory, filename));
  1542. if (!Core::System::access(file, X_OK, flags).is_error())
  1543. return file;
  1544. }
  1545. return Error::from_errno(ENOENT);
  1546. }
  1547. char** environment()
  1548. {
  1549. #if defined(AK_OS_MACOS)
  1550. return *_NSGetEnviron();
  1551. #else
  1552. return environ;
  1553. #endif
  1554. }
  1555. ErrorOr<String> current_executable_path()
  1556. {
  1557. char path[4096] = {};
  1558. #if defined(AK_OS_LINUX) || defined(AK_OS_ANDROID) || defined(AK_OS_SERENITY)
  1559. auto ret = ::readlink("/proc/self/exe", path, sizeof(path) - 1);
  1560. // Ignore error if it wasn't a symlink
  1561. if (ret == -1 && errno != EINVAL)
  1562. return Error::from_syscall("readlink"sv, -errno);
  1563. #elif defined(AK_OS_GNU_HURD)
  1564. // We could read /proc/self/exe, but why rely on procfs being mounted
  1565. // if we can do the same thing procfs does and ask the proc server directly?
  1566. process_t proc = getproc();
  1567. if (!MACH_PORT_VALID(proc))
  1568. return Error::from_syscall("getproc"sv, -errno);
  1569. kern_return_t err = proc_get_exe(proc, getpid(), path);
  1570. mach_port_deallocate(mach_task_self(), proc);
  1571. if (err) {
  1572. __hurd_fail(static_cast<error_t>(err));
  1573. return Error::from_syscall("proc_get_exe"sv, -errno);
  1574. }
  1575. #elif defined(AK_OS_DRAGONFLY)
  1576. return String::from_deprecated_string(TRY(readlink("/proc/curproc/file"sv)));
  1577. #elif defined(AK_OS_SOLARIS)
  1578. return String::from_deprecated_string(TRY(readlink("/proc/self/path/a.out"sv)));
  1579. #elif defined(AK_OS_FREEBSD)
  1580. int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
  1581. size_t len = sizeof(path);
  1582. if (sysctl(mib, 4, path, &len, nullptr, 0) < 0)
  1583. return Error::from_syscall("sysctl"sv, -errno);
  1584. #elif defined(AK_OS_NETBSD)
  1585. int mib[4] = { CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME };
  1586. size_t len = sizeof(path);
  1587. if (sysctl(mib, 4, path, &len, nullptr, 0) < 0)
  1588. return Error::from_syscall("sysctl"sv, -errno);
  1589. #elif defined(AK_OS_MACOS)
  1590. u32 size = sizeof(path);
  1591. auto ret = _NSGetExecutablePath(path, &size);
  1592. if (ret != 0)
  1593. return Error::from_errno(ENAMETOOLONG);
  1594. #elif defined(AK_OS_HAIKU)
  1595. image_info info = {};
  1596. for (int32 cookie { 0 }; get_next_image_info(B_CURRENT_TEAM, &cookie, &info) == B_OK && info.type != B_APP_IMAGE;)
  1597. ;
  1598. if (info.type != B_APP_IMAGE)
  1599. return Error::from_string_view("current_executable_path() failed"sv);
  1600. if (sizeof(info.name) > sizeof(path))
  1601. return Error::from_errno(ENAMETOOLONG);
  1602. strlcpy(path, info.name, sizeof(path) - 1);
  1603. #elif defined(AK_OS_EMSCRIPTEN)
  1604. return Error::from_string_view("current_executable_path() unknown on this platform"sv);
  1605. #else
  1606. # warning "Not sure how to get current_executable_path on this platform!"
  1607. // GetModuleFileName on Windows, unsure about OpenBSD.
  1608. return Error::from_string_view("current_executable_path unknown"sv);
  1609. #endif
  1610. path[sizeof(path) - 1] = '\0';
  1611. return String::from_utf8({ path, strlen(path) });
  1612. }
  1613. }