1 #include "wvunixdgsocket.h"
7 WvUnixDGSocket::WvUnixDGSocket(WvStringParm filename
, bool _server
, int perms
)
10 // log(WvLog::Debug2, "Starting up %s!\n", filename);
16 // open a datagram unix domain socket
17 setfd(socket(PF_UNIX
, SOCK_DGRAM
, 0));
19 // if we don't have a file desciptor, something is wrong.
22 seterr("No Socket available.");
26 // set non-blocking mode
27 fcntl(getfd(), F_SETFL
, O_RDWR
|O_NONBLOCK
);
29 WvUnixAddr
uaddr(socketfile
);
31 // Let this file be reusable, since we're going to own this anyway
32 // The business with the int x is just Unix stupidities.. *sigh*
34 setsockopt(getfd(), SOL_SOCKET
, SO_REUSEADDR
, &x
, sizeof(x
));
38 // Fix it so that there can't be another process on this file
41 // Actually bind to the address we set up above.
42 sockaddr
*addr
= uaddr
.sockaddr();
43 if (bind(getfd(), (sockaddr
*)addr
, uaddr
.sockaddr_len()))
45 seterr("Bind to %s failed: %s", socketfile
, strerror(errno
));
50 chmod(socketfile
, perms
);
54 // we're the client, so we connect to someone else's socket
55 sockaddr
*addr
= uaddr
.sockaddr();
56 if (connect(getfd(), (sockaddr
*)addr
, uaddr
.sockaddr_len()))
58 seterr("Connect to %s failed: %s",
59 socketfile
, strerror(errno
));
68 WvUnixDGSocket::~WvUnixDGSocket()
70 // log(WvLog::Debug2, "Destroying: %s\n", socketfile);
76 size_t WvUnixDGSocket::uwrite(const void *buf
, size_t count
)
78 size_t ret
= bufs
.isempty() ? WvFDStream::uwrite(buf
, count
) : 0;
82 WvDynBuf
*b
= new WvDynBuf
;
91 void WvUnixDGSocket::pre_select(SelectInfo
&si
)
93 SelectRequest oldwant
= si
.wants
;
96 // stupid unix domain sockets seem to return true when selecting
97 // for write EVEN IF write() RETURNS -EAGAIN! Just shoot me.
99 // To deal with this, we set an alarm() in post_select() if we
100 // couldn't write everything we wanted. While the alarm is set,
101 // we don't try to flush our output buffer.
102 if (alarm_remaining() <= 0)
103 si
.wants
.writable
= true;
104 else if (si
.msec_timeout
< 0
105 || si
.msec_timeout
> alarm_remaining())
106 si
.msec_timeout
= alarm_remaining();
109 WvFDStream::pre_select(si
);
114 bool WvUnixDGSocket::post_select(SelectInfo
&si
)
116 SelectRequest oldwant
= si
.wants
;
118 si
.wants
.writable
= true;
120 bool sure
= WvFDStream::post_select(si
);
126 // try flushing previous bufs
127 WvBufList::Iter
i(bufs
);
128 for (i
.rewind(); i
.next(); )
130 int used
= i
->used();
131 int retval
= WvFDStream::uwrite(i
->get(used
), used
);
138 break; // can't continue
143 i
.xunlink(); // done with that one