Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

wvunixsocket.cc

Go to the documentation of this file.
00001 /*
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  * 
00005  * WvStream-based Unix domain socket connection class.  See wvunixsocket.h.
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     // already connected...
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     // all is well and we're connected.  Make it non-blocking 
00055     // and close-on-exec.
00056     fcntl(getfd(), F_SETFD, 1);
00057     fcntl(getfd(), F_SETFL, O_RDWR|O_NONBLOCK);
00058 }
00059 
00060 
00061 WvUnixConn::~WvUnixConn()
00062 {
00063     // we don't want to delete the socket file here; that's a job for the
00064     // listener class.
00065     
00066     // close the socket
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     // unfortunately we have to change the umask here to make the create_mode
00089     // work, because bind() doesn't take extra arguments like open() does.
00090     // However, we don't actually want to _cancel_ the effects of umask,
00091     // only add to them; so the original umask is or'ed into ~create_mode.
00092     oldmask = umask(0777); // really just reading the old umask here
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     // delete the socket _before_ closing it.  Unix will keep
00120     // existing connections around anyway (if any), but if it's idle, then
00121     // we never have an existing not-in-use socket inode.
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 

Generated on Sun Mar 16 01:01:13 2003 for WvStreams by doxygen1.3-rc3