SHARE
TWEET

Untitled

a guest Mar 20th, 2017 62 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import Foundation
  2.  
  3. func withCStrings(_ strings: [String], scoped: ([UnsafeMutablePointer<CChar>?]) throws -> Void) rethrows {
  4.     let cStrings = strings.map { strdup($0) }
  5.     try scoped(cStrings + [nil])
  6.     cStrings.forEach { free($0) }
  7. }
  8.  
  9. enum RunCommandError: Error {
  10.     case WaitPIDError
  11.     case POSIXSpawnError(Int32)
  12. }
  13.  
  14. func runCommand(_ command: String, completion: ((Int32) -> Void)? = nil) throws {
  15.     var pid: pid_t = 0
  16.     let args = ["sh", "-c", command]
  17.     let envs = ProcessInfo().environment.map { k, v in "\(k)=\(v)" }
  18.     try withCStrings(args) { cArgs in
  19.         try withCStrings(envs) { cEnvs in
  20.             var status = posix_spawn(&pid, "/bin/sh", nil, nil, cArgs, cEnvs)
  21.             if status == 0 {
  22.                 if (waitpid(pid, &status, 0) != -1) {
  23.                     completion?(status)
  24.                 } else {
  25.                     throw RunCommandError.WaitPIDError
  26.                 }
  27.             } else {
  28.                 throw RunCommandError.POSIXSpawnError(status)
  29.             }
  30.         }
  31.     }
  32. }
RAW Paste Data
Top