From 8ee3118876514d92d23e961e34ed7464d734856f Mon Sep 17 00:00:00 2001 From: Amir Abbas Date: Sun, 15 Jul 2018 03:07:00 +0430 Subject: [PATCH] Implementing Timeout --- AMSMB2/AMSMB2.swift | 95 ++++++++++++++++++++++++----------------- AMSMB2/Context.swift | 59 +++++++++++++------------ AMSMB2/Directory.swift | 2 +- AMSMB2/Extensions.swift | 4 +- AMSMB2/FileHandle.swift | 18 ++++---- 5 files changed, 97 insertions(+), 81 deletions(-) diff --git a/AMSMB2/AMSMB2.swift b/AMSMB2/AMSMB2.swift index 0abfca4..c9c6175 100644 --- a/AMSMB2/AMSMB2.swift +++ b/AMSMB2/AMSMB2.swift @@ -10,6 +10,9 @@ import Foundation import SMB2 public typealias SimpleCompletionHandler = ((_ error: Error?) -> Void)? +public typealias SMB2ReadProgressHandler = ((_ bytes: Int64, _ total: Int64) -> Bool)? +public typealias SMB2WriteProgressHandler = ((_ bytes: Int64) -> Bool)? +private typealias CopyProgressHandler = ((_ bytes: Int64, _ soFar: Int64, _ total: Int64) -> Bool)? /// Implements SMB2 File operations. @objc @objcMembers @@ -24,6 +27,22 @@ public class AMSMB2: NSObject, NSSecureCoding { private let _server: String private let _password: String private let q: DispatchQueue + private var _timeout: TimeInterval + + /** + The timeout interval to use when doing an operation until getting response. Default value is 60 seconds. + Set this to 0 or negative value in order to disable it. + */ + @objc + public var timeout: TimeInterval { + get { + return context?.timeout ?? _timeout + } + set { + _timeout = newValue + context?.timeout = newValue + } + } /** Initializes a SMB2 class with given url and credential. @@ -60,24 +79,25 @@ public class AMSMB2: NSObject, NSSecureCoding { _workstation = workstation _user = user _password = credential?.password ?? "" + _timeout = 60.0 super.init() } public required init?(coder aDecoder: NSCoder) { guard let url = aDecoder.decodeObject(of: NSURL.self, forKey: "url") as URL? else { - aDecoder.failWithError(CocoaError.error(.coderValueNotFound, - userInfo: [NSLocalizedDescriptionKey: "URL is not set."])) + aDecoder.failWithError(CocoaError(.coderValueNotFound, + userInfo: [NSLocalizedDescriptionKey: "URL is not set."])) return nil } guard url.scheme?.lowercased() == "smb" else { - aDecoder.failWithError(CocoaError.error(.coderReadCorrupt, - userInfo: [NSLocalizedDescriptionKey: "URL is not smb."])) + aDecoder.failWithError(CocoaError(.coderReadCorrupt, + userInfo: [NSLocalizedDescriptionKey: "URL is not smb."])) return nil } guard let server = aDecoder.decodeObject(of: NSString.self, forKey: "server") as String? else { - aDecoder.failWithError(CocoaError.error(.coderValueNotFound, - userInfo: [NSLocalizedDescriptionKey: "server is not set."])) + aDecoder.failWithError(CocoaError(.coderValueNotFound, + userInfo: [NSLocalizedDescriptionKey: "server is not set."])) return nil } @@ -89,6 +109,7 @@ public class AMSMB2: NSObject, NSSecureCoding { self._workstation = aDecoder.decodeObject(of: NSString.self, forKey: "workstation") as String? ?? "" self._user = aDecoder.decodeObject(of: NSString.self, forKey: "user") as String? ?? "guest" self._password = aDecoder.decodeObject(of: NSString.self, forKey: "password") as String? ?? "" + self._timeout = aDecoder.decodeDouble(forKey: "timeout") super.init() } @@ -99,6 +120,7 @@ public class AMSMB2: NSObject, NSSecureCoding { aCoder.encode(_workstation, forKey: "workstation") aCoder.encode(_user, forKey: "user") aCoder.encode(_password, forKey: "password") + aCoder.encode(timeout, forKey: "timeout") } public static var supportsSecureCoding: Bool { @@ -113,7 +135,7 @@ public class AMSMB2: NSObject, NSSecureCoding { q.async { do { if self.context == nil { - let context = try SMB2Context() + let context = try SMB2Context(timeout: self._timeout) let url = try SMB2URL(self.url.absoluteString, on: context) self.context = context self.smburl = url @@ -177,7 +199,7 @@ public class AMSMB2: NSObject, NSSecureCoding { do { // We use separate context because when a context connects to a tree, it won't connect to another tree. let server = self.smburl?.server ?? self._server - let context = try SMB2Context() + let context = try SMB2Context(timeout: self.timeout) self.initContext(context) // Connecting to Interprocess Communication share @@ -418,7 +440,7 @@ public class AMSMB2: NSObject, NSSecureCoding { /** Fetches data contents of a file from an offset with specified length. With reporting progress - on about every 64KB. + on about every 1MiB. - Note: If offset is bigger than file's size, an empty `Data will be returned. If length exceeds file, returned data will be truncated to entire file content from given offset. @@ -436,8 +458,7 @@ public class AMSMB2: NSObject, NSSecureCoding { - error: `Error` if any occured during reading. */ @objc - public func contents(atPath path: String, offset: Int64 = 0, length: Int = -2, - progress: ((_ bytes: Int64, _ total: Int64) -> Bool)?, + public func contents(atPath path: String, offset: Int64 = 0, length: Int = -2, progress: SMB2ReadProgressHandler, completionHandler: @escaping (_ contents: Data?, _ error: Error?) -> Void) { q.async { do { @@ -447,15 +468,15 @@ public class AMSMB2: NSObject, NSSecureCoding { let stream = OutputStream.toMemory() if length > 0 { - try self.read(atPath: path, range: offset..<(offset + Int64(length)), to: stream, progress: progress) + try self.read(path: path, range: offset..<(offset + Int64(length)), to: stream, progress: progress) } else if length < 0 { - try self.read(atPath: path, range: offset.. Bool)?, + public func write(data: Data, toPath path: String, progress: SMB2WriteProgressHandler, completionHandler: SimpleCompletionHandler) { q.async { do { @@ -537,7 +558,7 @@ public class AMSMB2: NSObject, NSSecureCoding { } /** - Copy file contents to a new location. With reporting progress on about every 64KB. + Copy file contents to a new location. With reporting progress on about every 1MiB. - Note: This operation consists downloading and uploading file, which may take bandwidth. Unfortunately there is not a way to copy file remotely right now. @@ -554,8 +575,7 @@ public class AMSMB2: NSObject, NSSecureCoding { @available(*, deprecated, message: "New method does server-side copy and is much faster.", renamed: "copyItem(atPath:toPath:recursive:progress:completionHandler:)") @objc public func copyContentsOfItem(atPath path: String, toPath: String, recursive: Bool, - progress: ((_ bytes: Int64, _ total: Int64) -> Bool)?, - completionHandler: SimpleCompletionHandler) { + progress: SMB2ReadProgressHandler, completionHandler: SimpleCompletionHandler) { q.async { do { let context = try self.tryContext() @@ -610,7 +630,7 @@ public class AMSMB2: NSObject, NSSecureCoding { } /** - Copy files to a new location. With reporting progress on about every 64KB. + Copy files to a new location. With reporting progress on about every 1MiB. - Note: This operation consists downloading and uploading file, which may take bandwidth. Unfortunately there is not a way to copy file remotely right now. @@ -625,8 +645,7 @@ public class AMSMB2: NSObject, NSSecureCoding { - completionHandler: closure will be run after copying is completed. */ @objc - public func copyItem(atPath path: String, toPath: String, recursive: Bool, - progress: ((_ bytes: Int64, _ total: Int64) -> Bool)?, + public func copyItem(atPath path: String, toPath: String, recursive: Bool, progress: SMB2ReadProgressHandler, completionHandler: SimpleCompletionHandler) { q.async { do { @@ -682,7 +701,7 @@ public class AMSMB2: NSObject, NSSecureCoding { } /** - Uploads local file contents to a new location. With reporting progress on about every 64KB. + Uploads local file contents to a new location. With reporting progress on about every 1MiB. - Note: given url must be local file url otherwise process will crash. @@ -694,12 +713,12 @@ public class AMSMB2: NSObject, NSSecureCoding { - completionHandler: closure will be run after uploading is completed. */ @objc - public func uploadItem(at url: URL, toPath: String, progress: ((_ bytes: Int64) -> Bool)?, + public func uploadItem(at url: URL, toPath: String, progress: SMB2WriteProgressHandler, completionHandler: SimpleCompletionHandler) { q.async { do { guard url.isFileURL, let stream = InputStream(url: url) else { - throw POSIXError(.EIO, description: "Could not create NSStream from file URL.") + throw POSIXError(.EIO, description: "Could not create NSStream from given URL.") } guard let size = (try url.resourceValues(forKeys: [.fileSizeKey]).allValues[.fileSizeKey] as? NSNumber)?.uint64Value else { throw POSIXError(POSIXError.EFTYPE, description: "Could not retrieve file size from URL.") @@ -717,7 +736,7 @@ public class AMSMB2: NSObject, NSSecureCoding { } /** - Downloads file contents to a local url. With reporting progress on about every 64KB. + Downloads file contents to a local url. With reporting progress on about every 1MiB. - Note: if a file already exists on given url, This function will overwrite to that url. @@ -731,8 +750,7 @@ public class AMSMB2: NSObject, NSSecureCoding { - completionHandler: closure will be run after uploading is completed. */ @objc - public func downloadItem(atPath path: String, to url: URL, - progress: ((_ bytes: Int64, _ total: Int64) -> Bool)?, + public func downloadItem(atPath path: String, to url: URL, progress: SMB2ReadProgressHandler, completionHandler: SimpleCompletionHandler) { guard url.isFileURL else { fatalError("Downloading to remote url is not supported.") @@ -741,9 +759,9 @@ public class AMSMB2: NSObject, NSSecureCoding { q.async { do { guard url.isFileURL, let stream = OutputStream(url: url, append: false) else { - throw POSIXError(.EIO, description: "Could not create NSStream from file URL.") + throw POSIXError(.EIO, description: "Could not create NSStream from given URL.") } - try self.read(atPath: path, to: stream, progress: progress) + try self.read(path: path, to: stream, progress: progress) completionHandler?(nil) } catch { try? FileManager.default.removeItem(at: url) @@ -760,6 +778,7 @@ extension AMSMB2 { context.set(workstation: _workstation) context.set(user: _user) context.set(password: _password) + context.timeout = _timeout } fileprivate func tryContext() throws -> SMB2Context { @@ -825,14 +844,13 @@ extension AMSMB2 { return contents } - private func copyFile(atPath path: String, toPath: String, - progress: ((_ bytes: Int64, _ soFar: Int64, _ total: Int64) -> Bool)?) throws -> Bool { + private func copyFile(atPath path: String, toPath: String, progress: CopyProgressHandler) throws -> Bool { let context = try tryContext() let fileSource = try SMB2FileHandle(forReadingAtPath: path, on: context) let size = try Int64(fileSource.fstat().smb2_size) let sourceKey: IOCtl.RequestResumeKey = try fileSource.fcntl(command: .srvRequestResumeKey) // TODO: Get chunk size from server - let chunkSize = 1048576 + let chunkSize = fileSource.optimizedWriteSize let chunkArray = stride(from: 0, to: UInt64(size), by: chunkSize).map { IOCtl.SrvCopyChunk(sourceOffset: $0, targetOffset: $0, length: min(UInt32(UInt64(size) - $0), UInt32(chunkSize))) } @@ -851,8 +869,7 @@ extension AMSMB2 { return shouldContinue } - private func copyContentsOfFile(atPath path: String, toPath: String, - progress: ((_ bytes: Int64, _ soFar: Int64, _ total: Int64) -> Bool)?) throws -> Bool { + private func copyContentsOfFile(atPath path: String, toPath: String, progress: CopyProgressHandler) throws -> Bool { let context = try self.tryContext() let fileRead = try SMB2FileHandle(forReadingAtPath: path, on: context) let size = try Int64(fileRead.fstat().smb2_size) @@ -872,8 +889,8 @@ extension AMSMB2 { return shouldContinue } - private func read(atPath path: String, range: Range = 0.. Bool)?) throws { + private func read(path: String, range: Range = 0.. Bool)?) throws { + private func write(from stream: InputStream, size: UInt64, toPath: String, progress: SMB2WriteProgressHandler) throws { let context = try self.tryContext() let file = try SMB2FileHandle(forCreatingIfNotExistsAtPath: toPath, on: context) diff --git a/AMSMB2/Context.swift b/AMSMB2/Context.swift index 2fd5829..07dcf60 100644 --- a/AMSMB2/Context.swift +++ b/AMSMB2/Context.swift @@ -21,12 +21,14 @@ final class SMB2Context { internal var context: UnsafeMutablePointer private var _context_lock = NSLock() var isConnected = false + var timeout: TimeInterval - init() throws { + init(timeout: TimeInterval) throws { guard let _context = smb2_init_context() else { throw POSIXError(.ENOMEM) } self.context = _context + self.timeout = timeout } deinit { @@ -135,14 +137,14 @@ extension SMB2Context { // MARK: Connectivity extension SMB2Context { func connect(server: String, share: String, user: String) throws { - try async_wait(defaultError: .ECONNREFUSED) { (context, cbPtr) -> Int32 in + try async_await(defaultError: .ECONNREFUSED) { (context, cbPtr) -> Int32 in smb2_connect_share_async(context, server, share, user, SMB2Context.async_handler, cbPtr) } self.isConnected = true } func disconnect() throws { - try async_wait(defaultError: .ECONNREFUSED) { (context, cbPtr) -> Int32 in + try async_await(defaultError: .ECONNREFUSED) { (context, cbPtr) -> Int32 in smb2_disconnect_share_async(context, SMB2Context.async_handler, cbPtr) } self.isConnected = false @@ -150,7 +152,7 @@ extension SMB2Context { @discardableResult func echo() throws -> Bool { - try async_wait(defaultError: .ECONNREFUSED) { (context, cbPtr) -> Int32 in + try async_await(defaultError: .ECONNREFUSED) { (context, cbPtr) -> Int32 in smb2_echo_async(context, SMB2Context.async_handler, cbPtr) } return true @@ -160,7 +162,7 @@ extension SMB2Context { // MARK: DCE-RPC extension SMB2Context { func shareEnum() throws -> [(name: String, type: UInt32, comment: String)] { - let (_, cmddata) = try async_wait(defaultError: .ENOLINK) { (context, cbPtr) -> Int32 in + let (_, cmddata) = try async_await(defaultError: .ENOLINK) { (context, cbPtr) -> Int32 in smb2_share_enum_async(context, SMB2Context.async_handler, cbPtr) } @@ -189,27 +191,24 @@ extension SMB2Context { // MARK: File manipulation extension SMB2Context { func stat(_ path: String) throws -> smb2_stat_64 { - let cannonicalPath = path.replacingOccurrences(of: "/", with: "\\") var st = smb2_stat_64() - try async_wait(defaultError: .ENOLINK) { (context, cbPtr) -> Int32 in - smb2_stat_async(context, cannonicalPath, &st, SMB2Context.async_handler, cbPtr) + try async_await(defaultError: .ENOLINK) { (context, cbPtr) -> Int32 in + smb2_stat_async(context, path, &st, SMB2Context.async_handler, cbPtr) } return st } func statvfs(_ path: String) throws -> smb2_statvfs { - let cannonicalPath = path.replacingOccurrences(of: "/", with: "\\") var st = smb2_statvfs() - try async_wait(defaultError: .ENOLINK) { (context, cbPtr) -> Int32 in - smb2_statvfs_async(context, cannonicalPath, &st, SMB2Context.async_handler, cbPtr) + try async_await(defaultError: .ENOLINK) { (context, cbPtr) -> Int32 in + smb2_statvfs_async(context, path, &st, SMB2Context.async_handler, cbPtr) } return st } func truncate(_ path: String, toLength: UInt64) throws { - let cannonicalPath = path.replacingOccurrences(of: "/", with: "\\") - try async_wait(defaultError: .ENOLINK) { (context, cbPtr) -> Int32 in - smb2_truncate_async(context, cannonicalPath, toLength, SMB2Context.async_handler, cbPtr) + try async_await(defaultError: .ENOLINK) { (context, cbPtr) -> Int32 in + smb2_truncate_async(context, path, toLength, SMB2Context.async_handler, cbPtr) } } } @@ -217,31 +216,26 @@ extension SMB2Context { // MARK: File operation extension SMB2Context { func mkdir(_ path: String) throws { - let cannonicalPath = path.replacingOccurrences(of: "/", with: "\\") - try async_wait(defaultError: .EEXIST) { (context, cbPtr) -> Int32 in - smb2_mkdir_async(context, cannonicalPath, SMB2Context.async_handler, cbPtr) + try async_await(defaultError: .EEXIST) { (context, cbPtr) -> Int32 in + smb2_mkdir_async(context, path, SMB2Context.async_handler, cbPtr) } } func rmdir(_ path: String) throws { - let cannonicalPath = path.replacingOccurrences(of: "/", with: "\\") - try async_wait(defaultError: .ENOLINK) { (context, cbPtr) -> Int32 in - smb2_rmdir_async(context, cannonicalPath, SMB2Context.async_handler, cbPtr) + try async_await(defaultError: .ENOLINK) { (context, cbPtr) -> Int32 in + smb2_rmdir_async(context, path, SMB2Context.async_handler, cbPtr) } } func unlink(_ path: String) throws { - let cannonicalPath = path.replacingOccurrences(of: "/", with: "\\") - try async_wait(defaultError: .ENOLINK) { (context, cbPtr) -> Int32 in - smb2_unlink_async(context, cannonicalPath, SMB2Context.async_handler, cbPtr) + try async_await(defaultError: .ENOLINK) { (context, cbPtr) -> Int32 in + smb2_unlink_async(context, path, SMB2Context.async_handler, cbPtr) } } func rename(_ path: String, to newPath: String) throws { - let cannonicalPath = path.replacingOccurrences(of: "/", with: "\\") - let cannonicalNewPath = path.replacingOccurrences(of: "/", with: "\\") - try async_wait(defaultError: .ENOENT) { (context, cbPtr) -> Int32 in - smb2_rename_async(context, cannonicalPath, cannonicalNewPath, SMB2Context.async_handler, cbPtr) + try async_await(defaultError: .ENOENT) { (context, cbPtr) -> Int32 in + smb2_rename_async(context, path, newPath, SMB2Context.async_handler, cbPtr) } } } @@ -269,12 +263,13 @@ extension SMB2Context { } private func wait_for_reply(_ cbPtr: UnsafeMutableRawPointer) throws { + let startDate = Date() while !cbPtr.bindMemory(to: CBData.self, capacity: 1).pointee.isFinished { var pfd = pollfd() pfd.fd = fileDescriptor pfd.events = Int16(whichEvents()) - if poll(&pfd, 1, 1000) < 0 { + if poll(&pfd, 1, 1000) < 0, errno != EAGAIN { try POSIXError.throwIfError(errno, description: error, default: .EINVAL) } @@ -283,6 +278,10 @@ extension SMB2Context { } try service(revents: Int32(pfd.revents)) + + if timeout > 0, Date().timeIntervalSince(startDate) > timeout { + throw POSIXError(.ETIMEDOUT) + } } } @@ -293,7 +292,7 @@ extension SMB2Context { } @discardableResult - func async_wait(defaultError: POSIXError.Code, execute handler: (_ context: UnsafeMutablePointer, _ cbPtr: UnsafeMutableRawPointer) -> Int32) throws -> (result: Int32, data: UnsafeMutableRawPointer?) { + func async_await(defaultError: POSIXError.Code, execute handler: (_ context: UnsafeMutablePointer, _ cbPtr: UnsafeMutableRawPointer) -> Int32) throws -> (result: Int32, data: UnsafeMutableRawPointer?) { let cbPtr = CBData.initPointer() defer { cbPtr.deallocate() @@ -310,7 +309,7 @@ extension SMB2Context { return (cbresult, data) } - func async_wait_pdu(defaultError: POSIXError.Code, execute handler: (_ context: UnsafeMutablePointer, _ cbPtr: UnsafeMutableRawPointer) -> UnsafeMutablePointer?) throws -> (result: Int32, data: UnsafeMutableRawPointer?) { + func async_await_pdu(defaultError: POSIXError.Code, execute handler: (_ context: UnsafeMutablePointer, _ cbPtr: UnsafeMutableRawPointer) -> UnsafeMutablePointer?) throws -> (result: Int32, data: UnsafeMutableRawPointer?) { let cbPtr = CBData.initPointer() defer { cbPtr.deallocate() diff --git a/AMSMB2/Directory.swift b/AMSMB2/Directory.swift index 231234c..c41e0d9 100644 --- a/AMSMB2/Directory.swift +++ b/AMSMB2/Directory.swift @@ -20,7 +20,7 @@ final class SMB2Directory: Collection { private var handle: smb2dir init(_ path: String, on context: SMB2Context) throws { - let (_, cmddata) = try context.async_wait(defaultError: .ENOENT) { (context, cbPtr) -> Int32 in + let (_, cmddata) = try context.async_await(defaultError: .ENOENT) { (context, cbPtr) -> Int32 in smb2_opendir_async(context, path, SMB2Context.async_handler, cbPtr) } diff --git a/AMSMB2/Extensions.swift b/AMSMB2/Extensions.swift index 87fd724..67f9920 100644 --- a/AMSMB2/Extensions.swift +++ b/AMSMB2/Extensions.swift @@ -82,7 +82,7 @@ extension InputStream { self.read(p, maxLength: length) } if result < 0 { - throw self.streamError ?? POSIXError.init(.EIO, description: "Unknown stream error.") + throw self.streamError ?? POSIXError(.EIO, description: "Unknown stream error.") } else { data.count = result return data @@ -97,7 +97,7 @@ extension OutputStream { self.write(p, maxLength: count) } if result < 0 { - throw self.streamError ?? POSIXError.init(.EIO, description: "Unknown stream error.") + throw self.streamError ?? POSIXError(.EIO, description: "Unknown stream error.") } else { return result } diff --git a/AMSMB2/FileHandle.swift b/AMSMB2/FileHandle.swift index 9392391..b9d3d05 100644 --- a/AMSMB2/FileHandle.swift +++ b/AMSMB2/FileHandle.swift @@ -46,7 +46,7 @@ final class SMB2FileHandle { } private init(_ path: String, flags: Int32, on context: SMB2Context) throws { - let (_, cmddata) = try context.async_wait(defaultError: .ENOENT) { (context, cbPtr) -> Int32 in + let (_, cmddata) = try context.async_await(defaultError: .ENOENT) { (context, cbPtr) -> Int32 in smb2_open_async(context, path, flags, SMB2Context.async_handler, cbPtr) } @@ -79,14 +79,14 @@ final class SMB2FileHandle { func fstat() throws -> smb2_stat_64 { var st = smb2_stat_64() - try context.async_wait(defaultError: .EBADF) { (context, cbPtr) -> Int32 in + try context.async_await(defaultError: .EBADF) { (context, cbPtr) -> Int32 in smb2_fstat_async(context, handle, &st, SMB2Context.async_handler, cbPtr) } return st } func ftruncate(toLength: UInt64) throws { - try context.async_wait(defaultError: .EIO) { (context, cbPtr) -> Int32 in + try context.async_await(defaultError: .EIO) { (context, cbPtr) -> Int32 in smb2_ftruncate_async(context, handle, toLength, SMB2Context.async_handler, cbPtr) } } @@ -118,7 +118,7 @@ final class SMB2FileHandle { buffer.deallocate() } - let (result, _) = try context.async_wait(defaultError: .EIO) { (context, cbPtr) -> Int32 in + let (result, _) = try context.async_await(defaultError: .EIO) { (context, cbPtr) -> Int32 in smb2_read_async(context, handle, buffer, UInt32(bufSize), SMB2Context.async_handler, cbPtr) } return Data(bytes: buffer, count: Int(result)) @@ -135,7 +135,7 @@ final class SMB2FileHandle { buffer.deallocate() } - let (result, _) = try context.async_wait(defaultError: .EIO) { (context, cbPtr) -> Int32 in + let (result, _) = try context.async_await(defaultError: .EIO) { (context, cbPtr) -> Int32 in smb2_pread_async(context, handle, buffer, UInt32(bufSize), offset, SMB2Context.async_handler, cbPtr) } return Data(bytes: buffer, count: Int(result)) @@ -155,7 +155,7 @@ final class SMB2FileHandle { var data = data let count = data.count let (result, _) = try data.withUnsafeMutableBytes { (p) -> (result: Int32, data: UnsafeMutableRawPointer?) in - try context.async_wait(defaultError: .EBUSY) { (context, cbPtr) -> Int32 in + try context.async_await(defaultError: .EBUSY) { (context, cbPtr) -> Int32 in smb2_write_async(context, handle, p, UInt32(count), SMB2Context.async_handler, cbPtr) } @@ -191,7 +191,7 @@ final class SMB2FileHandle { var data = data let count = data.count let (result, _) = try data.withUnsafeMutableBytes { (p) -> (result: Int32, data: UnsafeMutableRawPointer?) in - try context.async_wait(defaultError: .EBUSY) { (context, cbPtr) -> Int32 in + try context.async_await(defaultError: .EBUSY) { (context, cbPtr) -> Int32 in smb2_pwrite_async(context, handle, p, UInt32(count), offset, SMB2Context.async_handler, cbPtr) } @@ -201,7 +201,7 @@ final class SMB2FileHandle { } func fsync() throws { - try context.async_wait(defaultError: .EIO) { (context, cbPtr) -> Int32 in + try context.async_await(defaultError: .EIO) { (context, cbPtr) -> Int32 in smb2_fsync_async(context, handle, SMB2Context.async_handler, cbPtr) } } @@ -218,7 +218,7 @@ final class SMB2FileHandle { req = smb2_ioctl_request(ctl_code: command.rawValue, file_id: fileId, input_count: 0, input: nil, flags: UInt32(SMB2_0_IOCTL_IS_FSCTL)) } - let (_, response) = try context.async_wait_pdu(defaultError: .EBADRPC) { (context, cbdata) -> UnsafeMutablePointer? in + let (_, response) = try context.async_await_pdu(defaultError: .EBADRPC) { (context, cbdata) -> UnsafeMutablePointer? in smb2_cmd_ioctl_async(context, &req, SMB2Context.async_handler, cbdata) }