123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
|
/*******************************************************************************
copyright: Copyright (c) 2009 Tango. All rights reserved
license: BSD style: $(LICENSE)
version: Nov 2009: Initial release
author: Lukas Pinkowski, Kris
*******************************************************************************/
module tango.net.device.LocalSocket;
private import tango.net.device.Socket;
private import tango.net.device.Berkeley;
/*******************************************************************************
*******************************************************************************/
version (Windows)
{
pragma(msg, "not yet available for windows");
}
/*******************************************************************************
A wrapper around the Berkeley API to implement the IConduit
abstraction and add stream-specific functionality.
*******************************************************************************/
class LocalSocket : Socket
{
/***********************************************************************
Create a streaming local socket
***********************************************************************/
private this ()
{
super (AddressFamily.UNIX, SocketType.STREAM, ProtocolType.IP);
}
/***********************************************************************
Create a streaming local socket
***********************************************************************/
this (const(char)[] path)
{
this (new LocalAddress (path));
}
/***********************************************************************
Create a streaming local socket
***********************************************************************/
this (LocalAddress addr)
{
this();
super.connect (addr);
}
/***********************************************************************
Return the name of this device
***********************************************************************/
override immutable(char)[] toString()
{
return "<localsocket>";
}
}
/*******************************************************************************
*******************************************************************************/
class LocalServerSocket : LocalSocket
{
/***********************************************************************
***********************************************************************/
this (const(char)[] path, int backlog=32, bool reuse=false)
{
auto addr = new LocalAddress (path);
native.addressReuse(reuse).bind(addr).listen(backlog);
}
/***********************************************************************
Return the name of this device
***********************************************************************/
override immutable(char)[] toString()
{
return "<localaccept>";
}
/***********************************************************************
***********************************************************************/
Socket accept (Socket recipient = null)
{
if (recipient is null)
recipient = new LocalSocket;
native.accept (*recipient.native);
recipient.timeout = timeout;
return recipient;
}
}
/*******************************************************************************
*******************************************************************************/
class LocalAddress : Address
{
align(1) struct sockaddr_un
{
ushort sun_family = AddressFamily.UNIX;
char[108] sun_path;
}
protected
{
sockaddr_un sun;
const(char)[] _path;
size_t _pathLength;
}
/***********************************************************************
-path- path to a unix domain socket (which is a filename)
***********************************************************************/
this (const(char)[] path)
{
assert (path.length < 108);
sun.sun_path [0 .. path.length] = path;
sun.sun_path [path.length .. $] = 0;
_pathLength = path.length;
_path = sun.sun_path [0 .. path.length];
}
/***********************************************************************
***********************************************************************/
@property override final sockaddr* name ()
{
return cast(sockaddr*) &sun;
}
/***********************************************************************
***********************************************************************/
@property override final const int nameLen ()
{
return cast(int)(_pathLength + ushort.sizeof);
}
/***********************************************************************
***********************************************************************/
@property override final AddressFamily addressFamily ()
{
return AddressFamily.UNIX;
}
/***********************************************************************
***********************************************************************/
final override string toString ()
{
if (isAbstract)
return "unix:abstract=" ~ _path[1..$].idup;
else
return "unix:path=" ~ _path.idup;
}
/***********************************************************************
***********************************************************************/
@property final const const(char)[] path ()
{
return _path;
}
/***********************************************************************
***********************************************************************/
@property final const bool isAbstract ()
{
return _path[0] == 0;
}
}
/******************************************************************************
******************************************************************************/
debug (LocalSocket)
{
import tango.io.Stdout;
void main()
{
auto y = new LocalSocket ("foo");
auto x = new LocalServerSocket ("foo");
}
}
|