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)
|
} while (0)
|
||||||
LIBSSH_API void ssh_channel_free(ssh_channel channel);
|
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 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_closed(ssh_channel channel);
|
||||||
LIBSSH_API int ssh_channel_is_eof(ssh_channel channel);
|
LIBSSH_API int ssh_channel_is_eof(ssh_channel channel);
|
||||||
|
@@ -498,8 +498,22 @@ public:
|
|||||||
return_throwable;
|
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(){
|
Session &getSession(){
|
||||||
return *session;
|
return *session;
|
||||||
|
@@ -3388,6 +3388,83 @@ static int ssh_channel_exit_status_termination(void *c)
|
|||||||
return 0;
|
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
|
* @brief Get the exit status of the channel (error code from the executed
|
||||||
* instruction).
|
* instruction).
|
||||||
@@ -3405,21 +3482,19 @@ static int ssh_channel_exit_status_termination(void *c)
|
|||||||
* exit status.
|
* exit status.
|
||||||
*
|
*
|
||||||
* @see ssh_channel_exit_status_callback
|
* @see ssh_channel_exit_status_callback
|
||||||
|
* @deprecated Please use ssh_channel_exit_state()
|
||||||
*/
|
*/
|
||||||
int ssh_channel_get_exit_status(ssh_channel channel)
|
int ssh_channel_get_exit_status(ssh_channel channel)
|
||||||
{
|
{
|
||||||
int rc;
|
uint32_t exit_status = (uint32_t)-1;
|
||||||
if ((channel == NULL) || (channel->flags & SSH_CHANNEL_FLAG_FREED_LOCAL)) {
|
int rc;
|
||||||
return SSH_ERROR;
|
|
||||||
}
|
rc = ssh_channel_get_exit_state(channel, &exit_status, NULL, NULL);
|
||||||
rc = ssh_handle_packets_termination(channel->session,
|
if (rc != SSH_OK) {
|
||||||
SSH_TIMEOUT_DEFAULT,
|
return SSH_ERROR;
|
||||||
ssh_channel_exit_status_termination,
|
}
|
||||||
channel);
|
|
||||||
if (rc == SSH_ERROR || channel->session->session_state ==
|
return exit_status;
|
||||||
SSH_SESSION_STATE_ERROR)
|
|
||||||
return SSH_ERROR;
|
|
||||||
return channel->exit.code;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -403,7 +403,7 @@ static void torture_channel_exit_status(void **state)
|
|||||||
ssh_session session = s->ssh.session;
|
ssh_session session = s->ssh.session;
|
||||||
ssh_channel channel = NULL;
|
ssh_channel channel = NULL;
|
||||||
char request[256];
|
char request[256];
|
||||||
int exit_status = -1;
|
uint32_t exit_status = (uint32_t)-1;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = snprintf(request, sizeof(request), "true");
|
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);
|
rc = ssh_channel_request_exec(channel, request);
|
||||||
assert_ssh_return_code(session, rc);
|
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);
|
assert_int_equal(exit_status, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user