mirror of
https://git.libssh.org/projects/libssh.git
synced 2025-08-05 20:55:46 +03:00
channels: Implement better ssh_channel_get_exit_state() variant
This way we will get errors as return code else we don't know if the function failed (SSH_ERROR) or the exit_status is -1 which would correspond to SSH_ERROR. Signed-off-by: Andreas Schneider <asn@cryptomilk.org> Reviewed-by: Jakub Jelen <jjelen@redhat.com>
This commit is contained in:
@@ -462,7 +462,11 @@ LIBSSH_API int ssh_channel_close(ssh_channel channel);
|
||||
} \
|
||||
} while (0)
|
||||
LIBSSH_API void ssh_channel_free(ssh_channel channel);
|
||||
LIBSSH_API int ssh_channel_get_exit_status(ssh_channel channel);
|
||||
LIBSSH_API int ssh_channel_get_exit_state(ssh_channel channel,
|
||||
uint32_t *pexit_code,
|
||||
char **pexit_signal,
|
||||
int *pcore_dumped);
|
||||
SSH_DEPRECATED LIBSSH_API int ssh_channel_get_exit_status(ssh_channel channel);
|
||||
LIBSSH_API ssh_session ssh_channel_get_session(ssh_channel channel);
|
||||
LIBSSH_API int ssh_channel_is_closed(ssh_channel channel);
|
||||
LIBSSH_API int ssh_channel_is_eof(ssh_channel channel);
|
||||
|
@@ -498,8 +498,22 @@ public:
|
||||
return_throwable;
|
||||
}
|
||||
|
||||
int getExitStatus(){
|
||||
return ssh_channel_get_exit_status(channel);
|
||||
/*
|
||||
* @deprecated Please use getExitState()
|
||||
*/
|
||||
int getExitStatus() {
|
||||
uint32_t exit_status = (uint32_t)-1;
|
||||
ssh_channel_get_exit_state(channel, &exit_status, NULL, NULL);
|
||||
return exit_status;
|
||||
}
|
||||
void_throwable getExitState(uint32_t & pexit_code,
|
||||
char **pexit_signal,
|
||||
int & pcore_dumped) {
|
||||
ssh_throw(ssh_channel_get_exit_state(channel,
|
||||
&pexit_code,
|
||||
pexit_signal,
|
||||
&pcore_dumped));
|
||||
return_throwable;
|
||||
}
|
||||
Session &getSession(){
|
||||
return *session;
|
||||
|
@@ -3388,6 +3388,83 @@ static int ssh_channel_exit_status_termination(void *c)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the exit state of the channel (error code from the executed
|
||||
* instruction or signal).
|
||||
*
|
||||
* @param[in] channel The channel to get the status from.
|
||||
*
|
||||
* @param[out] pexit_code A pointer to an uint32_t to store the exit status.
|
||||
*
|
||||
* @param[out] pexit_signal A pointer to store the exit signal as a string.
|
||||
* The signal is without the SIG prefix, e.g. "TERM" or
|
||||
* "KILL"). The caller has to free the memory.
|
||||
*
|
||||
* @param[out] pcore_dumped A pointer to store a boolean value if it dumped a
|
||||
* core.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_AGAIN if we don't have a status
|
||||
* or an SSH error.
|
||||
* @warning This function may block until a timeout (or never)
|
||||
* if the other side is not willing to close the channel.
|
||||
* When a channel is freed the function returns
|
||||
* SSH_ERROR immediately.
|
||||
*
|
||||
* If you're looking for an async handling of this register a callback for the
|
||||
* exit status!
|
||||
*
|
||||
* @see ssh_channel_exit_status_callback
|
||||
* @see ssh_channel_exit_signal_callback
|
||||
*/
|
||||
int ssh_channel_get_exit_state(ssh_channel channel,
|
||||
uint32_t *pexit_code,
|
||||
char **pexit_signal,
|
||||
int *pcore_dumped)
|
||||
{
|
||||
ssh_session session = NULL;
|
||||
int rc;
|
||||
|
||||
if ((channel == NULL) || (channel->flags & SSH_CHANNEL_FLAG_FREED_LOCAL)) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
session = channel->session;
|
||||
|
||||
rc = ssh_handle_packets_termination(channel->session,
|
||||
SSH_TIMEOUT_DEFAULT,
|
||||
ssh_channel_exit_status_termination,
|
||||
channel);
|
||||
if (rc == SSH_ERROR || channel->session->session_state ==
|
||||
SSH_SESSION_STATE_ERROR) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/* If we don't have any kind of exit state, return SSH_AGAIN */
|
||||
if (!channel->exit.status) {
|
||||
return SSH_AGAIN;
|
||||
}
|
||||
|
||||
if (pexit_code != NULL) {
|
||||
*pexit_code = channel->exit.code;
|
||||
}
|
||||
|
||||
if (pexit_signal != NULL) {
|
||||
*pexit_signal = NULL;
|
||||
if (channel->exit.signal != NULL) {
|
||||
*pexit_signal = strdup(channel->exit.signal);
|
||||
if (pexit_signal == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pcore_dumped != NULL) {
|
||||
*pcore_dumped = channel->exit.core_dumped;
|
||||
}
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the exit status of the channel (error code from the executed
|
||||
* instruction).
|
||||
@@ -3405,21 +3482,19 @@ static int ssh_channel_exit_status_termination(void *c)
|
||||
* exit status.
|
||||
*
|
||||
* @see ssh_channel_exit_status_callback
|
||||
* @deprecated Please use ssh_channel_exit_state()
|
||||
*/
|
||||
int ssh_channel_get_exit_status(ssh_channel channel)
|
||||
{
|
||||
uint32_t exit_status = (uint32_t)-1;
|
||||
int rc;
|
||||
if ((channel == NULL) || (channel->flags & SSH_CHANNEL_FLAG_FREED_LOCAL)) {
|
||||
|
||||
rc = ssh_channel_get_exit_state(channel, &exit_status, NULL, NULL);
|
||||
if (rc != SSH_OK) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
rc = ssh_handle_packets_termination(channel->session,
|
||||
SSH_TIMEOUT_DEFAULT,
|
||||
ssh_channel_exit_status_termination,
|
||||
channel);
|
||||
if (rc == SSH_ERROR || channel->session->session_state ==
|
||||
SSH_SESSION_STATE_ERROR)
|
||||
return SSH_ERROR;
|
||||
return channel->exit.code;
|
||||
|
||||
return exit_status;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -403,7 +403,7 @@ static void torture_channel_exit_status(void **state)
|
||||
ssh_session session = s->ssh.session;
|
||||
ssh_channel channel = NULL;
|
||||
char request[256];
|
||||
int exit_status = -1;
|
||||
uint32_t exit_status = (uint32_t)-1;
|
||||
int rc;
|
||||
|
||||
rc = snprintf(request, sizeof(request), "true");
|
||||
@@ -419,7 +419,8 @@ static void torture_channel_exit_status(void **state)
|
||||
rc = ssh_channel_request_exec(channel, request);
|
||||
assert_ssh_return_code(session, rc);
|
||||
|
||||
exit_status = ssh_channel_get_exit_status(channel);
|
||||
exit_status = ssh_channel_get_exit_state(channel, &exit_status, NULL, NULL);
|
||||
assert_ssh_return_code(session, rc);
|
||||
assert_int_equal(exit_status, 0);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user