Skip to content

Commit 36e19d3

Browse files
committed
Process: Reset the current directory even if the process fails.
1 parent 3a95d78 commit 36e19d3

File tree

2 files changed

+31
-6
lines changed

2 files changed

+31
-6
lines changed

Foundation/Process.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -450,16 +450,17 @@ open class Process: NSObject {
450450
throw _NSErrorWithErrno(errno, reading: true, url: currentDirectoryURL)
451451
}
452452

453-
// Launch
453+
defer {
454+
// Reset the previous working directory path.
455+
fileManager.changeCurrentDirectoryPath(previousDirectoryPath)
456+
}
454457

458+
// Launch
455459
var pid = pid_t()
456460
guard posix_spawn(&pid, launchPath, &fileActions, nil, argv, envp) == 0 else {
457461
throw _NSErrorWithErrno(errno, reading: true, path: launchPath)
458462
}
459463

460-
// Reset the previous working directory path.
461-
fileManager.changeCurrentDirectoryPath(previousDirectoryPath)
462-
463464
// Close the write end of the input and output pipes.
464465
if let pipe = standardInput as? Pipe {
465466
pipe.fileHandleForReading.closeFile()

TestFoundation/TestProcess.swift

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,21 +289,45 @@ class TestProcess : XCTestCase {
289289
}
290290

291291
func test_run() {
292+
let fm = FileManager.default
293+
let cwd = fm.currentDirectoryPath
294+
292295
do {
293296
let process = try Process.run(URL(fileURLWithPath: "/bin/sh", isDirectory: false), arguments: ["-c", "exit 123"], terminationHandler: nil)
294297
process.waitUntilExit()
295298
XCTAssertEqual(process.terminationReason, .exit)
296299
XCTAssertEqual(process.terminationStatus, 123)
297300
} catch {
298-
XCTFail("Cant execute /bin/sh: error")
301+
XCTFail("Cant execute /bin/sh: \(error)")
302+
}
303+
XCTAssertEqual(fm.currentDirectoryPath, cwd)
304+
305+
do {
306+
let process = Process()
307+
process.executableURL = URL(fileURLWithPath: "/bin/sh", isDirectory: false)
308+
process.arguments = ["-c", "exit 0"]
309+
process.currentDirectoryURL = URL(fileURLWithPath: "/.../_no_such_directory", isDirectory: true)
310+
try process.run()
311+
XCTFail("Executed /bin/sh with invalid currentDirectoryURL")
312+
process.terminate()
313+
process.waitUntilExit()
314+
} catch {
299315
}
316+
XCTAssertEqual(fm.currentDirectoryPath, cwd)
300317

301318
do {
302-
let process = try Process.run(URL(fileURLWithPath: "/..", isDirectory: false), arguments: [], terminationHandler: nil)
319+
let process = Process()
320+
process.executableURL = URL(fileURLWithPath: "/..", isDirectory: false)
321+
process.arguments = []
322+
process.currentDirectoryURL = URL(fileURLWithPath: "/tmp")
323+
try process.run()
303324
XCTFail("Somehow executed a directory!")
304325
process.terminate()
326+
process.waitUntilExit()
305327
} catch {
306328
}
329+
XCTAssertEqual(fm.currentDirectoryPath, cwd)
330+
fm.changeCurrentDirectoryPath(cwd)
307331
}
308332

309333
#endif

0 commit comments

Comments
 (0)