System.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /*
  2. * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/String.h>
  7. #include <LibCore/System.h>
  8. #include <LibSystem/syscall.h>
  9. #include <fcntl.h>
  10. #include <stdarg.h>
  11. #include <sys/mman.h>
  12. #include <unistd.h>
  13. #define HANDLE_SYSCALL_RETURN_VALUE(syscall_name, rc, success_value) \
  14. if ((rc) < 0) { \
  15. return Error::from_syscall(syscall_name, rc); \
  16. } \
  17. return success_value;
  18. namespace Core::System {
  19. #ifdef __serenity__
  20. ErrorOr<void> pledge(StringView promises, StringView execpromises)
  21. {
  22. Syscall::SC_pledge_params params {
  23. { promises.characters_without_null_termination(), promises.length() },
  24. { execpromises.characters_without_null_termination(), execpromises.length() },
  25. };
  26. int rc = syscall(SC_pledge, &params);
  27. HANDLE_SYSCALL_RETURN_VALUE("pledge"sv, rc, {});
  28. }
  29. ErrorOr<void> unveil(StringView path, StringView permissions)
  30. {
  31. Syscall::SC_unveil_params params {
  32. { path.characters_without_null_termination(), path.length() },
  33. { permissions.characters_without_null_termination(), permissions.length() },
  34. };
  35. int rc = syscall(SC_unveil, &params);
  36. HANDLE_SYSCALL_RETURN_VALUE("unveil"sv, rc, {});
  37. }
  38. ErrorOr<Array<int, 2>> pipe2(int flags)
  39. {
  40. Array<int, 2> fds;
  41. if (::pipe2(fds.data(), flags) < 0)
  42. return Error::from_syscall("pipe2"sv, -errno);
  43. return fds;
  44. }
  45. #endif
  46. ErrorOr<void> sigaction(int signal, struct sigaction const* action, struct sigaction* old_action)
  47. {
  48. if (::sigaction(signal, action, old_action) < 0)
  49. return Error::from_syscall("sigaction"sv, -errno);
  50. return {};
  51. }
  52. ErrorOr<struct stat> fstat(int fd)
  53. {
  54. struct stat st = {};
  55. if (::fstat(fd, &st) < 0)
  56. return Error::from_syscall("fstat"sv, -errno);
  57. return st;
  58. }
  59. ErrorOr<int> fcntl(int fd, int command, ...)
  60. {
  61. va_list ap;
  62. va_start(ap, command);
  63. u32 extra_arg = va_arg(ap, u32);
  64. int rc = ::fcntl(fd, command, extra_arg);
  65. va_end(ap);
  66. if (rc < 0)
  67. return Error::from_syscall("fcntl"sv, -errno);
  68. return rc;
  69. }
  70. 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)
  71. {
  72. #ifdef __serenity__
  73. Syscall::SC_mmap_params params { (uintptr_t)address, size, alignment, protection, flags, fd, offset, { name.characters_without_null_termination(), name.length() } };
  74. ptrdiff_t rc = syscall(SC_mmap, &params);
  75. if (rc < 0 && rc > -EMAXERRNO)
  76. return Error::from_syscall("mmap"sv, rc);
  77. return reinterpret_cast<void*>(rc);
  78. #else
  79. // NOTE: Regular POSIX mmap() doesn't support custom alignment requests.
  80. VERIFY(!alignment);
  81. auto* ptr = ::mmap(address, size, protection, flags, fd, offset);
  82. if (ptr == MAP_FAILED)
  83. return Error::from_syscall("mmap"sv, -errno);
  84. return ptr;
  85. #endif
  86. }
  87. ErrorOr<void> munmap(void* address, size_t size)
  88. {
  89. if (::munmap(address, size) < 0)
  90. return Error::from_syscall("munmap"sv, -errno);
  91. return {};
  92. }
  93. ErrorOr<int> open(StringView path, int options, ...)
  94. {
  95. if (!path.characters_without_null_termination())
  96. return Error::from_syscall("open"sv, -EFAULT);
  97. va_list ap;
  98. va_start(ap, options);
  99. auto mode = (mode_t)va_arg(ap, unsigned);
  100. va_end(ap);
  101. #ifdef __serenity__
  102. Syscall::SC_open_params params { AT_FDCWD, { path.characters_without_null_termination(), path.length() }, options, mode };
  103. int rc = syscall(SC_open, &params);
  104. HANDLE_SYSCALL_RETURN_VALUE("open"sv, rc, rc);
  105. #else
  106. // NOTE: We have to ensure that the path is null-terminated.
  107. String path_string = path;
  108. int rc = ::open(path_string.characters(), options, mode);
  109. if (rc < 0)
  110. return Error::from_syscall("open"sv, -errno);
  111. return rc;
  112. #endif
  113. }
  114. ErrorOr<void> close(int fd)
  115. {
  116. if (::close(fd) < 0)
  117. return Error::from_syscall("close"sv, -errno);
  118. return {};
  119. }
  120. ErrorOr<void> ftruncate(int fd, off_t length)
  121. {
  122. if (::ftruncate(fd, length) < 0)
  123. return Error::from_syscall("ftruncate"sv, -errno);
  124. return {};
  125. }
  126. ErrorOr<struct stat> stat(StringView path)
  127. {
  128. if (!path.characters_without_null_termination())
  129. return Error::from_syscall("stat"sv, -EFAULT);
  130. struct stat st = {};
  131. #ifdef __serenity__
  132. Syscall::SC_stat_params params { { path.characters_without_null_termination(), path.length() }, &st, AT_FDCWD, true };
  133. int rc = syscall(SC_stat, &params);
  134. HANDLE_SYSCALL_RETURN_VALUE("stat"sv, rc, st);
  135. #else
  136. String path_string = path;
  137. if (::stat(path_string.characters(), &st) < 0)
  138. return Error::from_syscall("stat"sv, -errno);
  139. return st;
  140. #endif
  141. }
  142. ErrorOr<ssize_t> read(int fd, void* buffer, size_t buffer_size)
  143. {
  144. ssize_t rc = ::read(fd, buffer, buffer_size);
  145. if (rc < 0)
  146. return Error::from_syscall("read"sv, -errno);
  147. return rc;
  148. }
  149. ErrorOr<ssize_t> write(int fd, void const* data, size_t data_size)
  150. {
  151. ssize_t rc = ::write(fd, data, data_size);
  152. if (rc < 0)
  153. return Error::from_syscall("write"sv, -errno);
  154. return rc;
  155. }
  156. ErrorOr<void> kill(pid_t pid, int signal)
  157. {
  158. if (::kill(pid, signal) < 0)
  159. return Error::from_syscall("kill"sv, -errno);
  160. return {};
  161. }
  162. ErrorOr<int> dup2(int source_fd, int destination_fd)
  163. {
  164. int fd = ::dup2(source_fd, destination_fd);
  165. if (fd < 0)
  166. return Error::from_syscall("dup2"sv, -errno);
  167. return fd;
  168. }
  169. ErrorOr<String> ptsname(int fd)
  170. {
  171. auto* name = ::ptsname(fd);
  172. if (!name)
  173. return Error::from_syscall("ptsname"sv, -errno);
  174. return String(name);
  175. }
  176. }