New test.
[mono.git] / mcs / class / Mono.Posix / Mono.Unix / UnixListener.cs
1 //
2 // UnixListener.cs
3 //
4 // Authors:
5 //      Joe Shaw (joeshaw@novell.com)
6 //
7 // Copyright (C) 2004-2005 Novell, Inc.
8 //
9
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining a
12 // copy of this software and associated documentation files (the "Software"),
13 // to deal in the Software without restriction, including without limitation
14 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 // and/or sell copies of the Software, and to permit persons to whom the
16 // Software is furnished to do so, subject to the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be included in
19 // all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 // DEALINGS IN THE SOFTWARE.
28 //
29
30
31 using System;
32 using System.Net;
33 using System.Net.Sockets;
34 using System.IO;
35
36 namespace Mono.Unix {
37
38         public class UnixListener : MarshalByRefObject, IDisposable {
39                 bool disposed;
40                 bool listening;
41                 Socket server;
42                 EndPoint savedEP;
43  
44                 void Init (UnixEndPoint ep)
45                 {
46                         listening = false;
47                         string filename = ep.Filename;
48                         if (File.Exists (filename)) {
49                                 Socket conn = new Socket (AddressFamily.Unix, SocketType.Stream, 0);
50                                 try {
51                                         conn.Connect (ep);
52                                         conn.Close ();
53                                         throw new InvalidOperationException ("There's already a server listening on " + filename);
54                                 } catch (SocketException se) {
55                                 }
56                                 File.Delete (filename);
57                         }
58
59                         server = new Socket (AddressFamily.Unix, SocketType.Stream, 0);
60                         server.Bind (ep);
61                         savedEP = server.LocalEndPoint;
62                 }
63         
64                 public UnixListener (string path)
65                 {
66                         if (!Directory.Exists (Path.GetDirectoryName (path)))
67                                 Directory.CreateDirectory (Path.GetDirectoryName (path));
68             
69                         Init (new UnixEndPoint (path));
70                 }
71
72                 public UnixListener (UnixEndPoint localEndPoint)
73                 {
74                         if (localEndPoint == null)
75                                 throw new ArgumentNullException ("localendPoint");
76
77                         Init (localEndPoint);
78                 }
79         
80                 public EndPoint LocalEndpoint {
81                         get { return savedEP; }
82                 }
83         
84                 protected Socket Server {
85                         get { return server; }
86                 }
87         
88                 public Socket AcceptSocket ()
89                 {
90                         CheckDisposed ();
91                         if (!listening)
92                                 throw new InvalidOperationException ("Socket is not listening");
93
94                         return server.Accept ();
95                 }
96         
97                 public UnixClient AcceptUnixClient ()
98                 {
99                         CheckDisposed ();
100                         if (!listening)
101                                 throw new InvalidOperationException ("Socket is not listening");
102
103                         return new UnixClient (AcceptSocket ());
104                 }
105         
106                 ~UnixListener ()
107                 {
108                         Dispose (false);
109                 }
110     
111                 public bool Pending ()
112                 {
113                         CheckDisposed ();
114                         if (!listening)
115                                 throw new InvalidOperationException ("Socket is not listening");
116
117                         return server.Poll (1000, SelectMode.SelectRead);
118                 }
119         
120                 public void Start ()
121                 {
122                         Start (5);
123                 }
124         
125                 public void Start (int backlog)
126                 {
127                         CheckDisposed ();
128                         if (listening)
129                                 return;
130
131                         server.Listen (backlog);
132                         listening = true;
133                 }
134
135                 public void Stop ()
136                 {
137                         CheckDisposed ();
138                         Dispose (true);
139                 }
140
141                 public void Dispose ()
142                 {
143                         Dispose (true);
144                         GC.SuppressFinalize (this);
145                 }
146
147                 protected void Dispose (bool disposing)
148                 {
149                         if (disposed)
150                                 return;
151
152                         if (disposing) {
153                                 if (server != null)
154                                         server.Close ();
155
156                                 server = null;
157                         }
158
159                         disposed = true;
160                 }
161         
162                 void CheckDisposed ()
163                 {
164                         if (disposed)
165                                 throw new ObjectDisposedException (GetType().FullName);
166                 }        
167         }
168
169 }