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:
committed by
Viktor Szakats
parent
5e56002055
commit
a4544c0117
@@ -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 \
|
||||||
|
32
docs/libssh2_channel_signal_ex.3
Normal file
32
docs/libssh2_channel_signal_ex.3
Normal 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)
|
@@ -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,
|
||||||
|
@@ -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;
|
||||||
|
}
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user