@@ -26,6 +26,7 @@ public class SshCommand : IDisposable
26
26
private CommandAsyncResult _asyncResult ;
27
27
private AsyncCallback _callback ;
28
28
private EventWaitHandle _sessionErrorOccuredWaitHandle ;
29
+ private EventWaitHandle _commandCancelledWaitHandle ;
29
30
private Exception _exception ;
30
31
private StringBuilder _result ;
31
32
private StringBuilder _error ;
@@ -186,7 +187,7 @@ internal SshCommand(ISession session, string commandText, Encoding encoding)
186
187
_encoding = encoding ;
187
188
CommandTimeout = Session . InfiniteTimeSpan ;
188
189
_sessionErrorOccuredWaitHandle = new AutoResetEvent ( initialState : false ) ;
189
-
190
+ _commandCancelledWaitHandle = new AutoResetEvent ( initialState : false ) ;
190
191
_session . Disconnected += Session_Disconnected ;
191
192
_session . ErrorOccured += Session_ErrorOccured ;
192
193
}
@@ -356,13 +357,12 @@ public string EndExecute(IAsyncResult asyncResult)
356
357
/// <summary>
357
358
/// Cancels command execution in asynchronous scenarios.
358
359
/// </summary>
359
- public void CancelAsync ( )
360
+ /// <param name="forceKill">if true send SIGKILL instead of SIGTERM.</param>
361
+ public void CancelAsync ( bool forceKill = false )
360
362
{
361
- if ( _channel is not null && _channel . IsOpen && _asyncResult is not null )
362
- {
363
- // TODO: check with Oleg if we shouldn't dispose the channel and uninitialize it ?
364
- _channel . Dispose ( ) ;
365
- }
363
+ var signal = forceKill ? "KILL" : "TERM" ;
364
+ _ = _channel ? . SendExitSignalRequest ( signal , coreDumped : false , "Command execution has been cancelled." , "en" ) ;
365
+ _ = _commandCancelledWaitHandle . Set ( ) ;
366
366
}
367
367
368
368
/// <summary>
@@ -506,6 +506,7 @@ private void WaitOnHandle(WaitHandle waitHandle)
506
506
var waitHandles = new [ ]
507
507
{
508
508
_sessionErrorOccuredWaitHandle ,
509
+ _commandCancelledWaitHandle ,
509
510
waitHandle
510
511
} ;
511
512
@@ -515,7 +516,8 @@ private void WaitOnHandle(WaitHandle waitHandle)
515
516
case 0 :
516
517
ExceptionDispatchInfo . Capture ( _exception ) . Throw ( ) ;
517
518
break ;
518
- case 1 :
519
+ case 1 : // Command cancelled
520
+ case 2 :
519
521
// Specified waithandle was signaled
520
522
break ;
521
523
case WaitHandle . WaitTimeout :
@@ -620,6 +622,9 @@ protected virtual void Dispose(bool disposing)
620
622
_sessionErrorOccuredWaitHandle = null ;
621
623
}
622
624
625
+ _commandCancelledWaitHandle ? . Dispose ( ) ;
626
+ _commandCancelledWaitHandle = null ;
627
+
623
628
_isDisposed = true ;
624
629
}
625
630
}
0 commit comments