00001
00002
00003
00004
00005
00006
00007 #include "wvstreamlist.h"
00008 #include "wvunixsocket.h"
00009
00010 #ifdef ISBSD
00011 #include <netinet/in_systm.h>
00012 #endif
00013
00014 #include <fcntl.h>
00015 #include <sys/socket.h>
00016 #include <sys/stat.h>
00017 #include <sys/types.h>
00018 #include <sys/un.h>
00019 #include <netinet/in.h>
00020 #include <netinet/ip.h>
00021 #include <netinet/tcp.h>
00022 #include <errno.h>
00023
00024
00025 WvUnixConn::WvUnixConn(int _fd, const WvUnixAddr &_addr)
00026 : WvStream(_fd), addr(_addr)
00027 {
00028
00029 }
00030
00031
00032 WvUnixConn::WvUnixConn(const WvUnixAddr &_addr)
00033 : addr(_addr)
00034 {
00035 sockaddr *sa;
00036
00037 rwfd = socket(PF_UNIX, SOCK_STREAM, 0);
00038 if (rwfd < 0)
00039 {
00040 seterr(errno);
00041 return;
00042 }
00043
00044 sa = addr.sockaddr();
00045 if (connect(getfd(), sa, addr.sockaddr_len()) < 0)
00046 {
00047 seterr(errno);
00048 delete sa;
00049 return;
00050 }
00051
00052 delete sa;
00053
00054
00055
00056 fcntl(getfd(), F_SETFD, 1);
00057 fcntl(getfd(), F_SETFL, O_RDWR|O_NONBLOCK);
00058 }
00059
00060
00061 WvUnixConn::~WvUnixConn()
00062 {
00063
00064
00065
00066
00067 close();
00068 }
00069
00070
00071 const WvUnixAddr *WvUnixConn::src() const
00072 {
00073 return &addr;
00074 }
00075
00076
00077 WvUnixListener::WvUnixListener(const WvUnixAddr &_addr, int create_mode)
00078 : addr(_addr), auto_callback(NULL)
00079 {
00080 mode_t oldmask;
00081
00082 auto_list = NULL;
00083 auto_userdata = NULL;
00084 bound_okay = false;
00085
00086 sockaddr *sa = addr.sockaddr();
00087
00088
00089
00090
00091
00092 oldmask = umask(0777);
00093 umask(oldmask | ((~create_mode) & 0777));
00094
00095 rwfd = socket(PF_UNIX, SOCK_STREAM, 0);
00096 if (rwfd < 0
00097 || fcntl(getfd(), F_SETFD, 1)
00098 || bind(getfd(), sa, addr.sockaddr_len())
00099 || listen(getfd(), 5))
00100 {
00101 seterr(errno);
00102 }
00103 else
00104 bound_okay = true;
00105
00106 delete sa;
00107 umask(oldmask);
00108 }
00109
00110
00111 WvUnixListener::~WvUnixListener()
00112 {
00113 close();
00114 }
00115
00116
00117 void WvUnixListener::close()
00118 {
00119
00120
00121
00122 if (bound_okay)
00123 {
00124 WvString filename(addr);
00125 ::unlink(filename);
00126 }
00127
00128 WvStream::close();
00129 }
00130
00131
00132 WvUnixConn *WvUnixListener::accept()
00133 {
00134 struct sockaddr_un sun;
00135 socklen_t len = sizeof(sun);
00136 int newfd;
00137 WvUnixConn *ret;
00138
00139 newfd = ::accept(getfd(), (struct sockaddr *)&sun, &len);
00140 ret = new WvUnixConn(newfd, addr);
00141 return ret;
00142 }
00143
00144
00145 void WvUnixListener::auto_accept(WvStreamList *list,
00146 WvStreamCallback callfunc, void *userdata)
00147 {
00148 auto_list = list;
00149 auto_callback = callfunc;
00150 auto_userdata = userdata;
00151 setcallback(accept_callback, this);
00152 }
00153
00154
00155 void WvUnixListener::accept_callback(WvStream &, void *userdata)
00156 {
00157 WvUnixListener &l = *(WvUnixListener *)userdata;
00158
00159 WvUnixConn *connection = l.accept();
00160 connection->setcallback(l.auto_callback, l.auto_userdata);
00161 l.auto_list->append(connection, true);
00162 }
00163
00164
00165 size_t WvUnixListener::uread(void *, size_t)
00166 {
00167 return 0;
00168 }
00169
00170
00171 size_t WvUnixListener::uwrite(const void *, size_t)
00172 {
00173 return 0;
00174 }
00175
00176
00177 const WvUnixAddr *WvUnixListener::src() const
00178 {
00179 return &addr;
00180 }
00181