#include "inet.h"
#include "inet6.h"
#include "sockaddr_private.h"
+#include "unix.h"
using namespace std;
return new InetAddr(sa);
case AF_INET6:
return new Inet6Addr(sa);
+ case AF_UNIX:
+ return new UnixAddr(sa);
default:
throw invalid_argument("SockAddr::create");
}
--- /dev/null
+#include <stdexcept>
+#ifndef WIN32
+#include <sys/un.h>
+#endif
+#include "sockaddr_private.h"
+#include "unix.h"
+
+using namespace std;
+
+namespace Msp {
+namespace Net {
+
+UnixAddr::UnixAddr():
+ abstract(false)
+{
+#ifdef WIN32
+ throw logic_error("no unix sockets on windows");
+#endif
+}
+
+UnixAddr::UnixAddr(const SysAddr &sa):
+ abstract(false)
+{
+#ifdef WIN32
+ (void)sa;
+ throw logic_error("no unix sockets on windows");
+#else
+ const sockaddr_un &sau = reinterpret_cast<const sockaddr_un &>(sa.addr);
+ if(sa.size>sizeof(sa_family_t))
+ {
+ abstract = (sau.sun_path[0]==0);
+ path.assign(sau.sun_path+abstract, sa.size-sizeof(sa_family_t)-abstract);
+ }
+#endif
+}
+
+UnixAddr::UnixAddr(const string &p, bool a):
+ path(p),
+ abstract(a)
+{
+#ifdef WIN32
+ throw logic_error("no unix sockets on windows");
+#else
+ if(sizeof(sa_family_t)+path.size()+1>sizeof(sockaddr_storage))
+ throw invalid_argument("UnixAddr");
+#endif
+}
+
+SockAddr::SysAddr UnixAddr::to_sys() const
+{
+ SysAddr sa;
+#ifndef WIN32
+ sa.size = sizeof(sa_family_t);
+ if(!path.empty())
+ sa.size += path.size()+1;
+
+ sockaddr_un &sau = reinterpret_cast<sockaddr_un &>(sa.addr);
+ sau.sun_family = AF_UNIX;
+ if(!path.empty())
+ {
+ if(abstract)
+ sau.sun_path[0] = 0;
+ std::copy(path.begin(), path.end(), sau.sun_path+abstract);
+ if(!abstract)
+ sau.sun_path[path.size()] = 0;
+ }
+#endif
+
+ return sa;
+}
+
+string UnixAddr::str() const
+{
+ string result = "unix:";
+ if(abstract)
+ result += '@';
+ result += path;
+ return result;
+}
+
+} // namespace Net
+} // namespace Msp
--- /dev/null
+#ifndef MSP_NET_UNIX_H_
+#define MSP_NET_UNIX_H_
+
+#include "sockaddr.h"
+
+namespace Msp {
+namespace Net {
+
+class UnixAddr: public SockAddr
+{
+private:
+ std::string path;
+ bool abstract;
+
+public:
+ UnixAddr();
+ UnixAddr(const SysAddr &);
+ UnixAddr(const std::string &, bool = false);
+
+ virtual UnixAddr *copy() const { return new UnixAddr(*this); }
+
+ virtual SysAddr to_sys() const;
+
+ virtual Family get_family() const { return UNIX; }
+ virtual std::string str() const;
+};
+
+} // namespace Net
+} // namespace Msp
+
+#endif