[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