From c468d9c2dc343446757360857a295736359b3024 Mon Sep 17 00:00:00 2001
From: "Artyom V. Poptsov" <poptsov.artyom@gmail.com>
Date: Tue, 7 Aug 2018 07:55:00 +0300
Subject: [PATCH] libguile-ssh/channel-type.c (ptob_close): Bugfix: fix a
 segfault

'ptob_close' would always get a segfault when it tried to free a closed
channel.  This patch fixes that by adding a check if a channel is already
closed.

Reported by Michael Bowcutt <mbowcutt@case.edu> in
  <https://github.com/artyom-poptsov/guile-ssh/issues/8>
  and Njagi Mwaniki in a personal email.

* libguile-ssh/channel-type.c (ptob_close): Check if a channel is already
  closed before trying to close and free it.  Improve logging.
* libguile-ssh/log.c (_gssh_log_debug, _gssh_log_debug1): New procedures
* libguile-ssh/log.h: Likewise.
---
 libguile-ssh/channel-type.c | 10 +++++++++-
 libguile-ssh/log.c          | 21 +++++++++++++++++++++
 libguile-ssh/log.h          |  3 +++
 3 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/libguile-ssh/channel-type.c b/libguile-ssh/channel-type.c
index ffcca64..4b0b9ae 100644
--- a/libguile-ssh/channel-type.c
+++ b/libguile-ssh/channel-type.c
@@ -29,6 +29,7 @@
 #include "channel-type.h"
 #include "error.h"
 #include "common.h"
+#include "log.h"
 
 
 /* The channel port type.  Guile 2.2 introduced a new port API, so we have a
@@ -223,10 +224,17 @@ ptob_close (SCM channel)
   ptob_flush (channel);
 #endif
 
-  if (ch)
+  if (ch && ssh_channel_is_open (ch->ssh_channel))
     {
+      _gssh_log_debug ("ptob_close", "closing and freeing the channel...",
+                       channel);
       ssh_channel_close (ch->ssh_channel);
       ssh_channel_free (ch->ssh_channel);
+      _gssh_log_debug1 ("ptob_close", "closing and freeing the channel... done");
+    }
+  else
+    {
+      _gssh_log_debug1 ("ptob_close", "the channel is already freeed.");
     }
 
   SCM_SETSTREAM (channel, NULL);
diff --git a/libguile-ssh/log.c b/libguile-ssh/log.c
index 6588749..e0e3027 100644
--- a/libguile-ssh/log.c
+++ b/libguile-ssh/log.c
@@ -270,6 +270,27 @@ _gssh_log_warning (const char* function_name, const char* msg, SCM args)
   scm_dynwind_end ();
 }
 
+void
+_gssh_log_debug (const char* function_name, const char* msg, SCM args)
+{
+  char *c_str;
+  scm_dynwind_begin (0);
+
+  c_str = scm_to_locale_string (scm_object_to_string (args, SCM_UNDEFINED));
+  scm_dynwind_free (c_str);
+
+  _ssh_log (SSH_LOG_FUNCTIONS, function_name, "[GSSH DEBUG] %s: %s",
+            msg, c_str);
+
+  scm_dynwind_end ();
+}
+
+void
+_gssh_log_debug1 (const char* function_name, const char* msg)
+{
+  _ssh_log (SSH_LOG_FUNCTIONS, function_name, "[GSSH DEBUG] %s", msg);
+}
+
 
 /* Initialization */
 
diff --git a/libguile-ssh/log.h b/libguile-ssh/log.h
index dd1424b..c3fe866 100644
--- a/libguile-ssh/log.h
+++ b/libguile-ssh/log.h
@@ -28,6 +28,9 @@ extern void _gssh_log_error (const char* function_name, const char* msg,
 
 extern void _gssh_log_warning (const char* function_name, const char* msg,
                                SCM args);
+extern void _gssh_log_debug (const char* function_name, const char* msg,
+                             SCM args);
+extern void _gssh_log_debug1 (const char* function_name, const char* msg);
 
 extern void init_log_func (void);
 
-- 
2.20.1

