diff --git a/Renci.SshClient/Renci.SshClient/Channels/Channel.cs b/Renci.SshClient/Renci.SshClient/Channels/Channel.cs
index bdc3f0de..a9c2a62c 100644
--- a/Renci.SshClient/Renci.SshClient/Channels/Channel.cs
+++ b/Renci.SshClient/Renci.SshClient/Channels/Channel.cs
@@ -1,5 +1,6 @@
using System;
using System.Threading;
+using Renci.SshClient.Common;
using Renci.SshClient.Messages;
using Renci.SshClient.Messages.Connection;
@@ -231,7 +232,12 @@ namespace Renci.SshClient.Channels
ChannelNumber = message.ChannelNumber,
};
- // TODO: if exitStatus is not 0 then throw an exception or notify user that command failed to execute correctly
+ // Throw an error if exit status is not 0
+ if (exitStatus > 0)
+ {
+ throw new SshException(string.Format("Operation failed. Exit status: {0}", exitStatus), false);
+ }
+
}
else
{
diff --git a/Renci.SshClient/Renci.SshClient/Channels/ChannelExec.cs b/Renci.SshClient/Renci.SshClient/Channels/ChannelExec.cs
index d6ead13d..dbd7700b 100644
--- a/Renci.SshClient/Renci.SshClient/Channels/ChannelExec.cs
+++ b/Renci.SshClient/Renci.SshClient/Channels/ChannelExec.cs
@@ -5,8 +5,6 @@ using Renci.SshClient.Messages.Connection;
namespace Renci.SshClient.Channels
{
- // TODO: Add Begin* and End* methods for async calls
-
internal class ChannelExec : Channel
{
private Stream _channelData;
diff --git a/Renci.SshClient/Renci.SshClient/Channels/ChannelSftp.cs b/Renci.SshClient/Renci.SshClient/Channels/ChannelSftp.cs
index 54ee2b0e..25960ec2 100644
--- a/Renci.SshClient/Renci.SshClient/Channels/ChannelSftp.cs
+++ b/Renci.SshClient/Renci.SshClient/Channels/ChannelSftp.cs
@@ -10,6 +10,8 @@ using Renci.SshClient.Messages.Sftp;
namespace Renci.SshClient.Channels
{
+ // TODO: Add Begin* and End* methods for async calls
+
internal class ChannelSftp : Channel
{
private EventWaitHandle _channelRequestSuccessWaitHandle = new AutoResetEvent(false);
diff --git a/Renci.SshClient/Renci.SshClient/Common/SshException.cs b/Renci.SshClient/Renci.SshClient/Common/SshException.cs
new file mode 100644
index 00000000..f888e24a
--- /dev/null
+++ b/Renci.SshClient/Renci.SshClient/Common/SshException.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Runtime.Serialization;
+
+namespace Renci.SshClient.Common
+{
+ public class SshException : Exception
+ {
+ public bool ShouldDisconnect { get; private set; }
+
+ public SshException()
+ {
+ this.ShouldDisconnect = true;
+ }
+
+ public SshException(string message)
+ : base(message)
+ {
+ this.ShouldDisconnect = true;
+ }
+
+ public SshException(string message, Exception inner)
+ : base(message, inner)
+ {
+ this.ShouldDisconnect = true;
+ }
+
+ public SshException(string message, bool shouldDisconnect)
+ : base(message)
+ {
+ this.ShouldDisconnect = shouldDisconnect;
+ }
+
+ public SshException(string message, bool shouldDisconnect, Exception inner)
+ : base(message, inner)
+ {
+ this.ShouldDisconnect = shouldDisconnect;
+ }
+
+ // This constructor is needed for serialization.
+ protected SshException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ // Add implementation.
+ }
+
+ }
+}
diff --git a/Renci.SshClient/Renci.SshClient/Renci.SshClient.csproj b/Renci.SshClient/Renci.SshClient/Renci.SshClient.csproj
index 1bb4cc31..dc9c735a 100644
--- a/Renci.SshClient/Renci.SshClient/Renci.SshClient.csproj
+++ b/Renci.SshClient/Renci.SshClient/Renci.SshClient.csproj
@@ -63,6 +63,7 @@
+
diff --git a/Renci.SshClient/Renci.SshClient/Session.cs b/Renci.SshClient/Renci.SshClient/Session.cs
index ca12ff61..fae528bf 100644
--- a/Renci.SshClient/Renci.SshClient/Session.cs
+++ b/Renci.SshClient/Renci.SshClient/Session.cs
@@ -914,9 +914,9 @@ namespace Renci.SshClient
///
private void MessageListener()
{
- try
+ while (this._socket.Connected)
{
- while (this._socket.Connected)
+ try
{
dynamic message = this.ReceiveMessage();
@@ -931,30 +931,43 @@ namespace Renci.SshClient
// Raise an event that message received
this.RaiseMessageReceived(this, new MessageReceivedEventArgs(message));
}
- }
- catch (Exception exp)
- {
- // TODO: This exception can be swolloed if it occures while running in the background, look for possible solutions
-
- // Ignore this error since socket was disconected
- if (exp is SocketException && ((SocketException)exp).SocketErrorCode == SocketError.ConnectionAborted && this._isDisconnecting)
+ catch (SshException exp)
{
- // Do nothing since connection was disconnected by the client
- }
- else
- {
- // In case of error issue disconntect command
- this.Disconnect(DisconnectReasonCodes.ByApplication, exp.ToString());
+ if (exp.ShouldDisconnect)
+ {
+ // In case of error issue disconntect command
+ this.Disconnect(DisconnectReasonCodes.ByApplication, exp.ToString());
+ }
this._exceptionToThrow = exp;
this._exceptionWaitHandle.Set();
}
+ catch (Exception exp)
+ {
+ // TODO: This exception can be swolloed if it occures while running in the background, look for possible solutions
- // Ensure socket is disconnected
- this._socket.Close();
+ // Ignore this error since socket was disconected
+ if (exp is SocketException && ((SocketException)exp).SocketErrorCode == SocketError.ConnectionAborted && this._isDisconnecting)
+ {
+ // Do nothing since connection was disconnected by the client
+ }
+ else
+ {
+ // In case of error issue disconntect command
+ this.Disconnect(DisconnectReasonCodes.ByApplication, exp.ToString());
+
+ this._exceptionToThrow = exp;
+
+ this._exceptionWaitHandle.Set();
+ }
+
+ // Ensure socket is disconnected
+ this._socket.Close();
+ }
}
+
this._listenerWaitHandle.Set();
}