/// <summary>Creates an anonymous pipe.</summary> /// <param name="inheritability">The inheritability to try to use. This may not always be honored, depending on platform.</param> /// <param name="reader">The resulting reader end of the pipe.</param> /// <param name="writer">The resulting writer end of the pipe.</param> internal static unsafe void CreateAnonymousPipe( HandleInheritability inheritability, out SafePipeHandle reader, out SafePipeHandle writer) { // Allocate the safe handle objects prior to calling pipe/pipe2, in order to help slightly in low-mem situations reader = new SafePipeHandle(); writer = new SafePipeHandle(); // Create the OS pipe int *fds = stackalloc int[2]; CreateAnonymousPipe(inheritability, fds); // Store the file descriptors into our safe handles reader.SetHandle(fds[Interop.Sys.ReadEndOfPipe]); writer.SetHandle(fds[Interop.Sys.WriteEndOfPipe]); }
/// <summary>Creates an anonymous pipe.</summary> /// <param name="reader">The resulting reader end of the pipe.</param> /// <param name="writer">The resulting writer end of the pipe.</param> internal static unsafe void CreateAnonymousPipe(out SafePipeHandle reader, out SafePipeHandle writer) { // Allocate the safe handle objects prior to calling pipe/pipe2, in order to help slightly in low-mem situations reader = new SafePipeHandle(); writer = new SafePipeHandle(); // Create the OS pipe. We always create it as O_CLOEXEC (trying to do so atomically) so that the // file descriptors aren't inherited. Then if inheritability was requested, we opt-in the child file // descriptor later; if the server file descriptor was also inherited, closing the server file // descriptor would fail to signal EOF for the child side. int *fds = stackalloc int[2]; Interop.CheckIo(Interop.Sys.Pipe(fds, Interop.Sys.PipeFlags.O_CLOEXEC)); // Store the file descriptors into our safe handles reader.SetHandle(fds[Interop.Sys.ReadEndOfPipe]); writer.SetHandle(fds[Interop.Sys.WriteEndOfPipe]); }