1
0
mirror of https://github.com/libssh2/libssh2.git synced 2025-08-07 08:02:56 +03:00

channel: add support for "signal" message

Can send specific signals to remote process. Allows for slightly
improved remote process management, if the server supports it.

Integration-patches-by: Viktor Szakats

* doc updates
* change `signame_len` to `size_t`
* variable scopes
* fix checksrc warnings

Closes #672
Closes #991
This commit is contained in:
Keith Dart
2022-02-11 23:20:48 -08:00
committed by Viktor Szakats
parent 5e56002055
commit a4544c0117
5 changed files with 128 additions and 0 deletions

View File

@@ -50,6 +50,7 @@ dist_man_MANS = \
libssh2_channel_setenv.3 \ libssh2_channel_setenv.3 \
libssh2_channel_setenv_ex.3 \ libssh2_channel_setenv_ex.3 \
libssh2_channel_shell.3 \ libssh2_channel_shell.3 \
libssh2_channel_signal_ex.3 \
libssh2_channel_subsystem.3 \ libssh2_channel_subsystem.3 \
libssh2_channel_wait_closed.3 \ libssh2_channel_wait_closed.3 \
libssh2_channel_wait_eof.3 \ libssh2_channel_wait_eof.3 \

View File

@@ -0,0 +1,32 @@
.TH libssh2_channel_signal_ex 3 "20 Apr 2023" "libssh2 1.11.0" "libssh2 manual"
.SH NAME
libssh2_channel_signal_ex -- Send a signal to process previously opened on channel.
.SH SYNOPSIS
.nf
#include <libssh2.h>
int
libssh2_channel_signal_ex(LIBSSH2_CHANNEL *channel,
const char *signame,
size_t signame_len)
.fi
.SH DESCRIPTION
A signal can be delivered to the remote process/service. Some servers or
systems may not implement signals, in which case they will probably ignore this
message.
\fIchannel\fP - Previously opened channel instance such as returned by
.BR libssh2_channel_open_ex(3)
\fIsigname\fP - The signal name is the same as the signal name constant, without the leading "SIG".
\fIsigname_len\fP - Length of passed signal name parameter.
There is also a macro \fIlibssh2_channel_signal(channel, signame)\fP that supplies the strlen of the signame.
.SH RETURN VALUE
Normal channel error codes.
LIBSSH2_ERROR_EAGAIN when it would block.
.SH SEE ALSO
.BR libssh2_channel_get_exit_signal(3)

View File

@@ -850,6 +850,12 @@ LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel,
#define libssh2_channel_x11_req(channel, screen_number) \ #define libssh2_channel_x11_req(channel, screen_number) \
libssh2_channel_x11_req_ex((channel), 0, NULL, NULL, (screen_number)) libssh2_channel_x11_req_ex((channel), 0, NULL, NULL, (screen_number))
LIBSSH2_API int libssh2_channel_signal_ex(LIBSSH2_CHANNEL *channel,
const char *signame,
size_t signame_len);
#define libssh2_channel_signal(channel, signame) \
libssh2_channel_signal_ex((channel), signame, strlen(signame))
LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
const char *request, const char *request,
unsigned int request_len, unsigned int request_len,

View File

@@ -2987,3 +2987,87 @@ libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel,
return channel->local.window_size; return channel->local.window_size;
} }
/* A signal can be delivered to the remote process/service using the
following message. Some systems may not implement signals, in which
case they SHOULD ignore this message.
byte SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "signal"
boolean FALSE
string signal name (without the "SIG" prefix)
'signal name' values will be encoded as discussed in the passage
describing SSH_MSG_CHANNEL_REQUEST messages using "exit-signal" in
this section.
*/
static int channel_signal(LIBSSH2_CHANNEL *channel,
const char *signame,
size_t signame_len)
{
LIBSSH2_SESSION *session = channel->session;
int retcode = LIBSSH2_ERROR_PROTO;
if(channel->sendsignal_state == libssh2_NB_state_idle) {
unsigned char *s;
/* 20 = packet_type(1) + channel(4) +
signal_len + sizeof(signal) - 1 + want_reply(1) +
signame_len_len(4) */
channel->sendsignal_packet_len = 20 + signame_len;
s = channel->sendsignal_packet =
LIBSSH2_ALLOC(session, channel->sendsignal_packet_len);
if(!channel->sendsignal_packet)
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"signal request");
*(s++) = SSH_MSG_CHANNEL_REQUEST;
_libssh2_store_u32(&s, channel->remote.id);
_libssh2_store_str(&s, "signal", sizeof("signal") - 1);
*(s++) = 0x00; /* Don't reply */
_libssh2_store_str(&s, signame, signame_len);
channel->sendsignal_state = libssh2_NB_state_created;
}
if(channel->sendsignal_state == libssh2_NB_state_created) {
int rc;
rc = _libssh2_transport_send(session, channel->sendsignal_packet,
channel->sendsignal_packet_len,
NULL, 0);
if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, rc, "Would block sending signal request");
return rc;
}
else if(rc) {
LIBSSH2_FREE(session, channel->sendsignal_packet);
channel->sendsignal_state = libssh2_NB_state_idle;
return _libssh2_error(session, rc, "Unable to send signal packet");
}
LIBSSH2_FREE(session, channel->sendsignal_packet);
retcode = LIBSSH2_ERROR_NONE;
}
channel->sendsignal_state = libssh2_NB_state_idle;
return retcode;
}
LIBSSH2_API int
libssh2_channel_signal_ex(LIBSSH2_CHANNEL *channel,
const char *signame,
size_t signame_len)
{
int rc;
if(!channel)
return LIBSSH2_ERROR_BAD_USE;
BLOCK_ADJUST(rc, channel->session,
channel_signal(channel, signame, signame_len));
return rc;
}

View File

@@ -466,6 +466,11 @@ struct _LIBSSH2_CHANNEL
size_t req_auth_agent_packet_len; size_t req_auth_agent_packet_len;
unsigned char req_auth_agent_local_channel[4]; unsigned char req_auth_agent_local_channel[4];
packet_requirev_state_t req_auth_agent_requirev_state; packet_requirev_state_t req_auth_agent_requirev_state;
/* State variables used in libssh2_channel_signal_ex() */
libssh2_nonblocking_states sendsignal_state;
unsigned char *sendsignal_packet;
size_t sendsignal_packet_len;
}; };
struct _LIBSSH2_LISTENER struct _LIBSSH2_LISTENER