Syscalls.swift 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. /*
  2. This source file is part of the Swift System open source project
  3. Copyright (c) 2020 - 2026 Apple Inc. and the Swift System project authors
  4. Licensed under Apache License v2.0 with Runtime Library Exception
  5. See https://swift.org/LICENSE.txt for license information
  6. */
  7. import CSystem
  8. #if SYSTEM_PACKAGE_DARWIN
  9. import Darwin
  10. #elseif canImport(Glibc)
  11. import Glibc
  12. #elseif canImport(Musl)
  13. import Musl
  14. #elseif canImport(WASILibc)
  15. import WASILibc
  16. #elseif os(Windows)
  17. import ucrt
  18. #elseif canImport(Android)
  19. import Android
  20. #else
  21. #error("Unsupported Platform")
  22. #endif
  23. // Interacting with the mocking system, tracing, etc., is a potentially significant
  24. // amount of code size, so we hand outline that code for every syscall
  25. // open
  26. internal func system_open(
  27. _ path: UnsafePointer<CInterop.PlatformChar>, _ oflag: Int32
  28. ) -> CInt {
  29. #if ENABLE_MOCKING
  30. if mockingEnabled {
  31. return _mock(path: path, oflag)
  32. }
  33. #endif
  34. return open(path, oflag)
  35. }
  36. internal func system_open(
  37. _ path: UnsafePointer<CInterop.PlatformChar>,
  38. _ oflag: Int32, _ mode: CInterop.Mode
  39. ) -> CInt {
  40. #if ENABLE_MOCKING
  41. if mockingEnabled {
  42. return _mock(path: path, oflag, mode)
  43. }
  44. #endif
  45. return open(path, oflag, mode)
  46. }
  47. // close
  48. internal func system_close(_ fd: Int32) -> Int32 {
  49. #if ENABLE_MOCKING
  50. if mockingEnabled { return _mock(fd) }
  51. #endif
  52. return close(fd)
  53. }
  54. // read
  55. internal func system_read(
  56. _ fd: Int32, _ buf: UnsafeMutableRawPointer?, _ nbyte: Int
  57. ) -> Int {
  58. #if ENABLE_MOCKING
  59. if mockingEnabled { return _mockInt(fd, buf, nbyte) }
  60. #endif
  61. return read(fd, buf, nbyte)
  62. }
  63. // pread
  64. internal func system_pread(
  65. _ fd: Int32, _ buf: UnsafeMutableRawPointer?, _ nbyte: Int, _ offset: off_t
  66. ) -> Int {
  67. #if ENABLE_MOCKING
  68. if mockingEnabled { return _mockInt(fd, buf, nbyte, offset) }
  69. #endif
  70. #if os(Android)
  71. var zero = UInt8.zero
  72. return withUnsafeMutablePointer(to: &zero) {
  73. // this pread has a non-nullable `buf` pointer
  74. pread(fd, buf ?? UnsafeMutableRawPointer($0), nbyte, offset)
  75. }
  76. #else
  77. return pread(fd, buf, nbyte, offset)
  78. #endif
  79. }
  80. // lseek
  81. internal func system_lseek(
  82. _ fd: Int32, _ off: off_t, _ whence: Int32
  83. ) -> off_t {
  84. #if ENABLE_MOCKING
  85. if mockingEnabled { return _mockOffT(fd, off, whence) }
  86. #endif
  87. return lseek(fd, off, whence)
  88. }
  89. // write
  90. internal func system_write(
  91. _ fd: Int32, _ buf: UnsafeRawPointer?, _ nbyte: Int
  92. ) -> Int {
  93. #if ENABLE_MOCKING
  94. if mockingEnabled { return _mockInt(fd, buf, nbyte) }
  95. #endif
  96. return write(fd, buf, nbyte)
  97. }
  98. // pwrite
  99. internal func system_pwrite(
  100. _ fd: Int32, _ buf: UnsafeRawPointer?, _ nbyte: Int, _ offset: off_t
  101. ) -> Int {
  102. #if ENABLE_MOCKING
  103. if mockingEnabled { return _mockInt(fd, buf, nbyte, offset) }
  104. #endif
  105. #if os(Android)
  106. var zero = UInt8.zero
  107. return withUnsafeMutablePointer(to: &zero) {
  108. // this pwrite has a non-nullable `buf` pointer
  109. pwrite(fd, buf ?? UnsafeRawPointer($0), nbyte, offset)
  110. }
  111. #else
  112. return pwrite(fd, buf, nbyte, offset)
  113. #endif
  114. }
  115. #if !os(WASI)
  116. internal func system_dup(_ fd: Int32) -> Int32 {
  117. #if ENABLE_MOCKING
  118. if mockingEnabled { return _mock(fd) }
  119. #endif
  120. return dup(fd)
  121. }
  122. internal func system_dup2(_ fd: Int32, _ fd2: Int32) -> Int32 {
  123. #if ENABLE_MOCKING
  124. if mockingEnabled { return _mock(fd, fd2) }
  125. #endif
  126. return dup2(fd, fd2)
  127. }
  128. @available(macOS 27.0, iOS 27.0, watchOS 27.0, tvOS 27.0, visionOS 27.0, *)
  129. internal func system_dup3(_ fd: Int32, _ fd2: Int32, _ oflag: Int32) -> Int32 {
  130. #if ENABLE_MOCKING
  131. if mockingEnabled { return _mock(fd, fd2, oflag) }
  132. #endif
  133. return csystem_posix_dup3(fd, fd2, oflag)
  134. }
  135. #endif // !os(WASI)
  136. #if !os(WASI)
  137. internal func system_pipe(_ fds: UnsafeMutablePointer<Int32>) -> CInt {
  138. #if ENABLE_MOCKING
  139. if mockingEnabled { return _mock(fds) }
  140. #endif
  141. return pipe(fds)
  142. }
  143. @available(macOS 27.0, iOS 27.0, watchOS 27.0, tvOS 27.0, visionOS 27.0, *)
  144. internal func system_pipe2(_ fds: UnsafeMutablePointer<Int32>, _ oflag: Int32) -> CInt {
  145. #if ENABLE_MOCKING
  146. if mockingEnabled { return _mock(fds, oflag) }
  147. #endif
  148. return csystem_posix_pipe2(fds, oflag)
  149. }
  150. #endif // !os(WASI)
  151. internal func system_ftruncate(_ fd: Int32, _ length: off_t) -> Int32 {
  152. #if ENABLE_MOCKING
  153. if mockingEnabled { return _mock(fd, length) }
  154. #endif
  155. return ftruncate(fd, length)
  156. }
  157. internal func system_mkdir(
  158. _ path: UnsafePointer<CInterop.PlatformChar>,
  159. _ mode: CInterop.Mode
  160. ) -> CInt {
  161. #if ENABLE_MOCKING
  162. if mockingEnabled { return _mock(path: path, mode) }
  163. #endif
  164. return mkdir(path, mode)
  165. }
  166. internal func system_rmdir(
  167. _ path: UnsafePointer<CInterop.PlatformChar>
  168. ) -> CInt {
  169. #if ENABLE_MOCKING
  170. if mockingEnabled { return _mock(path: path) }
  171. #endif
  172. return rmdir(path)
  173. }
  174. #if SYSTEM_PACKAGE_DARWIN
  175. internal let SYSTEM_CS_DARWIN_USER_TEMP_DIR = _CS_DARWIN_USER_TEMP_DIR
  176. internal func system_confstr(
  177. _ name: CInt,
  178. _ buf: UnsafeMutablePointer<CInterop.PlatformChar>,
  179. _ len: Int
  180. ) -> Int {
  181. return confstr(name, buf, len)
  182. }
  183. #endif // SYSTEM_PACKAGE_DARWIN
  184. #if !os(Windows)
  185. internal let SYSTEM_AT_REMOVE_DIR = AT_REMOVEDIR
  186. #if os(WASI)
  187. internal let SYSTEM_DT_DIR = _getConst_DT_DIR()
  188. internal typealias system_dirent = _system_dirent
  189. #else
  190. internal let SYSTEM_DT_DIR = DT_DIR
  191. internal typealias system_dirent = dirent
  192. #endif
  193. #if os(Linux) || os(Android) || os(FreeBSD) || os(OpenBSD) || os(WASI)
  194. internal typealias system_DIRPtr = OpaquePointer
  195. #else
  196. internal typealias system_DIRPtr = UnsafeMutablePointer<DIR>
  197. #endif
  198. internal func system_unlinkat(
  199. _ fd: CInt,
  200. _ path: UnsafePointer<CInterop.PlatformChar>,
  201. _ flag: CInt
  202. ) -> CInt {
  203. #if ENABLE_MOCKING
  204. if mockingEnabled { return _mock(fd, path, flag) }
  205. #endif
  206. return unlinkat(fd, path, flag)
  207. }
  208. internal func system_fdopendir(
  209. _ fd: CInt
  210. ) -> system_DIRPtr? {
  211. return fdopendir(fd)
  212. }
  213. internal func system_readdir(
  214. _ dir: system_DIRPtr
  215. ) -> UnsafeMutablePointer<system_dirent>? {
  216. #if os(WASI)
  217. return _system_dirent_from_wasi_dirent(readdir(dir))
  218. #else
  219. return readdir(dir)
  220. #endif
  221. }
  222. internal func system_rewinddir(
  223. _ dir: system_DIRPtr
  224. ) {
  225. return rewinddir(dir)
  226. }
  227. internal func system_closedir(
  228. _ dir: system_DIRPtr
  229. ) -> CInt {
  230. return closedir(dir)
  231. }
  232. internal func system_openat(
  233. _ fd: CInt,
  234. _ path: UnsafePointer<CInterop.PlatformChar>,
  235. _ oflag: Int32
  236. ) -> CInt {
  237. #if ENABLE_MOCKING
  238. if mockingEnabled {
  239. return _mock(fd, path, oflag)
  240. }
  241. #endif
  242. return openat(fd, path, oflag)
  243. }
  244. #endif // !os(Windows)
  245. #if !os(WASI) // WASI has no umask
  246. internal func system_umask(
  247. _ mode: CInterop.Mode
  248. ) -> CInterop.Mode {
  249. return umask(mode)
  250. }
  251. #endif // !os(WASI)
  252. internal func system_getenv(
  253. _ name: UnsafePointer<CChar>
  254. ) -> UnsafeMutablePointer<CChar>? {
  255. return getenv(name)
  256. }