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