1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
|
#include "socketserver.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
#include <errno.h>
#include <iostream>
using std::endl;
using std::cerr;
static gboolean incoming_connection(GIOChannel *source,
GIOCondition condition, gpointer data)
{
SocketServer *ss = (SocketServer*)data;
ss->_connection_established();
return true;
}
SocketServer::SocketServer(const string &sockpath)
{
int fd = socket(PF_UNIX, SOCK_STREAM, 0);
if (fd < 0)
{
cerr << "Could not create a socket: " << strerror(errno) << endl;
exit(3);
}
struct sockaddr_un sun;
sun.sun_family = AF_UNIX;
strncpy(sun.sun_path, sockpath.c_str(), sizeof(sun.sun_path));
unlink(sockpath.c_str());
if (bind(fd, (sockaddr*)&sun, sizeof(sun)))
{
cerr << "Could not bind socket: " << strerror(errno) << endl;
exit(4);
}
if (listen(fd, 5))
{
cerr << "Could not listen: " << strerror(errno) << endl;
exit(5);
}
listener = g_io_channel_unix_new(fd);
g_io_add_watch(listener, (GIOCondition)(G_IO_IN | G_IO_PRI),
::incoming_connection, this);
}
SocketServer::~SocketServer()
{
if (listener)
{
g_io_channel_close(listener);
g_io_channel_unref(listener);
listener = 0;
}
}
void SocketServer::_connection_established()
{
struct sockaddr_un sun;
memset(&sun, 0, sizeof(sun));
socklen_t size = 0;
int fd = accept(g_io_channel_unix_get_fd(listener),
(sockaddr*)&sun, &size);
init(fd);
#ifdef DEBUG
cerr << "Incoming connection!" << endl;
#endif
connection_established();
}
|