@@ -125,33 +125,6 @@ extension CocoaError {
125125#endif
126126}
127127
128- #if canImport(Darwin)
129- @_cdecl ( " _FileRemove_ConfirmCallback " )
130- internal func _FileRemove_ConfirmCallback( _ state: removefile_state_t , _ pathPtr: UnsafePointer < CChar > , _ contextPtr: UnsafeRawPointer ) -> Int {
131- let context = Unmanaged < _FileOperations . _FileRemoveContext > . fromOpaque ( contextPtr) . takeUnretainedValue ( )
132- let path = String ( cString: pathPtr)
133-
134- // Proceed unless the delegate says to skip
135- return ( context. manager? . _shouldRemoveItemAtPath ( path) ?? true ) ? REMOVEFILE_PROCEED : REMOVEFILE_SKIP
136- }
137-
138- @_cdecl ( " _FileRemove_ErrorCallback " )
139- internal func _FileRemove_ErrorCallback( _ state: removefile_state_t , _ pathPtr: UnsafePointer < CChar > , _ contextPtr: UnsafeRawPointer ) -> Int {
140- let context = Unmanaged < _FileOperations . _FileRemoveContext > . fromOpaque ( contextPtr) . takeUnretainedValue ( )
141- let path = String ( cString: pathPtr)
142-
143- let err = CocoaError . removeFileError ( Int32 ( _filemanagershims_removefile_state_get_errnum ( state) ) , path)
144-
145- // Proceed only if the delegate says so
146- if context. manager? . _shouldProceedAfter ( error: err, removingItemAtPath: path) ?? false {
147- return REMOVEFILE_PROCEED
148- } else {
149- context. error = err
150- return REMOVEFILE_STOP
151- }
152- }
153- #endif
154-
155128extension FileManager {
156129 fileprivate func _shouldProceedAfter( error: Error , removingItemAtPath path: String ) -> Bool {
157130 var delegateResponse : Bool ?
@@ -317,6 +290,25 @@ private extension LinkOrCopyDelegate {
317290 var extraCopyFileFlags : Int32 { 0 }
318291}
319292
293+ #if canImport(Darwin)
294+ private typealias RemoveFileCallback = @convention ( c) ( removefile_state_t , UnsafePointer < CChar > , UnsafeRawPointer ) -> Int
295+
296+ extension removefile_state_t {
297+ fileprivate var errnum : Int32 {
298+ var num : Int32 = 0
299+ removefile_state_get ( self , UInt32 ( REMOVEFILE_STATE_ERRNO) , & num)
300+ return num
301+ }
302+
303+ fileprivate func attachCallbacks( context: UnsafeRawPointer ? , confirm: RemoveFileCallback , error: RemoveFileCallback ) {
304+ removefile_state_set ( self , UInt32 ( REMOVEFILE_STATE_CONFIRM_CONTEXT) , context)
305+ removefile_state_set ( self , UInt32 ( REMOVEFILE_STATE_CONFIRM_CALLBACK) , unsafeBitCast ( confirm, to: UnsafeRawPointer . self) )
306+ removefile_state_set ( self , UInt32 ( REMOVEFILE_STATE_ERROR_CONTEXT) , context)
307+ removefile_state_set ( self , UInt32 ( REMOVEFILE_STATE_ERROR_CALLBACK) , unsafeBitCast ( error, to: UnsafeRawPointer . self) )
308+ }
309+ }
310+ #endif
311+
320312enum _FileOperations {
321313 // MARK: removefile
322314
@@ -421,20 +413,39 @@ enum _FileOperations {
421413 }
422414
423415 private static func _removeFile( _ pathPtr: UnsafePointer < CChar > , _ pathStr: String , with fileManager: FileManager ? ) throws {
424- let state = removefile_state_alloc ( )
416+ let state = removefile_state_alloc ( ) !
425417 defer { removefile_state_free ( state) }
426418
427419 let ctx = _FileRemoveContext ( fileManager)
428420 try withExtendedLifetime ( ctx) {
429421 let ctxPtr = Unmanaged . passUnretained ( ctx) . toOpaque ( )
430- _filemanagershims_removefile_attach_callbacks ( state, ctxPtr)
422+ state. attachCallbacks ( context: ctxPtr, confirm: { _, pathPtr, contextPtr in
423+ let context = Unmanaged < _FileOperations . _FileRemoveContext > . fromOpaque ( contextPtr) . takeUnretainedValue ( )
424+ let path = String ( cString: pathPtr)
425+
426+ // Proceed unless the delegate says to skip
427+ return ( context. manager? . _shouldRemoveItemAtPath ( path) ?? true ) ? REMOVEFILE_PROCEED : REMOVEFILE_SKIP
428+ } , error: { state, pathPtr, contextPtr in
429+ let context = Unmanaged < _FileOperations . _FileRemoveContext > . fromOpaque ( contextPtr) . takeUnretainedValue ( )
430+ let path = String ( cString: pathPtr)
431+
432+ let err = CocoaError . removeFileError ( state. errnum, path)
433+
434+ // Proceed only if the delegate says so
435+ if context. manager? . _shouldProceedAfter ( error: err, removingItemAtPath: path) ?? false {
436+ return REMOVEFILE_PROCEED
437+ } else {
438+ context. error = err
439+ return REMOVEFILE_STOP
440+ }
441+ } )
431442
432443 let err = removefile ( pathPtr, state, removefile_flags_t ( REMOVEFILE_RECURSIVE) )
433444 if err < 0 {
434445 if errno != 0 {
435446 throw CocoaError . removeFileError ( Int32 ( errno) , pathStr)
436447 }
437- throw CocoaError . removeFileError ( Int32 ( _filemanagershims_removefile_state_get_errnum ( state) ) , pathStr)
448+ throw CocoaError . removeFileError ( state. errnum , pathStr)
438449 }
439450
440451 if let error = ctx. error {
0 commit comments