From: Gonzalo Paniagua Javier Date: Thu, 21 Apr 2005 20:00:20 +0000 (-0000) Subject: 2005-04-21 Gonzalo Paniagua Javier X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=cd75528364a5d9853e323c00bbbf5b6917e3c41c;p=mono.git 2005-04-21 Gonzalo Paniagua Javier * Mono.Posix.dll.sources: added UnixListener and UnixClient from Joe Shaw. * UnixClient.cs: * UnixListener.cs: TcpListener/TcpClient clones from Jow Shaw. svn path=/trunk/mcs/; revision=43416 --- diff --git a/mcs/class/Mono.Posix/Mono.Posix.dll.sources b/mcs/class/Mono.Posix/Mono.Posix.dll.sources index 490a6d14876..dad6be996d3 100644 --- a/mcs/class/Mono.Posix/Mono.Posix.dll.sources +++ b/mcs/class/Mono.Posix/Mono.Posix.dll.sources @@ -8,6 +8,7 @@ ./Mono.Unix/StdioFileStream.cs ./Mono.Unix/Stdlib.cs ./Mono.Unix/Syscall.cs +./Mono.Unix/UnixClient.cs ./Mono.Unix/UnixConvert.cs ./Mono.Unix/UnixDirectory.cs ./Mono.Unix/UnixDirectoryInfo.cs @@ -20,6 +21,7 @@ ./Mono.Unix/UnixGroup.cs ./Mono.Unix/UnixGroupInfo.cs ./Mono.Unix/UnixIOException.cs +./Mono.Unix/UnixListener.cs ./Mono.Unix/UnixMarshal.cs ./Mono.Unix/UnixPath.cs ./Mono.Unix/UnixProcess.cs diff --git a/mcs/class/Mono.Posix/Mono.Unix/ChangeLog b/mcs/class/Mono.Posix/Mono.Unix/ChangeLog index 35a89142fa2..481cce8820c 100644 --- a/mcs/class/Mono.Posix/Mono.Unix/ChangeLog +++ b/mcs/class/Mono.Posix/Mono.Unix/ChangeLog @@ -1,3 +1,13 @@ +2005-04-21 Gonzalo Paniagua Javier + + * UnixClient.cs: + * UnixListener.cs: TcpListener/TcpClient clones from Jow Shaw. + +2005-04-21 Gonzalo Paniagua Javier + + * Mono.Posix.dll.sources: added UnixListener and UnixClient from Joe + Shaw. + 2005-04-21 Gonzalo Paniagua Javier * UnixEndPoint.cs: fix from Mono.Posix. diff --git a/mcs/class/Mono.Posix/Mono.Unix/UnixClient.cs b/mcs/class/Mono.Posix/Mono.Unix/UnixClient.cs new file mode 100644 index 00000000000..29416cf9c5e --- /dev/null +++ b/mcs/class/Mono.Posix/Mono.Unix/UnixClient.cs @@ -0,0 +1,229 @@ +// +// UnixListener.cs +// +// Authors: +// Joe Shaw (joeshaw@novell.com) +// +// Copyright (C) 2004-2005 Novell, Inc. +// + +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + +using System; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Runtime.InteropServices; + +namespace Mono.Unix { + + public class UnixClient : IDisposable { + NetworkStream stream; + Socket client; + bool disposed; + + public UnixClient () + { + if (client != null) { + client.Close (); + client = null; + } + + client = new Socket (AddressFamily.Unix, SocketType.Stream, 0); + } + + public UnixClient (string path) : this () + { + if (path == null) + throw new ArgumentNullException ("ep"); + + Connect (path); + } + + public UnixClient (UnixEndPoint ep) : this () + { + if (ep == null) + throw new ArgumentNullException ("ep"); + + Connect (ep); + } + + // UnixListener uses this when accepting a connection. + internal UnixClient (Socket sock) + { + Client = sock; + } + + protected Socket Client { + get { return client; } + set { + client = value; + stream = null; + } + } + + public PeerCred PeerCredential { + get { + CheckDisposed (); + return new PeerCred (client); + } + } + + public LingerOption LingerState { + get { + CheckDisposed (); + return (LingerOption) client.GetSocketOption (SocketOptionLevel.Socket, + SocketOptionName.Linger); + } + + set { + CheckDisposed (); + client.SetSocketOption (SocketOptionLevel.Socket, + SocketOptionName.Linger, value); + } + } + + public int ReceiveBufferSize { + get { + CheckDisposed (); + return (int) client.GetSocketOption (SocketOptionLevel.Socket, + SocketOptionName.ReceiveBuffer); + } + + set { + CheckDisposed (); + client.SetSocketOption (SocketOptionLevel.Socket, + SocketOptionName.ReceiveBuffer, value); + } + } + + public int ReceiveTimeout { + get { + CheckDisposed (); + return (int) client.GetSocketOption (SocketOptionLevel.Socket, + SocketOptionName.ReceiveTimeout); + } + + set { + CheckDisposed (); + client.SetSocketOption (SocketOptionLevel.Socket, + SocketOptionName.ReceiveTimeout, value); + } + } + + public int SendBufferSize { + get { + CheckDisposed (); + return (int) client.GetSocketOption (SocketOptionLevel.Socket, + SocketOptionName.SendBuffer); + } + + set { + CheckDisposed (); + client.SetSocketOption (SocketOptionLevel.Socket, + SocketOptionName.SendBuffer, value); + } + } + + public int SendTimeout { + get { + CheckDisposed (); + return (int) client.GetSocketOption (SocketOptionLevel.Socket, + SocketOptionName.SendTimeout); + } + + set { + CheckDisposed (); + client.SetSocketOption (SocketOptionLevel.Socket, + SocketOptionName.SendTimeout, value); + } + } + + public void Close () + { + CheckDisposed (); + Dispose (); + } + + public void Connect (UnixEndPoint remoteEndPoint) + { + CheckDisposed (); + client.Connect (remoteEndPoint); + stream = new NetworkStream (client, true); + } + + public void Connect (string path) + { + CheckDisposed (); + Connect (new UnixEndPoint (path)); + } + + public void Dispose () + { + Dispose (true); + GC.SuppressFinalize (this); + } + + protected virtual void Dispose (bool disposing) + { + if (disposed) + return; + + if (disposing) { + // release managed resources + NetworkStream s = stream; + stream = null; + if (s != null) { + // This closes the socket as well, as the NetworkStream + // owns the socket. + s.Close(); + s = null; + } else if (client != null){ + client.Close (); + } + client = null; + } + + disposed = true; + } + + public NetworkStream GetStream () + { + CheckDisposed (); + if (stream == null) + stream = new NetworkStream (client, true); + + return stream; + } + + void CheckDisposed () + { + if (disposed) + throw new ObjectDisposedException (GetType().FullName); + } + + ~UnixClient () + { + Dispose (false); + } + } +} + diff --git a/mcs/class/Mono.Posix/Mono.Unix/UnixListener.cs b/mcs/class/Mono.Posix/Mono.Unix/UnixListener.cs new file mode 100644 index 00000000000..16ae156b1c7 --- /dev/null +++ b/mcs/class/Mono.Posix/Mono.Unix/UnixListener.cs @@ -0,0 +1,177 @@ +// +// UnixListener.cs +// +// Authors: +// Joe Shaw (joeshaw@novell.com) +// +// Copyright (C) 2004-2005 Novell, Inc. +// + +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +using System; +using System.Net; +using System.Net.Sockets; +using System.IO; + +namespace Mono.Unix { + + public class UnixListener : IDisposable { + bool disposed; + bool listening; + Socket server; + EndPoint savedEP; + + void Init (UnixEndPoint ep) + { + Cleanup (ep); + listening = false; + string filename = ep.Filename; + if (File.Exists (filename)) { + Socket conn = new Socket (AddressFamily.Unix, SocketType.Stream, 0); + try { + conn.Connect (ep); + conn.Close (); + throw new InvalidOperationException ("There's already a server listening on " + filename); + } catch (SocketException se) { + } + File.Delete (filename); + } + + server = new Socket (AddressFamily.Unix, SocketType.Stream, 0); + server.Bind (ep); + savedEP = server.LocalEndPoint; + } + + public UnixListener (string path) + { + if (!Directory.Exists (Path.GetDirectoryName (path))) + Directory.CreateDirectory (Path.GetDirectoryName (path)); + + Init (new UnixEndPoint (path)); + } + + public UnixListener (UnixEndPoint localEndPoint) + { + if (localEndPoint == null) + throw new ArgumentNullException ("localendPoint"); + + Init (localEndPoint); + } + + public EndPoint LocalEndpoint { + get { return savedEP; } + } + + protected Socket Server { + get { return server; } + } + + public Socket AcceptSocket () + { + CheckDisposed (); + if (!listening) + throw new InvalidOperationException ("Socket is not listening"); + + return server.Accept (); + } + + public UnixClient AcceptUnixClient () + { + CheckDisposed (); + if (!listening) + throw new InvalidOperationException ("Socket is not listening"); + + return new UnixClient (AcceptSocket ()); + } + + ~UnixListener () + { + Dispose (false); + } + + public bool Pending () + { + CheckDisposed (); + if (!listening) + throw new InvalidOperationException ("Socket is not listening"); + + return server.Poll (1000, SelectMode.SelectRead); + } + + public void Start () + { + Start (5); + } + + public void Start (int backlog) + { + CheckDisposed (); + if (listening) + return; + + server.Listen (backlog); + listening = true; + } + + public void Stop () + { + CheckDisposed (); + Dispose (true); + } + + public void Dispose () + { + Dispose (true); + GC.SuppressFinalize (this); + } + + protected void Dispose (bool disposing) + { + if (disposed) + return; + + if (disposing) { + if (server != null) + server.Close (); + + server = null; + } + + disposed = true; + } + + void CheckDisposed () + { + if (disposed) + throw new ObjectDisposedException (GetType().FullName); + } + + static void Cleanup (UnixEndPoint ep) + { + string path = ((UnixEndPoint) ep).Filename; + if (File.Exists (path)) + File.Delete (path); + } + } + +}