diff options
| -rw-r--r-- | NEWS | 10 | ||||
| -rw-r--r-- | libguile-ssh/channel-type.c | 28 | ||||
| -rw-r--r-- | tests/client-server.scm | 19 |
3 files changed, 45 insertions, 12 deletions
@@ -13,7 +13,15 @@ Copyright (C) Artyom V. Poptsov <poptsov.artyom@gmail.com> **** 'node-guile-version' now does not fail The procedure would always fail to get Guile version. Now that should be fixed. -** Update uit tests +*** In (ssh channel) +**** Printing a freed channel doesn't lead to SIGSEGV anymore + Guile-SSH would always crash with SIGSEGV errors when tried to print a + freed channel object (e.g. after calling 'close' on a channel). This bug + is fixed now by introducing new checks. + + Now a freed channel will be printed like this: + #<unknown channel (freed) 9412f0> +** Update unit tests *** Add test cases for fixed bugs * Changes in version 0.11.1 (2017-05-09) diff --git a/libguile-ssh/channel-type.c b/libguile-ssh/channel-type.c index 3dd641f..cc9dae6 100644 --- a/libguile-ssh/channel-type.c +++ b/libguile-ssh/channel-type.c @@ -1,6 +1,6 @@ /* channel-type.c -- SSH channel smob. * - * Copyright (C) 2013, 2014, 2015 Artyom V. Poptsov <poptsov.artyom@gmail.com> + * Copyright (C) 2013, 2014, 2015, 2016, 2017 Artyom V. Poptsov <poptsov.artyom@gmail.com> * Copyright (C) 2017 Ludovic Courtès <ludo@gnu.org> * * This file is part of Guile-SSH. @@ -244,24 +244,30 @@ ptob_close (SCM channel) static int print_channel (SCM channel, SCM port, scm_print_state *pstate) { - struct channel_data *ch = _scm_to_channel_data (channel); + struct channel_data *ch = NULL; + + if (SCM_PTAB_ENTRY (channel)) + ch = _scm_to_channel_data (channel); scm_puts ("#<", port); - scm_print_port_mode (channel, port); - scm_puts ("channel ", port); if (! ch) { - scm_puts ("(freed) ", port); - } - else if (SCM_OPPORTP (channel)) - { - int is_open = ssh_channel_is_open (ch->ssh_channel); - scm_puts (is_open ? "(open) " : "(closed) ", port); + scm_puts ("unknown channel (freed) ", port); } else { - scm_puts ("(closed) ", port); + scm_print_port_mode (channel, port); + scm_puts ("channel ", port); + if (SCM_OPPORTP (channel)) + { + int is_open = ssh_channel_is_open (ch->ssh_channel); + scm_puts (is_open ? "(open) " : "(closed) ", port); + } + else + { + scm_puts ("(closed) ", port); + } } scm_display (_scm_object_hex_address (channel), port); scm_puts (">", port); diff --git a/tests/client-server.scm b/tests/client-server.scm index b56a329..702cd3a 100644 --- a/tests/client-server.scm +++ b/tests/client-server.scm @@ -23,6 +23,7 @@ (srfi srfi-26) (ice-9 threads) (ice-9 rdelim) + (ice-9 regex) (rnrs bytevectors) (rnrs io ports) (ssh server) @@ -585,6 +586,24 @@ (channel-request-exec channel "uname") (channel-get-exit-status channel))))))) +(test-assert-with-log "channel-request-exec, printing a freed channel" + (run-client-test + + ;; server + (lambda (server) + (start-server/channel-test server)) + + ;; client + (lambda () + (call-with-connected-session/channel-test + (lambda (session) + (let ((channel (make-channel session))) + (channel-open-session channel) + (channel-request-exec channel "uname") + (close channel) + (string-match "#<unknown channel \\(freed\\) [0-9a-f]+>" + (object->string channel)))))))) + ;; data transferring ;; FIXME: Probably these TCs can be implemented more elegantly. |
