Skip to content

Version 4.2.0

Latest

Choose a tag to compare

@RuiNelson RuiNelson released this 10 Oct 18:58

What's New

  • Cancellable blocking locks - You can now stop waiting for a blocking lock by cancelling the task that requested it. The server withdraws the request with an SMB2 CANCEL, so the lock is never granted later, and lock throws CancellationError. Disconnecting also withdraws a waiting lock, so disconnect() no longer waits behind it.
let lockTask = Task {
    try await file.lock(.exclusive, nonBlocking: false)
}
// ...
lockTask.cancel()
  • Full share details - SMB.listShares(..., detail: .full) now reports each share's local path on the server, its permissions, maximumUsers (nil when unlimited), and currentUsers. Windows servers only return these details to administrators and operators, and answer other users with accessDenied.
let shares = try await SMB.listShares(server: server, credentials: credentials, detail: .full)
for share in shares {
    print(share.name, share.path ?? "-", share.currentUsers ?? 0)
}
  • Typed symbolic links - makeLink(at:pointingTo:isDirectory:isAbsolute:) now looks up the target by default and creates a directory link when the target is a directory. Pass isDirectory to skip the lookup, and isAbsolute: true to force an absolute target. Servers that cannot store directory links, such as Samba, get a file link instead.
  • Node attributes and special files - SMB.Stat now exposes the raw Windows attributes and the reparseTag of reparse points. SMB.NodeType now reports the FIFOs, character and block devices, and sockets that WSL stores on Windows filesystems, which were previously reported as .unknown.
  • More SMB statuses - SMB.SMBStatus now includes the reparse-point statuses ioReparseTagInvalid, ioReparseTagMismatch, ioReparseDataInvalid, ioReparseTagNotHandled, reparsePointNotResolved, and directoryIsAReparsePoint.
  • Upstream libsmb2 - SwiftSMB now builds the official sahlberg/libsmb2 sources directly, updated to fc710a3, instead of a fork.

Bug Fixes

  • Fixed the command timeout leaving a blocking lock pending on the server. The lock could still be granted after lock had thrown ioTimeout; the request is now withdrawn, and the error is unchanged.
  • Fixed a cancelled directory watcher staying registered on the server until its directory handle closed.

Migration Guide

SMB.NodeType has four new cases. An exhaustive switch over it must handle them, or use a default clause.

Before:

switch info.type {
case .file, .directory, .link: handle(info)
case .unknown: skip(info)
}

After:

switch info.type {
case .file, .directory, .link: handle(info)
case .fifo, .characterDevice, .blockDevice, .socket, .unknown: skip(info)
}