Skip to content

Commit e739a4f

Browse files
authored
Merge branch 'develop' into shellstream-writeasync
2 parents 9e779d5 + cb1f26d commit e739a4f

File tree

62 files changed

+1546
-6056
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1546
-6056
lines changed

src/Renci.SshNet/Common/Extensions.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Globalization;
44
#if !NET
55
using System.IO;
6+
using System.Threading.Tasks;
67
#endif
78
using System.Net;
89
using System.Net.Sockets;
@@ -398,6 +399,29 @@ internal static void ReadExactly(this Stream stream, byte[] buffer, int offset,
398399
totalRead += read;
399400
}
400401
}
402+
403+
internal static Task<T> WaitAsync<T>(this Task<T> task, CancellationToken cancellationToken)
404+
{
405+
if (task.IsCompleted || !cancellationToken.CanBeCanceled)
406+
{
407+
return task;
408+
}
409+
410+
return WaitCore();
411+
412+
async Task<T> WaitCore()
413+
{
414+
TaskCompletionSource<T> tcs = new(TaskCreationOptions.RunContinuationsAsynchronously);
415+
416+
using var reg = cancellationToken.Register(
417+
() => tcs.TrySetCanceled(cancellationToken),
418+
useSynchronizationContext: false);
419+
420+
var completedTask = await Task.WhenAny(task, tcs.Task).ConfigureAwait(false);
421+
422+
return await completedTask.ConfigureAwait(false);
423+
}
424+
}
401425
#endif
402426
}
403427
}
Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
using System;
2-
#if NETFRAMEWORK
3-
using System.Runtime.Serialization;
4-
#endif // NETFRAMEWORK
1+
#nullable enable
2+
using System;
53

64
namespace Renci.SshNet.Common
75
{
@@ -10,7 +8,7 @@ namespace Renci.SshNet.Common
108
/// </summary>
119
#if NETFRAMEWORK
1210
[Serializable]
13-
#endif // NETFRAMEWORK
11+
#endif
1412
public class NetConfServerException : SshException
1513
{
1614
/// <summary>
@@ -23,34 +21,27 @@ public NetConfServerException()
2321
/// <summary>
2422
/// Initializes a new instance of the <see cref="NetConfServerException"/> class.
2523
/// </summary>
26-
/// <param name="message">The message.</param>
27-
public NetConfServerException(string message)
24+
/// <inheritdoc cref="Exception(string)" path="/param"/>
25+
public NetConfServerException(string? message)
2826
: base(message)
2927
{
3028
}
3129

3230
/// <summary>
3331
/// Initializes a new instance of the <see cref="NetConfServerException"/> class.
3432
/// </summary>
35-
/// <param name="message">The message.</param>
36-
/// <param name="innerException">The inner exception.</param>
37-
public NetConfServerException(string message, Exception innerException)
33+
/// <inheritdoc cref="Exception(string, Exception)" path="/param"/>
34+
public NetConfServerException(string? message, Exception? innerException)
3835
: base(message, innerException)
3936
{
4037
}
4138

4239
#if NETFRAMEWORK
43-
/// <summary>
44-
/// Initializes a new instance of the <see cref="NetConfServerException"/> class.
45-
/// </summary>
46-
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
47-
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual information about the source or destination.</param>
48-
/// <exception cref="ArgumentNullException">The <paramref name="info"/> parameter is <see langword="null"/>.</exception>
49-
/// <exception cref="SerializationException">The class name is <see langword="null"/> or <see cref="Exception.HResult"/> is zero (0). </exception>
50-
protected NetConfServerException(SerializationInfo info, StreamingContext context)
40+
/// <inheritdoc/>
41+
protected NetConfServerException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
5142
: base(info, context)
5243
{
5344
}
54-
#endif // NETFRAMEWORK
45+
#endif
5546
}
5647
}
Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
using System;
2-
#if NETFRAMEWORK
3-
using System.Runtime.Serialization;
4-
#endif // NETFRAMEWORK
1+
#nullable enable
2+
using System;
53

64
namespace Renci.SshNet.Common
75
{
@@ -10,7 +8,7 @@ namespace Renci.SshNet.Common
108
/// </summary>
119
#if NETFRAMEWORK
1210
[Serializable]
13-
#endif // NETFRAMEWORK
11+
#endif
1412
public class ProxyException : SshException
1513
{
1614
/// <summary>
@@ -23,34 +21,27 @@ public ProxyException()
2321
/// <summary>
2422
/// Initializes a new instance of the <see cref="ProxyException"/> class.
2523
/// </summary>
26-
/// <param name="message">The message.</param>
27-
public ProxyException(string message)
24+
/// <inheritdoc cref="Exception(string)" path="/param"/>
25+
public ProxyException(string? message)
2826
: base(message)
2927
{
3028
}
3129

3230
/// <summary>
3331
/// Initializes a new instance of the <see cref="ProxyException"/> class.
3432
/// </summary>
35-
/// <param name="message">The message.</param>
36-
/// <param name="innerException">The inner exception.</param>
37-
public ProxyException(string message, Exception innerException)
33+
/// <inheritdoc cref="Exception(string, Exception)" path="/param"/>
34+
public ProxyException(string? message, Exception? innerException)
3835
: base(message, innerException)
3936
{
4037
}
4138

4239
#if NETFRAMEWORK
43-
/// <summary>
44-
/// Initializes a new instance of the <see cref="ProxyException"/> class.
45-
/// </summary>
46-
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
47-
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual information about the source or destination.</param>
48-
/// <exception cref="ArgumentNullException">The <paramref name="info"/> parameter is <see langword="null"/>.</exception>
49-
/// <exception cref="SerializationException">The class name is <see langword="null"/> or <see cref="Exception.HResult"/> is zero (0).</exception>
50-
protected ProxyException(SerializationInfo info, StreamingContext context)
40+
/// <inheritdoc/>
41+
protected ProxyException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
5142
: base(info, context)
5243
{
5344
}
54-
#endif // NETFRAMEWORK
45+
#endif
5546
}
5647
}
Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
1-
using System;
2-
#if NETFRAMEWORK
3-
using System.Runtime.Serialization;
4-
#endif // NETFRAMEWORK
1+
#nullable enable
2+
using System;
53

64
namespace Renci.SshNet.Common
75
{
86
/// <summary>
9-
/// The exception that is thrown when SCP error occurred.
7+
/// The exception that is thrown when an SCP error occurs.
108
/// </summary>
119
#if NETFRAMEWORK
1210
[Serializable]
13-
#endif // NETFRAMEWORK
11+
#endif
1412
public class ScpException : SshException
1513
{
1614
/// <summary>
@@ -23,34 +21,27 @@ public ScpException()
2321
/// <summary>
2422
/// Initializes a new instance of the <see cref="ScpException"/> class.
2523
/// </summary>
26-
/// <param name="message">The message.</param>
27-
public ScpException(string message)
24+
/// <inheritdoc cref="Exception(string)" path="/param"/>
25+
public ScpException(string? message)
2826
: base(message)
2927
{
3028
}
3129

3230
/// <summary>
3331
/// Initializes a new instance of the <see cref="ScpException"/> class.
3432
/// </summary>
35-
/// <param name="message">The message.</param>
36-
/// <param name="innerException">The inner exception.</param>
37-
public ScpException(string message, Exception innerException)
33+
/// <inheritdoc cref="Exception(string, Exception)" path="/param"/>
34+
public ScpException(string? message, Exception? innerException)
3835
: base(message, innerException)
3936
{
4037
}
4138

4239
#if NETFRAMEWORK
43-
/// <summary>
44-
/// Initializes a new instance of the <see cref="ScpException"/> class.
45-
/// </summary>
46-
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
47-
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual information about the source or destination.</param>
48-
/// <exception cref="ArgumentNullException">The <paramref name="info"/> parameter is <see langword="null"/>.</exception>
49-
/// <exception cref="SerializationException">The class name is <see langword="null"/> or <see cref="Exception.HResult"/> is zero (0). </exception>
50-
protected ScpException(SerializationInfo info, StreamingContext context)
40+
/// <inheritdoc/>
41+
protected ScpException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
5142
: base(info, context)
5243
{
5344
}
54-
#endif // NETFRAMEWORK
45+
#endif
5546
}
5647
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#nullable enable
2+
using System;
3+
4+
using Renci.SshNet.Sftp;
5+
6+
namespace Renci.SshNet.Common
7+
{
8+
/// <summary>
9+
/// The exception that is thrown when an error occurs in the SFTP layer.
10+
/// </summary>
11+
#if NETFRAMEWORK
12+
[Serializable]
13+
#endif
14+
public class SftpException : SshException
15+
{
16+
/// <summary>
17+
/// Gets the status code that is associated with this exception.
18+
/// </summary>
19+
public StatusCode StatusCode { get; }
20+
21+
/// <summary>
22+
/// Initializes a new instance of the <see cref="SftpException"/> class.
23+
/// </summary>
24+
/// <param name="statusCode">The status code that indicates the error that occurred.</param>
25+
public SftpException(StatusCode statusCode)
26+
: this(statusCode, message: null, innerException: null)
27+
{
28+
}
29+
30+
/// <summary>
31+
/// Initializes a new instance of the <see cref="SftpException"/> class.
32+
/// </summary>
33+
/// <param name="statusCode">The status code that indicates the error that occurred.</param>
34+
/// <param name="message">The error message that explains the reason for the exception.</param>
35+
public SftpException(StatusCode statusCode, string? message)
36+
: this(statusCode, message, innerException: null)
37+
{
38+
}
39+
40+
/// <summary>
41+
/// Initializes a new instance of the <see cref="SftpException"/> class.
42+
/// </summary>
43+
/// <param name="statusCode">The status code that indicates the error that occurred.</param>
44+
/// <param name="message">The error message that explains the reason for the exception.</param>
45+
/// <param name="innerException">The exception that is the cause of the current exception.</param>
46+
public SftpException(StatusCode statusCode, string? message, Exception? innerException)
47+
: base(string.IsNullOrEmpty(message) ? GetDefaultMessage(statusCode) : message, innerException)
48+
{
49+
StatusCode = statusCode;
50+
}
51+
52+
private protected static string GetDefaultMessage(StatusCode statusCode)
53+
{
54+
#pragma warning disable IDE0072 // Add missing cases
55+
return statusCode switch
56+
{
57+
StatusCode.Ok => "The operation completed successfully.",
58+
StatusCode.NoSuchFile => "A reference was made to a file that does not exist.",
59+
StatusCode.PermissionDenied => "The user does not have sufficient permissions to perform the operation.",
60+
StatusCode.Failure => "An error occurred, but no specific error code exists to describe the failure.",
61+
StatusCode.BadMessage => "A badly formatted packet or SFTP protocol incompatibility was detected.",
62+
StatusCode.OperationUnsupported => "An attempt was made to perform an operation which is not supported.",
63+
_ => statusCode.ToString()
64+
};
65+
#pragma warning restore IDE0072 // Add missing cases
66+
}
67+
68+
#if NETFRAMEWORK
69+
/// <inheritdoc/>
70+
protected SftpException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
71+
: base(info, context)
72+
{
73+
}
74+
#endif
75+
}
76+
}

0 commit comments

Comments
 (0)