commit caea53ad329a79fce2ac2b3eadf7c8ba92b903fa Author: Gwen Mittertreiner Date: Sun Apr 7 13:23:17 2019 -0700 Remove use of fts Replace the use of fts with Foundation's Directory Enumerator, which (on Darwin/Linux), calls fts instead, but is cross platform for Windows. diff --git a/swiftpm/Sources/Basic/FileSystem.swift b/swiftpm/Sources/Basic/FileSystem.swift index 958eaaf4..1b9e01a0 100644 --- a/swiftpm/Sources/Basic/FileSystem.swift +++ b/swiftpm/Sources/Basic/FileSystem.swift @@ -88,16 +88,18 @@ public enum FileMode { case userUnWritable case userWritable case executable - - /// File mode as it would be passed to `chmod`. - public var cliArgument: String { + + internal var setMode: (Int16) -> Int16 { switch self { case .userUnWritable: - return "u-w" + // r-x rwx rwx + return {$0 & 0o577} case .userWritable: - return "u+w" + // -w- --- --- + return {$0 | 0o200} case .executable: - return "+x" + // --x --x --x + return {$0 | 0o111} } } } @@ -375,86 +377,39 @@ private class LocalFileSystem: FileSystem { } func chmod(_ mode: FileMode, path: AbsolutePath, options: Set) throws { - #if os(macOS) - // Get the mode we need to set. - guard let setMode = setmode(mode.cliArgument) else { - throw FileSystemError(errno: errno) - } - defer { setMode.deallocate() } + guard exists(path) else { return } + func setMode(path: String) throws { + // Skip if only files should be changed. + if options.contains(.onlyFiles) && isDirectory(AbsolutePath(path)) { + return + } - let recursive = options.contains(.recursive) - // If we're in recursive mode, do physical walk otherwise logical. - let ftsOptions = recursive ? FTS_PHYSICAL : FTS_LOGICAL + let attrs = try FileManager.default.attributesOfItem(atPath: path) - // Get handle to the file hierarchy we want to traverse. - let paths = CStringArray([path.pathString]) - guard let ftsp = fts_open(paths.cArray, ftsOptions, nil) else { - throw FileSystemError(errno: errno) + // Compute the new mode for this file. + let currentMode = attrs[.posixPermissions] as! Int16 + let newMode = mode.setMode(currentMode) + guard newMode != currentMode else { return } + try FileManager.default.setAttributes([.posixPermissions : newMode], + ofItemAtPath: path) } - defer { fts_close(ftsp) } - - // Start traversing. - while let p = fts_read(ftsp) { - - switch Int32(p.pointee.fts_info) { - - // A directory being visited in pre-order. - case FTS_D: - // If we're not recursing, skip the contents of the directory. - if !recursive { - fts_set(ftsp, p, FTS_SKIP) - } - continue - - // A directory couldn't be read. - case FTS_DNR: - // FIXME: We should warn here. - break - - // There was an error. - case FTS_ERR: - fallthrough - // No stat(2) information was available. - case FTS_NS: - // FIXME: We should warn here. - continue + try setMode(path: path.pathString) + guard isDirectory(path) else { return } - // A symbolic link. - case FTS_SL: - fallthrough - - // A symbolic link with a non-existent target. - case FTS_SLNONE: - // The only symlinks that end up here are ones that don't point - // to anything and ones that we found doing a physical walk. - continue - - default: - break - } - - // Compute the new mode for this file. - let currentMode = mode_t(p.pointee.fts_statp.pointee.st_mode) - - // Skip if only files should be changed. - if options.contains(.onlyFiles) && (currentMode & S_IFMT) == S_IFDIR { - continue - } + guard let traverse = FileManager.default.enumerator( + at: URL(fileURLWithPath: path.pathString), + includingPropertiesForKeys: nil) else { + throw FileSystemError.noEntry + } - // Compute the new mode. - let newMode = getmode(setMode, currentMode) - if newMode == currentMode { - continue - } + if !options.contains(.recursive) { + traverse.skipDescendants() + } - // Update the mode. - // - // We ignore the errors for now but we should have a way to report back. - _ = SPMLibc.chmod(p.pointee.fts_accpath, newMode) + while let path = traverse.nextObject() { + try setMode(path: (path as! URL).path) } - #endif - // FIXME: We only support macOS right now. } } diff --git a/swiftpm/Sources/clibc/include/clibc.h b/swiftpm/Sources/clibc/include/clibc.h index 7cf808c1..8a90bffa 100644 --- a/swiftpm/Sources/clibc/include/clibc.h +++ b/swiftpm/Sources/clibc/include/clibc.h @@ -1,5 +1,3 @@ -#include - #if defined(__linux__) #include #endif