1 /* LocalSocketImpl.java -- a unix domain client socket implementation.
2    Copyright (C) 2006  Free Software Foundation, Inc.
3 
4 This file is a part of GNU Classpath.
5 
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or (at
9 your option) any later version.
10 
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
19 USA
20 
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25 
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version.  */
37 
38 
39 package gnu.java.net.local;
40 
41 import gnu.classpath.Configuration;
42 
43 import java.io.FileDescriptor;
44 import java.io.InputStream;
45 import java.io.IOException;
46 import java.io.OutputStream;
47 
48 import java.net.InetAddress;
49 import java.net.SocketAddress;
50 import java.net.SocketException;
51 import java.net.SocketImpl;
52 
53 final class LocalSocketImpl extends SocketImpl
54 {
55 
56   // Fields.
57   // -------------------------------------------------------------------------
58 
59   private boolean created;
60   private InputStream in;
61   private OutputStream out;
62   // Package private to avoid synthetic accessor method.
63   int socket_fd;
64   private LocalSocketAddress local;
65   private LocalSocketAddress remote;
66 
67   static
68   {
69     try
70       {
71         if (Configuration.INIT_LOAD_LIBRARY)
72           {
73             System.loadLibrary ("javanet");
74           }
75       }
76     catch (Exception x)
77       {
78         x.printStackTrace ();
79       }
80   }
81 
82   // Constructor.
83   // -------------------------------------------------------------------------
84 
LocalSocketImpl()85   LocalSocketImpl ()
86   {
87     this (false);
88   }
89 
LocalSocketImpl(boolean nocreate)90   LocalSocketImpl (boolean nocreate)
91   {
92     created = nocreate;
93     socket_fd = -1;
94     fd = new FileDescriptor ();
95   }
96 
97   // Instance methods.
98   // -------------------------------------------------------------------------
99 
setOption(int opt, Object value)100   public void setOption (int opt, Object value) throws SocketException
101   {
102     throw new SocketException ("local sockets do not support options");
103   }
104 
getOption(int opt)105   public Object getOption (int opt) throws SocketException
106   {
107     throw new SocketException ("local sockets do not support options");
108   }
109 
create(boolean stream)110   protected native void create (boolean stream) throws IOException;
listen(int timeout)111   protected native void listen (int timeout) throws IOException;
accept(LocalSocketImpl socket)112   protected native void accept (LocalSocketImpl socket) throws IOException;
available(int fd)113   protected native int available (int fd) throws IOException;
close()114   protected native void close () throws IOException;
sendUrgentData(int data)115   protected native void sendUrgentData (int data) throws IOException;
shutdownInput()116   protected native void shutdownInput () throws IOException;
shutdownOutput()117   protected native void shutdownOutput () throws IOException;
118 
unlink()119   native void unlink () throws IOException;
localBind(LocalSocketAddress addr)120   native void localBind (LocalSocketAddress addr) throws IOException;
localConnect(LocalSocketAddress addr)121   native void localConnect (LocalSocketAddress addr) throws IOException;
read(int fd, byte[] buf, int off, int len)122   native int read (int fd, byte[] buf, int off, int len) throws IOException;
write(int fd, byte[] buf, int off, int len)123   native void write (int fd, byte[] buf, int off, int len) throws IOException;
124 
available()125   protected int available()
126     throws IOException
127   {
128     return available(socket_fd);
129   }
130 
doCreate()131   void doCreate () throws IOException
132   {
133     if (!created)
134       {
135         create (true);
136       }
137   }
138 
getLocalAddress()139   LocalSocketAddress getLocalAddress ()
140   {
141     return local;
142   }
143 
getRemoteAddress()144   LocalSocketAddress getRemoteAddress ()
145   {
146     return remote;
147   }
148 
getInputStream()149   protected InputStream getInputStream()
150   {
151     if (in == null)
152       {
153         in = new LocalInputStream (this);
154       }
155 
156     return in;
157   }
158 
getOutputStream()159   protected OutputStream getOutputStream()
160   {
161     if (out == null)
162       {
163         out = new LocalOutputStream (this);
164       }
165 
166     return out;
167   }
168 
accept(SocketImpl impl)169   protected void accept (SocketImpl impl) throws IOException
170   {
171     if (! (impl instanceof LocalSocketImpl))
172       {
173         throw new IllegalArgumentException ("not a local socket");
174       }
175     accept ((LocalSocketImpl) impl);
176   }
177 
connect(String host, int port)178   protected void connect (String host, int port) throws IOException
179   {
180     throw new SocketException ("this is a local socket");
181   }
182 
connect(InetAddress addr, int port)183   protected void connect (InetAddress addr, int port) throws IOException
184   {
185     throw new SocketException ("this is a local socket");
186   }
187 
connect(SocketAddress addr, int timeout)188   protected void connect(SocketAddress addr, int timeout) throws IOException
189   {
190     if (! (addr instanceof LocalSocketAddress))
191       {
192         throw new SocketException ("address is not local");
193       }
194     localConnect ((LocalSocketAddress) addr);
195   }
196 
bind(InetAddress addr, int port)197   protected void bind (InetAddress addr, int port) throws IOException
198   {
199     throw new SocketException ("this is a local socket");
200   }
201 
bind(SocketAddress addr)202   protected void bind (SocketAddress addr) throws IOException
203   {
204     if (! (addr instanceof LocalSocketAddress))
205       {
206         throw new SocketException ("address is not local");
207       }
208     localBind ((LocalSocketAddress) addr);
209   }
210 
211 // Inner classes.
212   // -------------------------------------------------------------------------
213 
214   class LocalInputStream extends InputStream
215   {
216 
217     // Field.
218     // -----------------------------------------------------------------------
219 
220     private final LocalSocketImpl impl;
221 
222     // Constructor.
223     // -----------------------------------------------------------------------
224 
LocalInputStream(LocalSocketImpl impl)225     LocalInputStream (LocalSocketImpl impl)
226     {
227       this.impl = impl;
228     }
229 
230     // Instance methods.
231     // -----------------------------------------------------------------------
232 
available()233     public int available () throws IOException
234     {
235       return impl.available();
236     }
237 
markSupported()238     public boolean markSupported ()
239     {
240       return false;
241     }
242 
mark(int readLimit)243     public void mark (int readLimit)
244     {
245     }
246 
reset()247     public void reset () throws IOException
248     {
249       throw new IOException ("mark/reset not supported");
250     }
251 
close()252     public void close () throws IOException
253     {
254       impl.close();
255     }
256 
read()257     public int read () throws IOException
258     {
259       byte[] buf = new byte[1];
260       int ret = read (buf);
261       if (ret != -1)
262         {
263           return buf[0] & 0xFF;
264         }
265       else
266         {
267           return -1;
268         }
269     }
270 
read(byte[] buf)271     public int read (byte[] buf) throws IOException
272     {
273       return read (buf, 0, buf.length);
274     }
275 
read(byte[] buf, int off, int len)276     public int read (byte[] buf, int off, int len) throws IOException
277     {
278       int ret = impl.read (socket_fd, buf, off, len);
279 
280       if (ret == 0)
281         {
282           return -1;
283         }
284 
285       return ret;
286     }
287   }
288 
289   class LocalOutputStream extends OutputStream
290   {
291 
292     // Field.
293     // -----------------------------------------------------------------------
294 
295     private final LocalSocketImpl impl;
296 
297     // Constructor.
298     // -----------------------------------------------------------------------
299 
LocalOutputStream(LocalSocketImpl impl)300     LocalOutputStream (LocalSocketImpl impl)
301     {
302       this.impl = impl;
303     }
304 
305     // Instance methods.
306     // -----------------------------------------------------------------------
307 
close()308     public void close () throws IOException
309     {
310       impl.close ();
311     }
312 
flush()313     public void flush () throws IOException
314     {
315     }
316 
write(int b)317     public void write (int b) throws IOException
318     {
319       byte[] buf = new byte [1];
320       buf[0] = (byte) b;
321       write (buf);
322     }
323 
write(byte[] buf)324     public void write (byte[] buf) throws IOException
325     {
326       write (buf, 0, buf.length);
327     }
328 
write(byte[] buf, int off, int len)329     public void write (byte[] buf, int off, int len) throws IOException
330     {
331       impl.write (socket_fd, buf, off, len);
332     }
333   }
334 }
335