Skip to content

Commit 28916d2

Browse files
authored
Merge pull request #11 from milseman/aperture_adapters
Windows syscall adapters
2 parents 8f2622a + 1eeeaf7 commit 28916d2

File tree

3 files changed

+124
-6
lines changed

3 files changed

+124
-6
lines changed

Sources/SystemInternals/Mocking.swift

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,26 @@ import Glibc
9292
#endif
9393

9494
// TLS helper functions
95-
#if !os(Windows)
95+
#if os(Windows)
96+
internal typealias TLSKey = DWORD
97+
internal func makeTLSKey() -> TLSKey {
98+
var raw: DWORD = FlsAlloc(nil)
99+
if raw == FLS_OUT_OF_INDEXES {
100+
fatalError("Unable to create key")
101+
}
102+
return raw
103+
}
104+
internal func setTLS(_ key: TLSKey, _ p: UnsafeMutableRawPointer?) {
105+
guard 0 != FlsSetValue(key, p) else {
106+
fatalError("Unable to set TLS")
107+
}
108+
}
109+
internal func getTLS(_ key: TLSKey) -> UnsafeMutableRawPointer? {
110+
FlsGetValue(key)
111+
}
112+
113+
#else
114+
96115
internal typealias TLSKey = pthread_key_t
97116
internal func makeTLSKey() -> TLSKey {
98117
var raw = pthread_key_t()
@@ -109,9 +128,6 @@ internal func setTLS(_ key: TLSKey, _ p: UnsafeMutableRawPointer?) {
109128
internal func getTLS(_ key: TLSKey) -> UnsafeMutableRawPointer? {
110129
pthread_getspecific(key)
111130
}
112-
#else
113-
// TODO: Windows version...
114-
#error("Unsupported Platform")
115131
#endif
116132

117133
private let driverKey: TLSKey = { makeTLSKey() }()

Sources/SystemInternals/Syscalls.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ private func mockImpl(
3535
switch driver.forceErrno {
3636
case .none: break
3737
case .always(let e):
38-
errno = e
38+
system_errno = e
3939
return -1
4040
case .counted(let e, let count):
4141
assert(count >= 1)
42-
errno = e
42+
system_errno = e
4343
driver.forceErrno = count > 1 ? .counted(errno: e, count: count-1) : .none
4444
return -1
4545
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
This source file is part of the Swift System open source project
3+
4+
Copyright (c) 2020 Apple Inc. and the Swift System project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See https://swift.org/LICENSE.txt for license information
8+
*/
9+
10+
#if os(Windows)
11+
12+
@inline(__always)
13+
internal func open(_ path: UnsafePointer<CChar>, _ oflag: Int32) {
14+
var fh: CInt = -1
15+
_ = _sopen_s(&fh, path, oflag, _SH_DENYNO, _S_IREAD | _S_IWRITE)
16+
return fh
17+
}
18+
19+
@inline(__always)
20+
internal func open(
21+
_ path: UnsafePointer<CChar>, _ oflag: Int32, _ mode: mode_t
22+
) -> CInt {
23+
// TODO(compnerd): Apply read/write permissions
24+
var fh: CInt = -1
25+
_ = _sopen_s(&fh, path, oflag, _SH_DENYNO, _S_IREAD | _S_IWRITE)
26+
return fh
27+
}
28+
29+
@inline(__always)
30+
internal func close(_ fd: Int32) -> Int32 {
31+
_close(fd)
32+
}
33+
34+
@inline(__always)
35+
internal func lseek(
36+
_ fd: Int32, _ off: off_t, _ whence: Int32
37+
) -> off_t {
38+
_lseek(fd, off, whence)
39+
}
40+
41+
@inline(__always)
42+
internal func read(
43+
_ fd: Int32, _ buf: UnsafeMutableRawPointer!, _ nbyte: Int
44+
) -> Int {
45+
Int(_read(fd, buf, numericCast(nbyte)))
46+
}
47+
48+
@inline(__always)
49+
internal func write(
50+
_ fd: Int32, _ buf: UnsafeRawPointer!, _ nbyte: Int
51+
) -> Int {
52+
Int(_write(fd, buf, numericCast(nbyte)))
53+
}
54+
55+
@inline(__always)
56+
internal func pread(
57+
_ fd: Int32, _ buf: UnsafeMutableRawPointer!, _ nbyte: Int, _ offset: off_t
58+
) -> Int {
59+
let handle: intptr_t = _get_osfhandle(fd)
60+
if handle == /* INVALID_HANDLE_VALUE */ -1 { return Int(EBADF) }
61+
62+
// NOTE: this is a non-owning handle, do *not* call CloseHandle on it
63+
let hFile: HANDLE = HANDLE(bitPattern: handle)!
64+
65+
var ovlOverlapped: OVERLAPPED = OVERLAPPED()
66+
ovlOverlapped.OffsetHigh = DWORD(UInt32(offset >> 32) & 0xffffffff)
67+
ovlOverlapped.Offset = DWORD(UInt32(offset >> 0) & 0xffffffff)
68+
69+
var nNumberOfBytesRead: DWORD = 0
70+
if !ReadFile(hFile, buf, DWORD(nbyte), &nNumberOfBytesRead, &ovlOverlapped) {
71+
let _ = GetLastError()
72+
// TODO(compnerd) map windows error to errno
73+
return Int(-1)
74+
}
75+
return Int(nNumberOfBytesRead)
76+
}
77+
78+
@inline(__always)
79+
internal func pwrite(
80+
_ fd: Int32, _ buf: UnsafeRawPointer!, _ nbyte: Int, _ offset: off_t
81+
) -> Int {
82+
let handle: intptr_t = _get_osfhandle(fd)
83+
if handle == /* INVALID_HANDLE_VALUE */ -1 { return Int(EBADF) }
84+
85+
// NOTE: this is a non-owning handle, do *not* call CloseHandle on it
86+
let hFile: HANDLE = HANDLE(bitPattern: handle)!
87+
88+
var ovlOverlapped: OVERLAPPED = OVERLAPPED()
89+
ovlOverlapped.OffsetHigh = DWORD(UInt32(offset >> 32) & 0xffffffff)
90+
ovlOverlapped.Offset = DWORD(UInt32(offset >> 0) & 0xffffffff)
91+
92+
var nNumberOfBytesWritten: DWORD = 0
93+
if !WriteFile(hFile, buf, DWORD(nbyte), &nNumberOfBytesWritten,
94+
&ovlOverlapped) {
95+
let _ = GetLastError()
96+
// TODO(compnerd) map windows error to errno
97+
return Int(-1)
98+
}
99+
return Int(nNumberOfBytesWritten)
100+
}
101+
102+
#endif

0 commit comments

Comments
 (0)