2005-04-21 Gonzalo Paniagua Javier <gonzalo@ximian.com>
authorGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Thu, 21 Apr 2005 20:00:20 +0000 (20:00 -0000)
committerGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Thu, 21 Apr 2005 20:00:20 +0000 (20:00 -0000)
* 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

mcs/class/Mono.Posix/Mono.Posix.dll.sources
mcs/class/Mono.Posix/Mono.Unix/ChangeLog
mcs/class/Mono.Posix/Mono.Unix/UnixClient.cs [new file with mode: 0644]
mcs/class/Mono.Posix/Mono.Unix/UnixListener.cs [new file with mode: 0644]

index 490a6d14876fc917052001e1605e2c658754b20d..dad6be996d3d264c0fa3a65c57f09a741f7ddb05 100644 (file)
@@ -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
index 35a89142fa2c13da965642ae41f1bf2febb653c9..481cce8820cde1c217c90355cc75a8253238a77c 100644 (file)
@@ -1,3 +1,13 @@
+2005-04-21 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * UnixClient.cs:
+       * UnixListener.cs: TcpListener/TcpClient clones from Jow Shaw.
+
+2005-04-21 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * Mono.Posix.dll.sources: added UnixListener and UnixClient from Joe
+       Shaw.
+
 2005-04-21 Gonzalo Paniagua Javier <gonzalo@ximian.com>
 
        * 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 (file)
index 0000000..29416cf
--- /dev/null
@@ -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 (file)
index 0000000..16ae156
--- /dev/null
@@ -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);
+               }
+       }
+
+}