Skip to content

Commit f311ec7

Browse files
rauhulrauhul-varma
authored andcommitted
initial implementation
1 parent e65848b commit f311ec7

File tree

2 files changed

+94
-2
lines changed

2 files changed

+94
-2
lines changed

Foundation/FileManager.swift

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -744,9 +744,41 @@ open class FileManager : NSObject {
744744
access($0, X_OK) == 0
745745
})
746746
}
747-
747+
748+
/**
749+
- parameters:
750+
- path: The path to the file we are trying to determine is deletable.
751+
752+
- returns: `true` if the file is deletable, `false` otherwise.
753+
*/
748754
open func isDeletableFile(atPath path: String) -> Bool {
749-
NSUnimplemented()
755+
// Get the parent directory of supplied path
756+
let parent = path._nsObject.deletingLastPathComponent
757+
758+
return _fileSystemRepresentation(withPath: parent, andPath: path, { parentFsRep, fsRep in
759+
// Check the parent directory is writeable, else return false.
760+
guard access(parentFsRep, W_OK) == 0 else {
761+
return false
762+
}
763+
764+
// Stat the parent directory, if that fails, return false.
765+
guard let parentS = try? _lstatFile(atPath: path, withFileSystemRepresentation: parentFsRep) else {
766+
return false
767+
}
768+
769+
// Check if the parent is 'sticky' if it exists.
770+
if (parentS.st_mode & S_ISVTX) == S_ISVTX {
771+
guard let s = try? _lstatFile(atPath: path, withFileSystemRepresentation: fsRep) else {
772+
return false
773+
}
774+
775+
// If the current user owns the file, return true.
776+
return s.st_uid == getuid()
777+
}
778+
779+
// Return true as the best guess.
780+
return true
781+
})
750782
}
751783

752784
private func _compareFiles(withFileSystemRepresentation file1Rep: UnsafePointer<Int8>, andFileSystemRepresentation file2Rep: UnsafePointer<Int8>, size: Int64, bufSize: Int) -> Bool {

TestFoundation/TestFileManager.swift

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ class TestFileManager : XCTestCase {
1616
("test_moveFile", test_moveFile),
1717
("test_fileSystemRepresentation", test_fileSystemRepresentation),
1818
("test_fileExists", test_fileExists),
19+
("test_isReadableFile", test_isReadableFile),
20+
("test_isWritableFile", test_isWritableFile),
21+
("test_isExecutableFile", test_isExecutableFile),
22+
("test_isDeletableFile", test_isDeletableFile),
1923
("test_fileAttributes", test_fileAttributes),
2024
("test_fileSystemAttributes", test_fileSystemAttributes),
2125
("test_setFileAttributes", test_setFileAttributes),
@@ -202,6 +206,62 @@ class TestFileManager : XCTestCase {
202206
ignoreError { try fm.removeItem(atPath: tmpDir.path) }
203207
}
204208

209+
func test_isReadableFile() {
210+
let fm = FileManager.default
211+
let path = NSTemporaryDirectory() + "test_fileAttributes\(NSUUID().uuidString)"
212+
213+
XCTAssertTrue(fm.createFile(atPath: path, contents: Data(), attributes: nil))
214+
215+
do {
216+
let attrs = try fm.attributesOfItem(atPath: path)
217+
let permissions = attrs[FileAttributeKey.posixPermissions] as! UInt16
218+
let fileIsReadableFile = (permissions & S_IRUSR == S_IRUSR)
219+
let fmIsReadableFile = fm.isReadableFile(atPath: path)
220+
XCTAssertTrue(fileIsReadableFile == fmIsReadableFile)
221+
} catch let e {
222+
XCTFail("\(e)")
223+
}
224+
}
225+
226+
func test_isWritableFile() {
227+
let fm = FileManager.default
228+
let path = NSTemporaryDirectory() + "test_fileAttributes\(NSUUID().uuidString)"
229+
230+
XCTAssertTrue(fm.createFile(atPath: path, contents: Data(), attributes: nil))
231+
232+
do {
233+
let attrs = try fm.attributesOfItem(atPath: path)
234+
let permissions = attrs[FileAttributeKey.posixPermissions] as! UInt16
235+
let fileIsReadableFile = (permissions & S_IWUSR == S_IWUSR)
236+
let fmIsReadableFile = fm.isReadableFile(atPath: path)
237+
XCTAssertTrue(fileIsReadableFile == fmIsReadableFile)
238+
} catch let e {
239+
XCTFail("\(e)")
240+
}
241+
}
242+
243+
func test_isExecutableFile() {
244+
let fm = FileManager.default
245+
let path = NSTemporaryDirectory() + "test_fileAttributes\(NSUUID().uuidString)"
246+
247+
XCTAssertTrue(fm.createFile(atPath: path, contents: Data(), attributes: nil))
248+
249+
do {
250+
let attrs = try fm.attributesOfItem(atPath: path)
251+
let permissions = attrs[FileAttributeKey.posixPermissions] as! UInt16
252+
let fileIsReadableFile = (permissions & S_IXUSR == S_IXUSR)
253+
let fmIsReadableFile = fm.isReadableFile(atPath: path)
254+
XCTAssertTrue(fileIsReadableFile == fmIsReadableFile)
255+
} catch let e {
256+
XCTFail("\(e)")
257+
}
258+
}
259+
260+
func test_isDeletableFile() {
261+
// TODO: Implement test
262+
// how to test?
263+
}
264+
205265
func test_fileAttributes() {
206266
let fm = FileManager.default
207267
let path = NSTemporaryDirectory() + "test_fileAttributes\(NSUUID().uuidString)"

0 commit comments

Comments
 (0)