📄 wysockaddrlocal.cpp
字号:
/* Copyright is licensed under GNU LGPL. by I.J.Wang 2003 -- Note -- Documents says differently(to me) with the data stored in sun_path[] Manual page [unix(7),Redhat v9.0]: sun_path contains the zero-terminated pathname.., and it indicates that the rest of bytes in sun_path is meaningful? Unix Network Programming [W. RICHARD STEVENS] v1,p374: The pathname stored in the sun_path array must be null terminated.. Linux Application Development [Johnson,Troan] 2nd, p419: The sun_path does not need to be '\0' terminated. Other documents indicates either the trailing zero is counted or not. Implement takes what is meant in the header file un.h: # define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path)\ + strlen ((ptr)->sun_path)) i.e. zero-terminated, the trailing zero is not counted. -- Note -- (7)unix (Fedora3) says "..Linux supports an abstract namespace which is independent of the file system.... sun_path contains the zero terminated pathname of the socket in the file system. If sun_path starts with a zero byte it refers to the abstract namespace... The socket's address in this namespace is given by the rest of the bytes in sun_path.." Implement Basic#1: If sun_path contains a system file pathname, the pathname has to terminate with 0 (and may not contain 0), or SUN_LEN fails. (at least for now). And,the trailing zero is not counted in _slen. Implement Basic#2: If sun_path contains the system supported(Fedora3) namespace, rare info. available. SUN_LEN may fail for the 'abstract-namespace'. */#define WYLIB_SOURCE#include "wysockaddrlocal.h"#include <memory>#include <typeinfo>#include <cstring>const char WySockAddrLocal::class_name[]="WySockAddrLocal";const socklen_t WySockAddrLocal::SunPathZeroSize= (socklen_t)(((struct ::sockaddr_un*)0)->sun_path);const socklen_t WySockAddrLocal::DefaultSockLen=SunPathZeroSize;#ifndef NDEBUGclass WySockAddrLocal::Wy__Assert_Check__ { public: Wy__Assert_Check__() { struct ::sockaddr_un addr; addr.sun_path[0]=0; if(SunPathZeroSize!=SUN_LEN(&addr)) { WY_TERMINATE(""); } if(SunPathZeroSize!=DefaultSockLen) { WY_TERMINATE(""); } };} static const wy__do_not_use_me__;#endifWyRet WySockAddrLocal::_init_pathname(const char* pdata) WY__NOTHROW__{ if(pdata==0) { WY_RETURN(Wym_EFAULT); } const size_t plen( std::strlen(pdata) ); if(plen>=WySockAddrLocal::PathMaxLen) { WY_RETURN(Wym_ENAMETOOLONG); // not space for the trailing zero } _saddr.sun_family=AF_LOCAL; // note: trailing zero is stored because SUN_LEN may use it // std::memcpy(_saddr.sun_path,pdata,plen+1); _slen=SunPathZeroSize+plen; return(Ok);};WyRet WySockAddrLocal::_init_pathname(const char* pdata,size_t plen) WY__NOTHROW__{ if(pdata==0) { WY_RETURN(Wym_EFAULT); } if(plen>=WySockAddrLocal::PathMaxLen) { WY_RETURN(Wym_ENAMETOOLONG); } _saddr.sun_family=AF_LOCAL; std::memcpy(_saddr.sun_path,pdata,plen); // note: trailing zero is stored because SUN_LEN may use it // _saddr.sun_path[plen]=0; _slen=SunPathZeroSize+plen; return(Ok);};WyRet WySockAddrLocal::_init_lans(const char* pdata,size_t plen) WY__NOTHROW__{ if(pdata==0) { WY_RETURN(Wym_EFAULT); } if(plen>0) { if(plen>WySockAddrLocal::PathMaxLen) { WY_RETURN(Wym_ENAMETOOLONG); } if(pdata[0]!=0) { WY_RETURN(Wym_EINVAL); } } _saddr.sun_family=AF_LOCAL; std::memcpy(_saddr.sun_path,pdata,plen); _slen=SunPathZeroSize+plen; return(Ok);};WyRet WySockAddrLocal::_init_sockaddr(const struct ::sockaddr_un& addr, size_t len) WY__NOTHROW__{ if((len<SunPathZeroSize)||(len>sizeof(struct ::sockaddr_un))) { WY_RETURN(Wym_EINVAL); } std::memcpy(&_saddr,&addr,len); _slen=len; _saddr.sun_family=AF_LOCAL; return(Ok);};WySockAddrLocal::WySockAddrLocal() WY__TSPC() : _slen(DefaultSockLen) { _saddr.sun_family=AF_LOCAL;};WySockAddrLocal::WySockAddrLocal(const WySockAddrLocal &src) WY__TSPC(){ std::memcpy(&_saddr,&src._saddr,src._slen); _slen=src._slen;};WySockAddrLocal::WySockAddrLocal(const struct ::sockaddr_un& addr, size_t len) WY__TSPC(WyRet){ const WyRet r( this->_init_sockaddr(addr,len) ); if(r!=Ok) { WY_THROW( Reply(r) ); }};WySockAddrLocal::WySockAddrLocal(const char* path) WY__TSPC(WyRet){ const WyRet r( this->_init_pathname(path) ); if(r!=Ok) { WY_THROW( Reply(r) ); }};WySockAddrLocal::WySockAddrLocal(const WyStr& path) WY__TSPC(WyRet) : _slen(DefaultSockLen) { if(path.size()==0) { _saddr.sun_family=AF_LOCAL; return; } WyRet r; if(path[0]==0) { // path is a Linux-absolute-namespace if((r=this->_init_lans(path.data(),path.size()))!=Ok) { WY_THROW( Reply(r) ); } } else { if((r=this->_init_pathname(path.data(),path.size()))!=Ok) { WY_THROW( Reply(r) ); } }};WySockAddrLocal::WySockAddrLocal(const WyCSeg& path) WY__TSPC(WyRet) : _slen(DefaultSockLen) { if(path.size()==0) { _saddr.sun_family=AF_LOCAL; return; } WyRet r; if(path[0]==0) { // path is a Linux-absolute-namespace if((r=this->_init_lans(path.begin(),path.size()))!=Ok) { WY_THROW( Reply(r) ); } } else { if((r=this->_init_pathname(path.begin(),path.size()))!=Ok) { WY_THROW( Reply(r) ); } }};WySockAddrLocal::WySockAddrLocal(WySockAddrLocal &src, Wy::ByMove_t) WY__TSPC(){ if(&this->_saddr==&src._saddr) { return; // self move, probably ok } std::memcpy(&_saddr,&src._saddr,src._slen); _slen=src._slen; src._slen=0; // for safety and error detection};bool WySockAddrLocal::is_default(void) const WY__TSPC(){ return _slen==DefaultSockLen; };WyCSeg WySockAddrLocal::_path(void) const WY__TSPC(){ return WyCSeg(_saddr.sun_path,_sun_path_dlen());};WyRet WySockAddrLocal::notation(WyStr& str) const{ // note: the string from _path() may begin with 0, which is yet undefined. WY_RETURN( str.reset(this->_path()) );};void WySockAddrLocal::reset(void) WY__TSPC(){ _saddr.sun_family=AF_LOCAL; _slen=DefaultSockLen; };void WySockAddrLocal::reset(const WySockAddrLocal &src) WY__TSPC(){ _slen=src._slen; if(&_saddr!=&src._saddr) { std::memcpy(&_saddr,&src._saddr,src._slen); }};WyRet WySockAddrLocal::reset(const struct ::sockaddr_un& addr, size_t len) WY__TSPC(){ const WyRet r( this->_init_sockaddr(addr,len) ); if(r!=Ok) { WY_RETURN(r); } return(Ok);};WyRet WySockAddrLocal::reset(const char* path) WY__TSPC(){ const WyRet r( this->_init_pathname(path) ); if(r!=Ok) { WY_RETURN(r); } return(Ok);};WyRet WySockAddrLocal::reset(const WyStr& path) WY__TSPC(){ if(path.size()==0) { _slen=DefaultSockLen; _saddr.sun_family=AF_LOCAL; return(Ok); } WyRet r; if(path[0]==0) { // path is a Linux-absolute-namespace if((r=this->_init_lans(path.data(),path.size()))!=Ok) { WY_RETURN(r); } } else { if((r=this->_init_pathname(path.data(),path.size()))!=Ok) { WY_RETURN(r); } } return(Ok);};WyRet WySockAddrLocal::reset(const WyCSeg& path) WY__TSPC(){ if(path.size()==0) { _slen=DefaultSockLen; _saddr.sun_family=AF_LOCAL; return(Ok); } WyRet r; if(path[0]==0) { // path is a Linux-absolute-namespace if((r=this->_init_lans(path.begin(),path.size()))!=Ok) { WY_RETURN(r); } } else { if((r=this->_init_pathname(path.begin(),path.size()))!=Ok) { WY_RETURN(r); } } return(Ok);};WyRet WySockAddrLocal::_swap(Wy_SockAddr& laddr) WY__TSPC(){ if(WY__EQU_TYPEID(*this,laddr)==false) { WY_RETURN(Wym_EBADTYPE); } WySockAddrLocal* lptr( dynamic_cast<WySockAddrLocal*>(&laddr) ); Wy__Base::memswp(&_saddr,&lptr->_saddr,sizeof(_saddr)); Wy__Base::vswap(_slen,lptr->_slen); return(Ok);};WySockAddrLocal* WySockAddrLocal::_alloc(WyRet& r) consttry { if(WY__EQU_TYPEID(*this,WySockAddrLocal)==false) { r=Wym_ENOSYS; WY_HERE(r); // _alloc not overridden return(NULL); } WySockAddrLocal* p=new(std::nothrow) WySockAddrLocal(); if(p==NULL) { r=Wym_ENOMEM; WY_HERE(r); } else { r=Ok; } return(p);}catch(const Reply& e) { r=e; WY_HERE(r); return(NULL);};const WySockAddrLocal& WySockAddrLocal::operator=(const WySockAddrLocal& rhs) WY__TSPC(){ this->reset(rhs); return(*this);};const WySockAddrLocal& WySockAddrLocal::operator=(const char* rhs) WY__TSPC(WyRet){ WyRet r=this->reset(rhs); if(r!=Ok) { WY_THROW( Reply(r) ); } return(*this);};const WySockAddrLocal& WySockAddrLocal::operator=(const WyStr& rhs) WY__TSPC(WyRet){ WyRet r=this->reset(rhs); if(r!=Ok) { WY_THROW( Reply(r) ); } return(*this);};const WySockAddrLocal& WySockAddrLocal::operator=(const WyCSeg& rhs) WY__TSPC(WyRet){ WyRet r=this->reset(rhs); if(r!=Ok) { WY_THROW( Reply(r) ); } return(*this);};bool WySockAddrLocal::operator==(const WySockAddrLocal &rhs) const WY__TSPC(){ if(_slen!=rhs._slen) { return(false); }#ifdef WY_DEBUG if(_saddr.sun_family!=rhs._saddr.sun_family) { WY_TERMINATE(""); } if((_slen<DefaultSockLen)||(_slen>sizeof(struct ::sockaddr_un))) { WY_TERMINATE(""); }#endif return std::memcmp(_saddr.sun_path,rhs._saddr.sun_path,_sun_path_dlen())==0;};bool WySockAddrLocal::operator==(const char* rhs) const WY__TSPC(Reply){ if(rhs==0) { WY_THROW( Reply(Wym_EFAULT) ); } const size_t rlen( std::strlen(rhs) ); if(rlen!=this->_sun_path_dlen()) { return(false); } return(std::memcmp(_saddr.sun_path,rhs,rlen)==0);};bool WySockAddrLocal::operator==(const WyStr& rhs) const WY__TSPC(){ const socklen_t tlen=_sun_path_dlen(); if(tlen!=rhs.size()) { return(false); } return(std::memcmp(_saddr.sun_path,rhs.c_str(),tlen)==0);};bool WySockAddrLocal::operator==(const WyCSeg& rhs) const WY__TSPC(){ const socklen_t tlen=_sun_path_dlen(); if(tlen!=rhs.size()) { return(false); } return(std::memcmp(_saddr.sun_path,rhs.begin(),tlen)==0);};void WySockAddrLocal::wy_adj_slen(void){ socklen_t dlen( _sun_path_dlen() ); if(dlen<=0) { return; } if(_saddr.sun_path[0]==0) { return; } if(_saddr.sun_path[dlen-1]!=0) { WY_THROW( WyRet(Wym_EADDRNOTAVAIL) ); } _slen=SunPathZeroSize+std::strlen(_saddr.sun_path); };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -