public void WaitForConnection() { CheckConnectOperationsServer(); if (State == PipeState.Connected) { throw new InvalidOperationException(SR.InvalidOperation_PipeAlreadyConnected); } // Binding to an existing path fails, so we need to remove anything left over at this location. // There's of course a race condition here, where it could be recreated by someone else between this // deletion and the bind below, in which case we'll simply let the bind fail and throw. Interop.Sys.Unlink(_path); // ignore any failures var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified); try { socket.Bind(new UnixDomainSocketEndPoint(_path)); socket.Listen(1); Socket acceptedSocket = socket.Accept(); SafePipeHandle serverHandle = new SafePipeHandle(acceptedSocket); try { ConfigureSocket(acceptedSocket, serverHandle, _direction, _inBufferSize, _outBufferSize, _inheritability); } catch { serverHandle.Dispose(); acceptedSocket.Dispose(); throw; } InitializeHandle(serverHandle, isExposed: false, isAsync: (_options & PipeOptions.Asynchronous) != 0); State = PipeState.Connected; } finally { // Bind will have created a file. Now that the client is connected, it's no longer necessary, so get rid of it. Interop.Sys.Unlink(_path); // ignore any failures; worst case is we leave a tmp file // Clean up the listening socket socket.Dispose(); } }
private bool TryConnect(int timeout, CancellationToken cancellationToken) { // timeout and cancellationToken aren't used as Connect will be very fast, // either succeeding immediately if the server is listening or failing // immediately if it isn't. The only delay will be between the time the server // has called Bind and Listen, with the latter immediately following the former. var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified); SafePipeHandle clientHandle = null; try { socket.Connect(new UnixDomainSocketEndPoint(_normalizedPipePath)); clientHandle = new SafePipeHandle(socket); ConfigureSocket(socket, clientHandle, _direction, 0, 0, _inheritability); } catch (SocketException e) { if (clientHandle != null) { clientHandle.Dispose(); } socket.Dispose(); switch (e.SocketErrorCode) { // Retryable errors case SocketError.AddressAlreadyInUse: case SocketError.AddressNotAvailable: case SocketError.ConnectionRefused: return false; // Non-retryable errors default: throw; } } InitializeHandle(clientHandle, isExposed: false, isAsync: (_pipeOptions & PipeOptions.Asynchronous) != 0); State = PipeState.Connected; return true; }