// unixpipe.cc include <net/cs/unixaddr.h> include <net/cs/uds/socket.h> include <net/cs/uds/dataconn.h> include <net/cs/uds/listenconn.h> include <net/cs/uds/client.h> include <net/cs/uds/clientimp.h> include <net/cs/uds/server.h> include <net/cs/uds/serverimp.h> include <net/cs/samlib.h> include <errno.h> include <signal.h> include <stdio.h> include <string.h> include <unistd.h> include <sys/socket.h> include <sys/types.h> // IMPLEMENTATION NOTE: man socket states that SIGPIPE will be raised if a // process writes to a broken pipe (when the other side // has hung up). So for robustness, this signal has to // be handled. //------------------------------ unixsocket implementation ----------------- int unixsocket::_got_sigpipe = 0; int unixsocket::_handler_installed = 0; void (*unixsocket::_old_sigpipe_handler)(int) = NULL; void unixsocket::sigpipe_handler(int signr) { signal(SIGPIPE, sigpipe_handler); _got_sigpipe = 1; if (_old_sigpipe_handler != NULL) (*_old_sigpipe_handler)(signr); } unixsocket::unixsocket() { if (!_handler_installed) { _old_sigpipe_handler = signal(SIGPIPE, sigpipe_handler); _handler_installed = 1; } _name.sun_family = AF_UNIX; _name.sun_path[0] = '\0'; _pipename[0] = '\0'; _sd = -1; } void unixsocket::close() { ::close(_sd); _sd = -1; } //------------------------- unixdataconn implementation -------------------- uds_dataconn::uds_dataconn(const csaddress* addr) :unixsocket(), data_connection(addr) { unix_address* a = (unix_address*) addr; if (addr == NULL) { warn("uds_dataconn::uds_dataconn : addr = NULL"); return; } if ((_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { warn("uds_dataconn::uds_dataconn : couldn't create socket (%s)", strerror(errno)); return; } _name.sun_family = AF_UNIX; strcpy(_name.sun_path, a -> pipename()); if (connect(_fd, (struct sockaddr*) &_name, sizeof(_name)) < 0) { warn("uds_dataconn::uds_dataconn : couldn't connect (%s)", strerror(errno)); ::close(_fd); return; } // set socketdescriptor _sd = _fd; _connected = 1; } uds_dataconn::uds_dataconn(int fd) :unixsocket(), data_connection() { _fd = fd; _sd = fd; // since this constructor will be called by the receiving side of a // connection, the connection is already a fact _connected = 1; } uds_dataconn::~uds_dataconn() { close(); } int uds_dataconn::readmsg(char* buf, int nrbytes) { int retval; if (_fd < 0) { warn("uds_dataconn::readmsg : no valid filedescriptor (%d)", _fd); return -1; } if (!_connected) { warn("uds_dataconn::readmsg : connection is closed"); return -1; } retval = read_package(_fd, buf, nrbytes); if (retval < 0) _connected = 0; return retval; } int uds_dataconn::writemsg(const char* buf, int nrbytes) { int retval; if (_fd < 0) { warn("uds_dataconn::writemsg : no valid filedescriptor %d", _fd); return -1; } if (!_connected) { warn("uds_dataconn::writemsg : connection is closed"); return -1; } retval = write_package(_fd, buf, nrbytes); if (retval < 0) _connected = 0; return retval; } //-------------------------- uds_listenconn implementation ----------------- uds_listenconn::uds_listenconn(const csaddress* addr) :unixsocket(), listen_connection(addr) { unix_address* a = (unix_address*) addr; // listensocket has to have an address (pipename) if (addr == NULL) { warn("uds_listenconn::uds_listenconn : addr = NULL"); return; } // make socket connection if ((_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { warn("uds_listenconn::uds_listenconn : couldn't create socket (%s)", strerror(errno)); return; } _name.sun_family = AF_UNIX; strcpy(_name.sun_path, a -> pipename()); if (bind(_fd, (struct sockaddr*) &_name, sizeof(_name)) < 0) { warn("uds_listenconn::uds_listenconn : couldn't bind socket (%s)", strerror(errno)); ::close(_fd); return; } if (listen(_fd, 5) < 0) { warn("uds_listenconn::uds_listenconn : listen failed (%s)", strerror(errno)); ::close(_fd); return; } // set socketdescriptor _sd = _fd; _connected = 1; } uds_listenconn::~uds_listenconn() { close(); } data_connection* uds_listenconn::waitconnect() { int new_sd; data_connection* new_conn; if ((new_sd = accept(_fd, 0, 0)) < 0) return NULL; if (!(new_conn = new uds_dataconn(new_sd))) { warn("uds_listenconn::waitconnect : couldn't create new ", "data_connection"); return NULL; } return new_conn; } //------------------------ uds_client implementation --------------------- uds_client::uds_client() :csclient(_udsimp = new uds_clientimp()) { _unixaddr = NULL; } uds_client::uds_client(const char* pipename) :csclient(_udsimp = new uds_clientimp(), _unixaddr = new unix_address(pipename)) { } uds_client::~uds_client() { if (_unixaddr != NULL) delete _unixaddr; delete _udsimp; } int uds_client::connect(const char* pipename) { if (_unixaddr) delete _unixaddr; _unixaddr = new unix_address(pipename); write_to_log("uds_client::connect with %s", pipename); return csclient::connect(_unixaddr); } //------------------------ uds_server implementation --------------------- uds_server::uds_server(const char* pipename) :csserver(_udsimp = new uds_serverimp(), _unixaddr = new unix_address(pipename)) { } uds_server::~uds_server() { delete _unixaddr; delete _udsimp; } const char* uds_server::pipename() { return _unixaddr -> pipename(); } //--------------------- uds_clientimp implementation ----------------------- uds_clientimp::uds_clientimp() { } data_connection* uds_clientimp::createdata(const csaddress* addr) const { return new uds_dataconn(addr); } //------------------------- uds_serverimp ------------------------------ uds_serverimp::uds_serverimp() { } listen_connection* uds_serverimp::createlisten(const csaddress* addr) const { return new uds_listenconn(addr); }
Hush Online Technology
hush@cs.vu.nl
09/09/98 |
![]() |
![]() |