jakeheis / Shout

SSH made easy in Swift
MIT License
357 stars 103 forks source link

SSH and SFTP connections must have deinit managed manually #37

Closed Redoubts closed 4 years ago

Redoubts commented 4 years ago

I'm trying to connect to a device with an SSH session and SFTP session. My class is something like

class Device {
    let ssh_conn: SSH
    let sftp_conn: SFTP

    init() {
        ssh_conn = try! SSH(host: "localhost", port: port)
        try! ssh_conn.authenticate(username: "user", password: "password")
        sftp_conn = try! ssh_conn.openSftp()
    }
    func test() {
        do {
            let (_, ssh_output) = try ssh_conn.capture("some command")
            print(ssh_output)

            try sftp_conn.download(remotePath: "/some/path", localURL: URL(fileURLWithPath: "/some/local/path"))
            try sftp_conn.upload(localURL: URL(fileURLWithPath: "/some/local/path"), remotePath: "/some/path2")
        } catch let error as SSHError {
            ...
        }
    }
}

I'm finding that when Device goes out of scope, I get an EXC_BAD_ACCESS from the sftp deinit (libssh2_sftp_shutdown(sftpSession)). I can work around it by adding a deinit function to this, where I nil out the sftp connection first.

    deinit {
        sftp_conn = nil
        ssh_conn = nil

    }

But I find this weird, and makes all my connection members look like var sftp_conn: SFTP!, which seems ugly. Is there any reason I should have to manage the lifecycle of these connections manually like this? Am I using this inappropriately?

Shout 0.5.1; Swift 5.1, MacOS catalina.

jakeheis commented 4 years ago

I believe 15dffc008426bf8af3d6a53d77bd04f0de544259 should have fixed the issue, could you pin Shout to this commit and see if it fixes the issue?

jakeheis commented 4 years ago

0.5.5