2

When using Ruby, the following will terminate the current ruby script and replace the process with an instance of ssh:

exec "ssh host -p 1234 -v"

Is this possible to do in Swift?

Doug
  • 2,972
  • 3
  • 22
  • 28
  • There used to be a `system` API in Swift, but it is deprecated in favor of the `posix_spawn` APIs and `NSTask`. I'd start with those. – JAL Nov 29 '16 at 21:27
  • @JAL: Those are slightly different, posix_spawn create a new process. The execX functions replace the existing process. – Martin R Nov 29 '16 at 22:34

1 Answers1

3

execv and related functions from the BSD library can be called from Swift (with the exception of those with a variable argument list). The only "challenge" is to create a

UnsafePointer<UnsafeMutablePointer<Int8>?>

that can be passed as the argument list. A simple example:

import Foundation

let args = ["ls", "-l", "/Library"]

// Array of UnsafeMutablePointer<Int8>
let cargs = args.map { strdup($0) } + [nil]

execv("/bin/ls", cargs)

fatalError("exec failed")

Here it is used that you can pass a Swift string to the C function strdup() which expects a const char *, and the compiler creates a temporary UTF-8 representation (see String value to UnsafePointer<UInt8> function parameter behavior).

Community
  • 1
  • 1
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • So this works, other than I also had to add `cargs.append(nil)` just before calling `execv`. Thanks! – Doug Nov 29 '16 at 22:09