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