1 //
2 // UnixClient.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 using System;
31 using System.IO;
32 using System.Net;
33 using System.Net.Sockets;
34 using System.Runtime.InteropServices;
35 
36 namespace Mono.Unix {
37 
38 	public class UnixClient : MarshalByRefObject, IDisposable {
39 		NetworkStream stream;
40 		Socket client;
41 		bool disposed;
42 
UnixClient()43 		public UnixClient ()
44 		{
45 			if (client != null) {
46 				client.Close ();
47 				client = null;
48 			}
49 
50 			client = new Socket (AddressFamily.Unix, SocketType.Stream, 0);
51 		}
52 
UnixClient(string path)53 		public UnixClient (string path) : this ()
54 		{
55 			if (path == null)
56 				throw new ArgumentNullException ("ep");
57 
58 			Connect (path);
59 		}
60 
UnixClient(UnixEndPoint ep)61 		public UnixClient (UnixEndPoint ep) : this ()
62 		{
63 			if (ep == null)
64 				throw new ArgumentNullException ("ep");
65 
66 			Connect (ep);
67 		}
68 
69 		// UnixListener uses this when accepting a connection.
UnixClient(Socket sock)70 		internal UnixClient (Socket sock)
71 		{
72 			Client = sock;
73 		}
74 
75 		public
76 		Socket Client {
77 			get { return client; }
78 			set {
79 				client = value;
80 				stream = null;
81 			}
82 		}
83 
84 		public PeerCred PeerCredential {
85 			get {
86 				CheckDisposed ();
87 				return new PeerCred (client);
88 			}
89 		}
90 
91 		public LingerOption LingerState {
92 			get {
93 				CheckDisposed ();
94 				return (LingerOption) client.GetSocketOption (SocketOptionLevel.Socket,
95 									      SocketOptionName.Linger);
96 			}
97 
98 			set {
99 				CheckDisposed ();
100 				client.SetSocketOption (SocketOptionLevel.Socket,
101 							SocketOptionName.Linger, value);
102 			}
103 		}
104 
105 		public int ReceiveBufferSize {
106 			get {
107 				CheckDisposed ();
108 				return (int) client.GetSocketOption (SocketOptionLevel.Socket,
109 								     SocketOptionName.ReceiveBuffer);
110 			}
111 
112 			set {
113 				CheckDisposed ();
114 				client.SetSocketOption (SocketOptionLevel.Socket,
115 							SocketOptionName.ReceiveBuffer, value);
116 			}
117 		}
118 
119 		public int ReceiveTimeout {
120 			get {
121 				CheckDisposed ();
122 				return (int) client.GetSocketOption (SocketOptionLevel.Socket,
123 								     SocketOptionName.ReceiveTimeout);
124 			}
125 
126 			set {
127 				CheckDisposed ();
128 				client.SetSocketOption (SocketOptionLevel.Socket,
129 							SocketOptionName.ReceiveTimeout, value);
130 			}
131 		}
132 
133 		public int SendBufferSize {
134 			get {
135 				CheckDisposed ();
136 				return (int) client.GetSocketOption (SocketOptionLevel.Socket,
137 								     SocketOptionName.SendBuffer);
138 			}
139 
140 			set {
141 				CheckDisposed ();
142 				client.SetSocketOption (SocketOptionLevel.Socket,
143 							SocketOptionName.SendBuffer, value);
144 			}
145 		}
146 
147 		public int SendTimeout {
148 			get {
149 				CheckDisposed ();
150 				return (int) client.GetSocketOption (SocketOptionLevel.Socket,
151 								     SocketOptionName.SendTimeout);
152 			}
153 
154 			set {
155 				CheckDisposed ();
156 				client.SetSocketOption (SocketOptionLevel.Socket,
157 							SocketOptionName.SendTimeout, value);
158 			}
159 		}
160 
Close()161 		public void Close ()
162 		{
163 			CheckDisposed ();
164 			Dispose ();
165 		}
166 
Connect(UnixEndPoint remoteEndPoint)167 		public void Connect (UnixEndPoint remoteEndPoint)
168 		{
169 			CheckDisposed ();
170 			client.Connect (remoteEndPoint);
171 			stream = new NetworkStream (client, true);
172 		}
173 
Connect(string path)174 		public void Connect (string path)
175 		{
176 			CheckDisposed ();
177 			Connect (new UnixEndPoint (path));
178 		}
179 
Dispose()180 		public void Dispose ()
181 		{
182 			Dispose (true);
183 			GC.SuppressFinalize (this);
184 		}
185 
Dispose(bool disposing)186 		protected virtual void Dispose (bool disposing)
187 		{
188 			if (disposed)
189 				return;
190 
191 			if (disposing) {
192 				// release managed resources
193 				NetworkStream s = stream;
194 				stream = null;
195 				if (s != null) {
196 					// This closes the socket as well, as the NetworkStream
197 					// owns the socket.
198 					s.Close();
199 					s = null;
200 				} else if (client != null){
201 					client.Close ();
202 				}
203 				client = null;
204 			}
205 
206 			disposed = true;
207 		}
208 
GetStream()209 		public NetworkStream GetStream ()
210 		{
211 			CheckDisposed ();
212 			if (stream == null)
213 				stream = new NetworkStream (client, true);
214 
215 			return stream;
216 		}
217 
CheckDisposed()218 		void CheckDisposed ()
219 		{
220 			if (disposed)
221 				throw new ObjectDisposedException (GetType().FullName);
222 		}
223 
~UnixClient()224 		~UnixClient ()
225 		{
226 			Dispose (false);
227 		}
228 	}
229 }
230 
231