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