Hey

Here's an old mail I spotted we never got anywhere with. Did anyone have a look?

--

 / daniel.haxx.se

---------- Forwarded message ----------
Date: Mon, 5 Oct 2009 00:03:51
From: Adrian <[email protected]>
To: [email protected]
Subject: [PATCH] Add signal support

As mentioned in IRC, here's the (untested, thanks to OpenSSH's lack of
signal support) patch to add signals.

--
Adrian
diff --git a/include/libssh2.h b/include/libssh2.h
index 685a5cc..f3c25a4 100644
--- a/include/libssh2.h
+++ b/include/libssh2.h
@@ -529,6 +529,13 @@ LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel,
  libssh2_channel_setenv_ex((channel), (varname), strlen(varname), (value), \
                            strlen(value))
 
+LIBSSH2_API int libssh2_channel_signal_ex(LIBSSH2_CHANNEL *channel,
+                                          const char *signame,
+                                          unsigned int signame_len);
+
+#define libssh2_channel_signal(channel, signame) \
+ libssh2_channel_signal_ex((channel), (signame), strlen(signame))
+
 LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel,
                                                const char *term,
                                                unsigned int term_len,
diff --git a/src/channel.c b/src/channel.c
index 0a840da..2c64cce 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -896,6 +896,94 @@ libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel,
 }
 
 /*
+ * channel_signal
+ *
+ * Send a signal to the running shell/program
+ */
+static int channel_signal(LIBSSH2_CHANNEL *channel,
+                          const char *signame, unsigned int signame_len)
+{
+    LIBSSH2_SESSION *session = channel->session;
+    unsigned char *s;
+    int rc;
+
+    if (channel->signal_state == libssh2_NB_state_idle) {
+        /* 20 = packet_type(1) + channel_id(4) + request_len(4) +
+         * request(6)"signal" + want_reply(1) + signame_len(4) */
+        channel->signal_packet_len = signame_len + 20;
+
+        _libssh2_debug(session, LIBSSH2_DBG_CONN,
+                       "Sending signal: %s on channel %lu/%lu",
+                       signame, channel->local.id, channel->remote.id);
+
+        s = channel->signal_packet =
+            LIBSSH2_ALLOC(session, channel->signal_packet_len);
+        if (!channel->signal_packet) {
+            libssh2_error(session, LIBSSH2_ERROR_ALLOC,
+                          "Unable to allocate memeory for signal packet", 0);
+            return LIBSSH2_ERROR_ALLOC;
+        }
+
+        *(s++) = SSH_MSG_CHANNEL_REQUEST;
+        _libssh2_htonu32(s, channel->remote.id);
+        s += 4;
+        _libssh2_htonu32(s, sizeof("signal") - 1);
+        s += 4;
+        memcpy(s, "signal", sizeof("signal") - 1);
+        s += sizeof("signal") - 1;
+
+        *(s++) = 0x00; /* Don't reply */
+
+        _libssh2_htonu32(s, signame_len);
+        s += 4;
+        memcpy(s, signame, signame_len);
+        s += signame_len;
+
+        channel->signal_state = libssh2_NB_state_created;
+    }
+
+    if (channel->signal_state == libssh2_NB_state_created) {
+        rc = _libssh2_transport_write(session, channel->signal_packet,
+                                  channel->signal_packet_len);
+        if (rc == PACKET_EAGAIN) {
+            return rc;
+        } else if (rc) {
+            libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
+                          "Unable to send channel-request packet for "
+                          "signal request",
+                          0);
+            LIBSSH2_FREE(session, channel->signal_packet);
+            channel->signal_packet = NULL;
+            channel->signal_state = libssh2_NB_state_idle;
+            return LIBSSH2_ERROR_SOCKET_SEND;
+        }
+        LIBSSH2_FREE(session, channel->signal_packet);
+        channel->signal_packet = NULL;
+        channel->signal_state = libssh2_NB_state_sent;
+
+	return 0;
+    }
+
+    channel->signal_state = libssh2_NB_state_idle;
+    return -1;
+}
+
+/*
+ * libssh2_channel_signal_ex
+ *
+ * Send a signal to a shell/program
+ */
+LIBSSH2_API int
+libssh2_channel_signal_ex(LIBSSH2_CHANNEL *channel,
+                          const char *signame, unsigned int signame_len)
+{
+    int rc;
+    BLOCK_ADJUST(rc, channel->session,
+                 channel_signal(channel, signame, signame_len));
+    return rc;
+}
+
+/*
  * channel_request_pty
  * Duh... Request a PTY
  */
diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h
index cfb8262..fa8fe3d 100644
--- a/src/libssh2_priv.h
+++ b/src/libssh2_priv.h
@@ -364,6 +364,11 @@ struct _LIBSSH2_CHANNEL
     unsigned char setenv_local_channel[4];
     packet_requirev_state_t setenv_packet_requirev_state;
 
+    /* State variables used in libssh2_channel_signal_ex() */
+    libssh2_nonblocking_states signal_state;
+    unsigned char *signal_packet;
+    unsigned long signal_packet_len;
+
     /* State variables used in libssh2_channel_request_pty_ex() */
     libssh2_nonblocking_states reqPTY_state;
     unsigned char *reqPTY_packet;
_______________________________________________
libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel
_______________________________________________
libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel

Reply via email to