Skip to content

Commit

Permalink
Allow writing to stdin for SshCommand execution
Browse files Browse the repository at this point in the history
  • Loading branch information
skogaby committed Feb 7, 2018
1 parent 7691cb0 commit 7945a95
Showing 1 changed file with 46 additions and 3 deletions.
49 changes: 46 additions & 3 deletions src/Renci.SshNet/SshCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,8 @@ public IAsyncResult BeginExecute(AsyncCallback callback)
/// </summary>
/// <param name="callback">An optional asynchronous callback, to be called when the command execution is complete.</param>
/// <param name="state">A user-provided object that distinguishes this particular asynchronous read request from other requests.</param>
/// <param name="stdout">A stream to be used as the output stream.</param>
/// <param name="stderr">A stream to be used as the extended output stream.</param>
/// <returns>
/// An <see cref="IAsyncResult" /> that represents the asynchronous command execution, which could still be pending.
/// </returns>
Expand All @@ -205,7 +207,7 @@ public IAsyncResult BeginExecute(AsyncCallback callback)
/// <exception cref="SshOperationTimeoutException">Operation has timed out.</exception>
/// <exception cref="InvalidOperationException">Asynchronous operation is already in progress.</exception>
/// <exception cref="ArgumentException">CommandText property is empty.</exception>
public IAsyncResult BeginExecute(AsyncCallback callback, object state)
public IAsyncResult BeginExecute(AsyncCallback callback, object state, Stream stdout = null, Stream stderr = null)
{
// Prevent from executing BeginExecute before calling EndExecute
if (_asyncResult != null && !_asyncResult.EndCalled)
Expand Down Expand Up @@ -245,8 +247,8 @@ public IAsyncResult BeginExecute(AsyncCallback callback, object state)
}

// Initialize output streams
OutputStream = new PipeStream();
ExtendedOutputStream = new PipeStream();
OutputStream = (stdout == null ? new PipeStream() : stdout);
ExtendedOutputStream = (stderr == null ? new PipeStream() : stderr);

_result = null;
_error = null;
Expand Down Expand Up @@ -307,6 +309,9 @@ public string EndExecute(IAsyncResult asyncResult)
throw new ArgumentException("EndExecute can only be called once for each asynchronous operation.");
}

// always send EOF when closing exec channel
_channel.SendEof();

// wait for operation to complete (or time out)
WaitOnHandle(_asyncResult.AsyncWaitHandle);

Expand Down Expand Up @@ -514,6 +519,44 @@ private void UnsubscribeFromEventsAndDisposeChannel(IChannel channel)
channel.Dispose();
}

/// <summary>
/// Sends the data to channel.
/// </summary>
/// <param name="data">Data.</param>
public void SendData(byte[] data)
{
SendData(data, 0, data.Length);
}

/// <summary>
/// Sends the data with offset and size to channel.
/// </summary>
/// <param name="data">Data.</param>
/// <param name="offset">Offset.</param>
/// <param name="size">Size.</param>
public void SendData(byte[] data, int offset, int size)
{
_channel.SendData(data, offset, size);
}

/// <summary>
/// Sends the data to channel.
/// </summary>
/// <param name="data">Data.</param>
public void SendData(Stream data)
{
if (data == null)
return;

byte[] buffer = new byte[2048]; // read in chunks of 2KB
int bytesRead;

while ((bytesRead = data.Read(buffer, 0, buffer.Length)) > 0)
{
_channel.SendData(buffer, 0, bytesRead);
}
}

#region IDisposable Members

private bool _isDisposed;
Expand Down

0 comments on commit 7945a95

Please sign in to comment.