Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PipeOptions.FirstPipeInstance enum value #83936

Merged
2 changes: 2 additions & 0 deletions src/libraries/System.IO.Pipes/ref/System.IO.Pipes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ public enum PipeOptions
None = 0,
CurrentUserOnly = 536870912,
Asynchronous = 1073741824,
[System.Runtime.Versioning.SupportedOSPlatformAttribute("windows")]
FirstPipeInstance = 524288
stephentoub marked this conversation as resolved.
Show resolved Hide resolved
}
public abstract partial class PipeStream : System.IO.Stream
{
Expand Down
3 changes: 3 additions & 0 deletions src/libraries/System.IO.Pipes/src/Resources/Strings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,9 @@
<data name="PlatformNotSupported_MessageTransmissionMode" xml:space="preserve">
<value>Message transmission mode is not supported on this platform.</value>
</data>
<data name="PlatformNotSupported_PipeOptions_FirstPipeInstance" xml:space="preserve">
<value>First Pipe Instance option is not supported on this platform.</value>
</data>
adamsitnik marked this conversation as resolved.
Show resolved Hide resolved
<data name="PlatformNotSupported_RemotePipes" xml:space="preserve">
<value>Access to remote named pipes is not supported on this platform.</value>
</data>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ private void Create(string pipeName, PipeDirection direction, int maxNumberOfSer
throw new PlatformNotSupportedException(SR.PlatformNotSupported_MessageTransmissionMode);
}

#pragma warning disable CA1416
if ((options & PipeOptions.FirstPipeInstance) != 0)
#pragma warning restore CA1416
{
throw new PlatformNotSupportedException(SR.PlatformNotSupported_PipeOptions_FirstPipeInstance);
}

// We don't have a good way to enforce maxNumberOfServerInstances across processes; we only factor it in
// for streams created in this process. Between processes, we behave similarly to maxNumberOfServerInstances == 1,
// in that the second process to come along and create a stream will find the pipe already in existence and will fail.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Win32.SafeHandles;
Expand Down Expand Up @@ -60,10 +59,10 @@ public NamedPipeServerStream(string pipeName, PipeDirection direction, int maxNu
/// Win32 note: this gets used for dwPipeMode. CreateNamedPipe allows you to specify PIPE_TYPE_BYTE/MESSAGE
/// and PIPE_READMODE_BYTE/MESSAGE independently, but this sets type and readmode to match.
/// </param>
/// <param name="options">PipeOption enum: None, Asynchronous, or Write-through
/// <param name="options">PipeOption enum: None, Asynchronous, Write-through, or FirstPipeInstance
/// Win32 note: this gets passed in with dwOpenMode to CreateNamedPipe. Asynchronous corresponds to
/// FILE_FLAG_OVERLAPPED option. PipeOptions enum doesn't expose FIRST_PIPE_INSTANCE option because
/// this sets that automatically based on the number of instances specified.
/// FILE_FLAG_OVERLAPPED option. PipeOptions.FIRST_PIPE_INSTANCE
adamsitnik marked this conversation as resolved.
Show resolved Hide resolved
/// is automatically set based on the number of instances specified.
adamsitnik marked this conversation as resolved.
Show resolved Hide resolved
Tarun047 marked this conversation as resolved.
Show resolved Hide resolved
/// </param>
/// <param name="inBufferSize">Incoming buffer size, 0 or higher.
/// Note: this size is always advisory; OS uses a suggestion.
Expand Down Expand Up @@ -103,7 +102,9 @@ private void ValidateParameters(
{
throw new ArgumentOutOfRangeException(nameof(transmissionMode), SR.ArgumentOutOfRange_TransmissionModeByteOrMsg);
}
if ((options & ~(PipeOptions.WriteThrough | PipeOptions.Asynchronous | PipeOptions.CurrentUserOnly)) != 0)
#pragma warning disable CA1416
if ((options & ~(PipeOptions.WriteThrough | PipeOptions.Asynchronous | PipeOptions.CurrentUserOnly | PipeOptions.FirstPipeInstance)) != 0)
#pragma warning restore CA1416
{
throw new ArgumentOutOfRangeException(nameof(options), SR.ArgumentOutOfRange_OptionsInvalid);
}
Expand Down Expand Up @@ -161,7 +162,7 @@ public Task WaitForConnectionAsync()
return WaitForConnectionAsync(CancellationToken.None);
}

public System.IAsyncResult BeginWaitForConnection(AsyncCallback? callback, object? state) =>
public IAsyncResult BeginWaitForConnection(AsyncCallback? callback, object? state) =>
TaskToAsyncResult.Begin(WaitForConnectionAsync(), callback, state);

public void EndWaitForConnection(IAsyncResult asyncResult) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.Versioning;

namespace System.IO.Pipes
{
[Flags]
Expand All @@ -9,6 +11,8 @@ public enum PipeOptions
None = 0x0,
WriteThrough = unchecked((int)0x80000000),
Asynchronous = unchecked((int)0x40000000), // corresponds to FILE_FLAG_OVERLAPPED
CurrentUserOnly = unchecked((int)0x20000000)
CurrentUserOnly = unchecked((int)0x20000000),
[SupportedOSPlatform("windows")]
adamsitnik marked this conversation as resolved.
Show resolved Hide resolved
FirstPipeInstance = unchecked((int)0x00080000)
stephentoub marked this conversation as resolved.
Show resolved Hide resolved
}
}
adamsitnik marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ public static void ReservedPipeName_Throws_ArgumentOutOfRangeException(PipeDirec
AssertExtensions.Throws<ArgumentOutOfRangeException>("pipeName", () => new NamedPipeServerStream(reservedName, direction, 1));
AssertExtensions.Throws<ArgumentOutOfRangeException>("pipeName", () => new NamedPipeServerStream(reservedName, direction, 1, PipeTransmissionMode.Byte));
AssertExtensions.Throws<ArgumentOutOfRangeException>("pipeName", () => new NamedPipeServerStream(reservedName, direction, 1, PipeTransmissionMode.Byte, PipeOptions.None));
AssertExtensions.Throws<ArgumentOutOfRangeException>("pipeName", () => new NamedPipeServerStream(reservedName, direction, 1, PipeTransmissionMode.Byte, PipeOptions.None, 0, 0));}
AssertExtensions.Throws<ArgumentOutOfRangeException>("pipeName", () => new NamedPipeServerStream(reservedName, direction, 1, PipeTransmissionMode.Byte, PipeOptions.None, 0, 0));
}

[Fact]
[SkipOnPlatform(TestPlatforms.LinuxBionic, "SElinux blocks UNIX sockets in our CI environment")]
Expand Down Expand Up @@ -254,5 +255,24 @@ public static void Windows_ServerCloneWithDifferentDirection_Throws_Unauthorized
Assert.Throws<UnauthorizedAccessException>(() => new NamedPipeServerStream(uniqueServerName, PipeDirection.Out));
}
}

[Fact]
[PlatformSpecific(TestPlatforms.AnyUnix)]
public static void Unix_PipeOptions_FirstPipeInstance_ThrowsPlatformNotSupportedException()
{
Assert.Throws<PlatformNotSupportedException>(() => new NamedPipeServerStream(PipeStreamConformanceTests.GetUniquePipeName(), PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.FirstPipeInstance));
}

[Fact]
[PlatformSpecific(TestPlatforms.Windows)]
public static void Windows_PipeOptions_FirstPipeInstanceWithSameNameReuse_Throws_UnauthorizedAccessException()
{
string uniqueServerName = PipeStreamConformanceTests.GetUniquePipeName();
using (NamedPipeServerStream server = new NamedPipeServerStream(uniqueServerName, PipeDirection.In, 2, PipeTransmissionMode.Byte, PipeOptions.FirstPipeInstance))
{
Assert.Throws<UnauthorizedAccessException>(() => new NamedPipeServerStream(uniqueServerName, PipeDirection.In, 2, PipeTransmissionMode.Byte, PipeOptions.FirstPipeInstance));
}
}

}
}