File: System\IO\Pipes\AnonymousPipeServerStream.Unix.cs
Web Access
Project: src\src\libraries\System.IO.Pipes\src\System.IO.Pipes.csproj (System.IO.Pipes)
// 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;
using Microsoft.Win32.SafeHandles;
 
namespace System.IO.Pipes
{
    /// <summary>
    /// Anonymous pipe server stream
    /// </summary>
    public sealed partial class AnonymousPipeServerStream : PipeStream
    {
        // Creates the anonymous pipe.
        private void Create(PipeDirection direction, HandleInheritability inheritability, int bufferSize)
        {
            Debug.Assert(direction != PipeDirection.InOut, "Anonymous pipe direction shouldn't be InOut");
            // Ignore bufferSize.  It's optional, and the fcntl F_SETPIPE_SZ for changing it is Linux specific.
 
            SafePipeHandle? serverHandle = null, clientHandle = null;
            try
            {
                if (direction == PipeDirection.In)
                {
                    CreateAnonymousPipe(reader: out serverHandle, writer: out clientHandle);
                }
                else
                {
                    CreateAnonymousPipe(reader: out clientHandle, writer: out serverHandle);
                }
            }
            catch
            {
                serverHandle?.Dispose();
                clientHandle?.Dispose();
                throw;
            }
 
            // We always create pipes with both file descriptors being O_CLOEXEC.
            // If inheritability is requested, we clear the O_CLOEXEC flag
            // from the child descriptor so that it can be passed to a child process.
            // We assume that the HandleInheritability only applies to the child fd,
            // as if we allowed the server fd to be inherited, then when this process
            // closes its end of the pipe, the client won't receive an EOF or broken
            // pipe notification, as the child will still have open its dup of the fd.
            if (inheritability == HandleInheritability.Inheritable &&
                Interop.Sys.Fcntl.SetFD(clientHandle, 0) == -1)
            {
                serverHandle.Dispose();
                clientHandle.Dispose();
                throw Interop.GetExceptionForIoErrno(Interop.Sys.GetLastErrorInfo());
            }
 
            // Configure the pipe.  For buffer size, the size applies to the pipe, rather than to
            // just one end's file descriptor, so we only need to do this with one of the handles.
            // bufferSize is just advisory and ignored if platform does not support setting pipe capacity via fcntl.
            if (bufferSize > 0 && Interop.Sys.Fcntl.CanGetSetPipeSz)
            {
                Interop.Sys.Fcntl.SetPipeSz(serverHandle, bufferSize); // advisory, ignore errors
            }
 
            // We're connected.  Finish initialization using the newly created handles.
            InitializeHandle(serverHandle, isExposed: false, isAsync: false);
            _clientHandle = clientHandle;
            State = PipeState.Connected;
        }
    }
}