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); }
private unsafe void RecvExactBytes(void *pBuf, uint length) { CheckNotDisposed(); if (!LibChildProcess.SubchannelRecvExactBytes(_handle, pBuf, length)) { var err = Marshal.GetLastWin32Error(); ThrowFatalCommnicationError(err); } }
public SafeFileHandle OpenNullDevice(FileAccess fileAccess) { var fd = LibChildProcess.OpenNullDevice(ToLibChildProcessFileAccess(fileAccess)); if (fd.IsInvalid) { throw new Win32Exception(); } return(fd); }
private UnixSubchannel CreateSubchannel() { var mainChannelhandle = _mainChannelSocket.SafeHandle; var subchannelHandle = LibChildProcess.SubchannelCreate(mainChannelhandle.DangerousGetHandle()); if (subchannelHandle.IsInvalid) { throw new Win32Exception(); } return(new UnixSubchannel(subchannelHandle)); }
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); }
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); } } }
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]); } }
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); } } } } }
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); } }