[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] channel: add ssh_channel_write timeout family
[Thread Prev] | [Thread Next]
- Subject: [PATCH] channel: add ssh_channel_write timeout family
- From: Jon Simons <jon@xxxxxxxxxxxxx>
- Reply-to: libssh@xxxxxxxxxx
- Date: Sun, 02 Feb 2014 04:57:00 -0800
- To: libssh@xxxxxxxxxx
Hi, Attached is a patch which adds timeout versions of the ssh_channel_write functions. The thinking is that these complement ssh_read_channel_timeout, and provide a way for clients to specify their own timeouts to be used for each of the 'waitsession_unblocked' and 'waitwindow_termination' loops that take place before the write. There should be no behavior change for the existing ssh_channel_write functions. -Jon
From 172504dfdb57629b0dd9f8c6d5b37b4814e10250 Mon Sep 17 00:00:00 2001 From: Jon Simons <jon@xxxxxxxxxxxxx> Date: Tue, 28 Jan 2014 21:06:24 -0800 Subject: [PATCH] channel: add ssh_channel_write timeout family --- include/libssh/channels.h | 2 +- include/libssh/libssh.h | 1 + include/libssh/server.h | 6 +++- src/channels.c | 77 ++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 69 insertions(+), 17 deletions(-) diff --git a/include/libssh/channels.h b/include/libssh/channels.h index 4515223..f155287 100644 --- a/include/libssh/channels.h +++ b/include/libssh/channels.h @@ -97,7 +97,7 @@ int ssh_channel_flush(ssh_channel channel); uint32_t ssh_channel_new_id(ssh_session session); ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id); int channel_write_common(ssh_channel channel, const void *data, - uint32_t len, int is_stderr); + uint32_t len, int is_stderr, int timeout_ms); void ssh_channel_do_free(ssh_channel channel); #ifdef WITH_SSH1 SSH_PACKET_CALLBACK(ssh_packet_data1); diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h index 31bcc86..1456495 100644 --- a/include/libssh/libssh.h +++ b/include/libssh/libssh.h @@ -396,6 +396,7 @@ LIBSSH_API int ssh_channel_select(ssh_channel *readchans, ssh_channel *writechan timeval * timeout); LIBSSH_API void ssh_channel_set_blocking(ssh_channel channel, int blocking); LIBSSH_API int ssh_channel_write(ssh_channel channel, const void *data, uint32_t len); +LIBSSH_API int ssh_channel_write_timeout(ssh_channel channel, const void *data, uint32_t len, int timeout_ms); LIBSSH_API uint32_t ssh_channel_window_size(ssh_channel channel); LIBSSH_API char *ssh_basename (const char *path); diff --git a/include/libssh/server.h b/include/libssh/server.h index 9d095fe..af60596 100644 --- a/include/libssh/server.h +++ b/include/libssh/server.h @@ -379,8 +379,12 @@ LIBSSH_API int ssh_channel_request_send_exit_signal(ssh_channel channel, const char *errmsg, const char *lang); LIBSSH_API int ssh_channel_write_stderr(ssh_channel channel, + const void *data, + uint32_t len); +LIBSSH_API int ssh_channel_write_stderr_timeout(ssh_channel channel, const void *data, - uint32_t len); + uint32_t len, + int timeout_ms); LIBSSH_API int ssh_send_keepalive(ssh_session session); diff --git a/src/channels.c b/src/channels.c index b77ad0a..eb111fc 100644 --- a/src/channels.c +++ b/src/channels.c @@ -1271,8 +1271,24 @@ int ssh_channel_flush(ssh_channel channel){ return ssh_blocking_flush(channel->session, SSH_TIMEOUT_DEFAULT); } +/** + * @internal + * @brief Write to the given channel's stdout or stderr, specifying + * a timeout in millseconds or any of the SSH_TIMEOUT* values. + * + * @param[in] channel The channel to write to. + * @param[in] data A pointer to the data to write. + * @param[in] len The length of the source buffer. + * @param[in] is_stderr Whether to write to stderr or stdout. + * @param[in] timeout_ms Timeout in millseconds, or any of the + * SSH_TIMEOUT* values. + * + * @return The number of bytes written, 0 upon timeout, SSH_ERROR on error. + * + * @see ssh_channel_read() + */ int channel_write_common(ssh_channel channel, const void *data, - uint32_t len, int is_stderr) { + uint32_t len, int is_stderr, int timeout_ms) { ssh_session session; uint32_t origlen = len; size_t effectivelen; @@ -1325,7 +1341,7 @@ int channel_write_common(ssh_channel channel, const void *data, } #endif if (ssh_waitsession_unblocked(session) == 0){ - rc = ssh_handle_packets_termination(session, SSH_TIMEOUT_DEFAULT, + rc = ssh_handle_packets_termination(session, timeout_ms, ssh_waitsession_unblocked, session); if (rc == SSH_ERROR || !ssh_waitsession_unblocked(session)) goto out; @@ -1341,7 +1357,7 @@ int channel_write_common(ssh_channel channel, const void *data, /* nothing can be written */ SSH_LOG(SSH_LOG_PROTOCOL, "Wait for a growing window message..."); - rc = ssh_handle_packets_termination(session, SSH_TIMEOUT_DEFAULT, + rc = ssh_handle_packets_termination(session, timeout_ms, ssh_channel_waitwindow_termination,channel); if (rc == SSH_ERROR || !ssh_channel_waitwindow_termination(channel) || @@ -1403,20 +1419,35 @@ uint32_t ssh_channel_window_size(ssh_channel channel) { } /** - * @brief Blocking write on a channel. + * @brief Write to the given channel's stdout. * * @param[in] channel The channel to write to. - * * @param[in] data A pointer to the data to write. + * @param[in] len The length of the source buffer. * - * @param[in] len The length of the buffer to write to. - * - * @return The number of bytes written, SSH_ERROR on error. + * @return The number of bytes written, SSH_ERROR on error. * * @see ssh_channel_read() */ int ssh_channel_write(ssh_channel channel, const void *data, uint32_t len) { - return channel_write_common(channel, data, len, 0); + return channel_write_common(channel, data, len, 0, SSH_TIMEOUT_DEFAULT); +} + +/** + * @brief Write to the given channel's stdout with timeout. + * + * @param[in] channel The channel to write to. + * @param[in] data A pointer to the data to write. + * @param[in] len The length of the source buffer. + * @param[in] timeout_ms Timeout in millseconds. + * + * @return The number of bytes written, 0 upon timeout, SSH_ERROR on error. + * + * @see ssh_channel_read() + */ +int ssh_channel_write_timeout(ssh_channel channel, const void *data, + uint32_t len, int timeout_ms) { + return channel_write_common(channel, data, len, 0, timeout_ms); } /** @@ -3240,20 +3271,36 @@ int ssh_channel_select(ssh_channel *readchans, ssh_channel *writechans, #if WITH_SERVER /** - * @brief Blocking write on a channel stderr. + * @brief Write to the given channel's stderr. * * @param[in] channel The channel to write to. - * * @param[in] data A pointer to the data to write. + * @param[in] len The length of the source buffer. + * + * @return The number of bytes written, SSH_ERROR on error. + * + * @see ssh_channel_read() + */ +int ssh_channel_write_stderr(ssh_channel channel, const void *data, + uint32_t len) { + return channel_write_common(channel, data, len, 1, SSH_TIMEOUT_DEFAULT); +} + +/** + * @brief Write to the given channel's stderr with timeout. * - * @param[in] len The length of the buffer to write to. + * @param[in] channel The channel to write to. + * @param[in] data A pointer to the data to write. + * @param[in] len The length of the source buffer. + * @param[in] timeout_ms Timeout in millseconds. * - * @return The number of bytes written, SSH_ERROR on error. + * @return The number of bytes written, 0 upon timeout, SSH_ERROR on error. * * @see ssh_channel_read() */ -int ssh_channel_write_stderr(ssh_channel channel, const void *data, uint32_t len) { - return channel_write_common(channel, data, len, 1); +int ssh_channel_write_stderr_timeout(ssh_channel channel, const void *data, + uint32_t len, int timeout_ms) { + return channel_write_common(channel, data, len, 1, timeout_ms); } /** -- 1.8.4.21.g992c386
Archive administrator: postmaster@lists.cynapses.org