System.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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. #endif
  39. ErrorOr<void> sigaction(int signal, struct sigaction const* action, struct sigaction* old_action)
  40. {
  41. if (::sigaction(signal, action, old_action) < 0)
  42. return Error::from_syscall("sigaction"sv, -errno);
  43. return {};
  44. }
  45. ErrorOr<struct stat> fstat(int fd)
  46. {
  47. struct stat st = {};
  48. if (::fstat(fd, &st) < 0)
  49. return Error::from_syscall("fstat"sv, -errno);
  50. return st;
  51. }
  52. ErrorOr<int> fcntl(int fd, int command, ...)
  53. {
  54. va_list ap;
  55. va_start(ap, command);
  56. u32 extra_arg = va_arg(ap, u32);
  57. int rc = ::fcntl(fd, command, extra_arg);
  58. va_end(ap);
  59. if (rc < 0)
  60. return Error::from_syscall("fcntl"sv, -errno);
  61. return rc;
  62. }
  63. 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)
  64. {
  65. #ifdef __serenity__
  66. Syscall::SC_mmap_params params { (uintptr_t)address, size, alignment, protection, flags, fd, offset, { name.characters_without_null_termination(), name.length() } };
  67. ptrdiff_t rc = syscall(SC_mmap, &params);
  68. if (rc < 0 && rc > -EMAXERRNO)
  69. return Error::from_syscall("mmap"sv, rc);
  70. return reinterpret_cast<void*>(rc);
  71. #else
  72. // NOTE: Regular POSIX mmap() doesn't support custom alignment requests.
  73. VERIFY(!alignment);
  74. auto* ptr = ::mmap(address, size, protection, flags, fd, offset);
  75. if (ptr == MAP_FAILED)
  76. return Error::from_syscall("mmap"sv, -errno);
  77. return ptr;
  78. #endif
  79. }
  80. ErrorOr<void> munmap(void* address, size_t size)
  81. {
  82. if (::munmap(address, size) < 0)
  83. return Error::from_syscall("munmap"sv, -errno);
  84. return {};
  85. }
  86. ErrorOr<int> open(StringView path, int options, ...)
  87. {
  88. if (!path.characters_without_null_termination())
  89. return Error::from_syscall("open"sv, -EFAULT);
  90. va_list ap;
  91. va_start(ap, options);
  92. auto mode = (mode_t)va_arg(ap, unsigned);
  93. va_end(ap);
  94. #ifdef __serenity__
  95. Syscall::SC_open_params params { AT_FDCWD, { path.characters_without_null_termination(), path.length() }, options, mode };
  96. int rc = syscall(SC_open, &params);
  97. HANDLE_SYSCALL_RETURN_VALUE("open"sv, rc, rc);
  98. #else
  99. // NOTE: We have to ensure that the path is null-terminated.
  100. String path_string = path;
  101. int rc = ::open(path_string.characters(), options, mode);
  102. if (rc < 0)
  103. return Error::from_syscall("open"sv, -errno);
  104. return rc;
  105. #endif
  106. }
  107. ErrorOr<void> close(int fd)
  108. {
  109. if (::close(fd) < 0)
  110. return Error::from_syscall("close"sv, -errno);
  111. return {};
  112. }
  113. ErrorOr<void> ftruncate(int fd, off_t length)
  114. {
  115. if (::ftruncate(fd, length) < 0)
  116. return Error::from_syscall("ftruncate"sv, -errno);
  117. return {};
  118. }
  119. ErrorOr<struct stat> stat(StringView path)
  120. {
  121. if (!path.characters_without_null_termination())
  122. return Error::from_syscall("stat"sv, -EFAULT);
  123. struct stat st = {};
  124. #ifdef __serenity__
  125. Syscall::SC_stat_params params { { path.characters_without_null_termination(), path.length() }, &st, AT_FDCWD, true };
  126. int rc = syscall(SC_stat, &params);
  127. HANDLE_SYSCALL_RETURN_VALUE("stat"sv, rc, st);
  128. #else
  129. String path_string = path;
  130. if (::stat(path_string.characters(), &st) < 0)
  131. return Error::from_syscall("stat"sv, -errno);
  132. return st;
  133. #endif
  134. }
  135. ErrorOr<ssize_t> read(int fd, void* buffer, size_t buffer_size)
  136. {
  137. ssize_t rc = ::read(fd, buffer, buffer_size);
  138. if (rc < 0)
  139. return Error::from_syscall("read"sv, -errno);
  140. return rc;
  141. }
  142. ErrorOr<ssize_t> write(int fd, void const* data, size_t data_size)
  143. {
  144. ssize_t rc = ::write(fd, data, data_size);
  145. if (rc < 0)
  146. return Error::from_syscall("write"sv, -errno);
  147. return rc;
  148. }
  149. }