1 /******************************************************************************* 2 3 copyright: Copyright (c) 2009 Tango. All rights reserved 4 5 license: BSD style: $(LICENSE) 6 7 version: Nov 2009: Initial release 8 9 author: Lukas Pinkowski, Kris 10 11 *******************************************************************************/ 12 13 module tango.net.device.LocalSocket; 14 15 private import tango.net.device.Socket; 16 private import tango.net.device.Berkeley; 17 18 /******************************************************************************* 19 20 21 *******************************************************************************/ 22 23 version (Posix): 24 25 /******************************************************************************* 26 27 A wrapper around the Berkeley API to implement the IConduit 28 abstraction and add stream-specific functionality. 29 30 *******************************************************************************/ 31 32 class LocalSocket : Socket 33 { 34 /*********************************************************************** 35 36 Create a streaming local socket 37 38 ***********************************************************************/ 39 40 private this () 41 { 42 super (AddressFamily.UNIX, SocketType.STREAM, ProtocolType.IP); 43 } 44 45 /*********************************************************************** 46 47 Create a streaming local socket 48 49 ***********************************************************************/ 50 51 this (const(char)[] path) 52 { 53 this (new LocalAddress (path)); 54 } 55 56 /*********************************************************************** 57 58 Create a streaming local socket 59 60 ***********************************************************************/ 61 62 this (LocalAddress addr) 63 { 64 this(); 65 super.connect (addr); 66 } 67 68 /*********************************************************************** 69 70 Return the name of this device 71 72 ***********************************************************************/ 73 74 override immutable(char)[] toString() 75 { 76 return "<localsocket>"; 77 } 78 } 79 80 /******************************************************************************* 81 82 83 *******************************************************************************/ 84 85 class LocalServerSocket : LocalSocket 86 { 87 /*********************************************************************** 88 89 ***********************************************************************/ 90 91 this (const(char)[] path, int backlog=32, bool reuse=false) 92 { 93 auto addr = new LocalAddress (path); 94 native.addressReuse(reuse).bind(addr).listen(backlog); 95 } 96 97 /*********************************************************************** 98 99 Return the name of this device 100 101 ***********************************************************************/ 102 103 override immutable(char)[] toString() 104 { 105 return "<localaccept>"; 106 } 107 108 /*********************************************************************** 109 110 ***********************************************************************/ 111 112 Socket accept (Socket recipient = null) 113 { 114 if (recipient is null) 115 recipient = new LocalSocket; 116 117 native.accept (*recipient.native); 118 recipient.timeout = timeout; 119 return recipient; 120 } 121 } 122 123 /******************************************************************************* 124 125 *******************************************************************************/ 126 127 class LocalAddress : Address 128 { 129 align(1) struct sockaddr_un 130 { 131 ushort sun_family = AddressFamily.UNIX; 132 char[108] sun_path; 133 } 134 135 protected 136 { 137 sockaddr_un sun; 138 const(char)[] _path; 139 size_t _pathLength; 140 } 141 142 /*********************************************************************** 143 144 -path- path to a unix domain socket (which is a filename) 145 146 ***********************************************************************/ 147 148 this (const(char)[] path) 149 { 150 assert (path.length < 108); 151 152 sun.sun_path [0 .. path.length] = path[]; 153 sun.sun_path [path.length .. $] = 0; 154 155 _pathLength = path.length; 156 _path = sun.sun_path [0 .. path.length]; 157 } 158 159 /*********************************************************************** 160 161 ***********************************************************************/ 162 163 @property override final sockaddr* name () 164 { 165 return cast(sockaddr*) &sun; 166 } 167 168 /*********************************************************************** 169 170 ***********************************************************************/ 171 172 @property override final const int nameLen () 173 { 174 return cast(int)(_pathLength + ushort.sizeof); 175 } 176 177 /*********************************************************************** 178 179 ***********************************************************************/ 180 181 @property override final AddressFamily addressFamily () 182 { 183 return AddressFamily.UNIX; 184 } 185 186 /*********************************************************************** 187 188 ***********************************************************************/ 189 190 final override string toString () 191 { 192 if (isAbstract) 193 return "unix:abstract=" ~ _path[1..$].idup; 194 else 195 return "unix:path=" ~ _path.idup; 196 } 197 198 /*********************************************************************** 199 200 ***********************************************************************/ 201 202 @property final const const(char)[] path () 203 { 204 return _path; 205 } 206 207 /*********************************************************************** 208 209 ***********************************************************************/ 210 211 @property final const bool isAbstract () 212 { 213 return _path[0] == 0; 214 } 215 } 216 217 /****************************************************************************** 218 219 ******************************************************************************/ 220 221 debug (LocalSocket) 222 { 223 import tango.io.Stdout; 224 225 void main() 226 { 227 auto y = new LocalSocket ("foo"); 228 auto x = new LocalServerSocket ("foo"); 229 } 230 }