Beispiel #1
0
        private static SafeFileHandle?DuplicateStdFileForChild(int stdFd, bool createNewConsole)
        {
            if (!LibChildProcess.DuplicateStdFileForChild(stdFd, createNewConsole, out var newFd))
            {
                // Probably EBADF.
                return(null);
            }

            return(newFd.IsInvalid ? null : newFd);
        }
Beispiel #2
0
        private unsafe void RecvExactBytes(void *pBuf, uint length)
        {
            CheckNotDisposed();

            if (!LibChildProcess.SubchannelRecvExactBytes(_handle, pBuf, length))
            {
                var err = Marshal.GetLastWin32Error();
                ThrowFatalCommnicationError(err);
            }
        }
Beispiel #3
0
        public SafeFileHandle OpenNullDevice(FileAccess fileAccess)
        {
            var fd = LibChildProcess.OpenNullDevice(ToLibChildProcessFileAccess(fileAccess));

            if (fd.IsInvalid)
            {
                throw new Win32Exception();
            }

            return(fd);
        }
Beispiel #4
0
        private UnixSubchannel CreateSubchannel()
        {
            var mainChannelhandle = _mainChannelSocket.SafeHandle;
            var subchannelHandle  = LibChildProcess.SubchannelCreate(mainChannelhandle.DangerousGetHandle());

            if (subchannelHandle.IsInvalid)
            {
                throw new Win32Exception();
            }

            return(new UnixSubchannel(subchannelHandle));
        }
Beispiel #5
0
        private static string MakeSocketPathPrefix()
        {
            var       candidate     = NamedPipeUtil.MakePipePathPrefix(Path.GetTempPath(), (uint)LibChildProcess.GetPid());
            const int maxBodyLength = 11;

            if ((ulong)(candidate.Length + maxBodyLength) > LibChildProcess.GetMaxSocketPathLength().ToUInt64())
            {
                throw new PathTooLongException("Path to the temporary directory is too long to accomodate a socket file.");
            }

            return(candidate);
        }
Beispiel #6
0
 public unsafe void SendExactBytes(ReadOnlySpan <byte> buffer)
 {
     fixed(byte *pBuffer = buffer)
     {
         if (!LibChildProcess.SubchannelSendExactBytes(
                 _handle, pBuffer, new UIntPtr((uint)buffer.Length)))
         {
             var err = Marshal.GetLastWin32Error();
             ThrowFatalCommnicationError(err);
         }
     }
 }
Beispiel #7
0
        public unsafe (int error, int pid) ReadResponse()
        {
            const int ResponseInts = 2;

            fixed(int *pBuf = stackalloc int[ResponseInts])
            {
                if (!LibChildProcess.SubchannelRecvExactBytes(_handle, pBuf, new UIntPtr(ResponseInts * sizeof(int))))
                {
                    var err = Marshal.GetLastWin32Error();
                    ThrowFatalCommnicationError(err);
                }

                return(pBuf[0], pBuf[1]);
            }
        }
Beispiel #8
0
        public unsafe void SendExactBytesAndFds(ReadOnlySpan <byte> buffer, ReadOnlySpan <int> fds)
        {
            CheckNotDisposed();

            fixed(byte *pBuffer = buffer)
            {
                fixed(int *pFds = fds)
                {
                    if (!LibChildProcess.SubchannelSendExactBytesAndFds(
                            _handle, pBuffer, (uint)buffer.Length, pFds, (uint)fds.Length))
                    {
                        var err = Marshal.GetLastWin32Error();
                        ThrowFatalCommnicationError(err);
                    }
                }
            }
        }
        public unsafe (int error, int pid) ReadResponse()
        {
            const int ResponseInts = 2;

            fixed(int *pBuf = stackalloc int[ResponseInts])
            {
                if (!LibChildProcess.SubchannelRecvExactBytes(_handle, pBuf, new UIntPtr(ResponseInts * sizeof(int))))
                {
                    var err = Marshal.GetLastWin32Error();
                    if (err == 0)
                    {
                        // TODO: handle helper crash or internal communication error
                        throw new AsmichiChildProcessLibraryCrashedException("Process cannot be created: Connection reset.");
                    }
                    else
                    {
                        throw new Win32Exception(err);
                    }
                }

                return(pBuf[0], pBuf[1]);
            }
        }
 public unsafe void SendExactBytesAndFds(ReadOnlySpan <byte> buffer, ReadOnlySpan <int> fds)
 {
     fixed(byte *pBuffer = buffer)
     {
         fixed(int *pFds = fds)
         {
             if (!LibChildProcess.SubchannelSendExactBytesAndFds(
                     _handle, pBuffer, new UIntPtr((uint)buffer.Length), pFds, new UIntPtr((uint)fds.Length)))
             {
                 var err = Marshal.GetLastWin32Error();
                 if (err == 0)
                 {
                     // TODO: handle helper crash or internal communication error
                     throw new AsmichiChildProcessLibraryCrashedException("Process cannot be created: Connection reset.");
                 }
                 else
                 {
                     throw new Win32Exception(err);
                 }
             }
         }
     }
 }
Beispiel #11
0
        public (Stream serverStream, SafeFileHandle clientPipe) CreatePipePairWithAsyncServerSide(PipeDirection pipeDirection)
        {
            var pipePath = CreateUniqueSocketPath();

            try
            {
                using var listeningSock = CreateListeningDomainSocket(pipePath, 1);

                // We do not want a Socket to manage and close this fd; connect on our own.
                if (!LibChildProcess.ConnectToUnixSocket(pipePath, out var clientSock))
                {
                    throw new Win32Exception();
                }
                Debug.Assert(listeningSock.Poll(0, SelectMode.SelectRead));

                var serverSock   = listeningSock.Accept();
                var serverStream = new NetworkStream(serverSock, ownsSocket: true);
                return(serverStream, clientSock);
            }
            finally
            {
                File.Delete(pipePath);
            }
        }