@@ -15,22 +15,12 @@ actor TunnelHandle {
15
15
16
16
init ( dylibPath: URL ) throws ( TunnelHandleError) {
17
17
guard let dylibHandle = dlopen ( dylibPath. path, RTLD_NOW | RTLD_LOCAL) else {
18
- var errStr = " UNKNOWN "
19
- let e = dlerror ( )
20
- if e != nil {
21
- errStr = String ( cString: e!)
22
- }
23
- throw . dylib( errStr)
18
+ throw . dylib( dlerror ( ) . flatMap { String ( cString: $0) } ?? " UNKNOWN " )
24
19
}
25
20
self . dylibHandle = dylibHandle
26
21
27
22
guard let startSym = dlsym ( dylibHandle, startSymbol) else {
28
- var errStr = " UNKNOWN "
29
- let e = dlerror ( )
30
- if e != nil {
31
- errStr = String ( cString: e!)
32
- }
33
- throw . symbol( startSymbol, errStr)
23
+ throw . symbol( startSymbol, dlerror ( ) . flatMap { String ( cString: $0) } ?? " UNKNOWN " )
34
24
}
35
25
let openTunnelFn = unsafeBitCast ( startSym, to: OpenTunnel . self)
36
26
tunnelReadPipe = Pipe ( )
@@ -42,21 +32,42 @@ actor TunnelHandle {
42
32
}
43
33
}
44
34
45
- func close( ) throws {
46
- dlclose ( dylibHandle)
35
+ // This could be an isolated deinit in Swift 6.1
36
+ func close( ) throws ( TunnelHandleError) {
37
+ var errs : [ Error ] = [ ]
38
+ if dlclose ( dylibHandle) == 0 {
39
+ errs. append ( TunnelHandleError . dylib ( dlerror ( ) . flatMap { String ( cString: $0) } ?? " UNKNOWN " ) )
40
+ }
41
+ do {
42
+ try writeHandle. close ( )
43
+ } catch {
44
+ errs. append ( error)
45
+ }
46
+ do {
47
+ try readHandle. close ( )
48
+ } catch {
49
+ errs. append ( error)
50
+ }
51
+ if !errs. isEmpty {
52
+ throw . close( errs)
53
+ }
47
54
}
48
55
}
49
56
50
57
enum TunnelHandleError : Error {
51
58
case dylib( String )
52
59
case symbol( String , String )
53
60
case openTunnel( OpenTunnelError )
61
+ case pipe( any Error )
62
+ case close( [ any Error ] )
54
63
55
64
var description : String {
56
65
switch self {
66
+ case let . pipe( err) : return " pipe error: \( err) "
57
67
case let . dylib( d) : return d
58
68
case let . symbol( symbol, message) : return " \( symbol) : \( message) "
59
69
case let . openTunnel( error) : return " OpenTunnel: \( error. message) "
70
+ case let . close( errs) : return " close tunnel: \( errs. map ( \. localizedDescription) . joined ( separator: " , " ) ) "
60
71
}
61
72
}
62
73
}
0 commit comments