The DejaVU Framework -- hush 3.0
[.] Papers Tutorials Examples Manuals Interfaces Sources Packages Resources ?

source: uds.c hush-3.0b4/auxiliary/net/cs


[.] - [up] [top] - index README make include source scripts configure
  // 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);
  }
  
  

[.] Papers Tutorials Examples Manuals Interfaces Sources Packages Resources ?
Hush Online Technology
hush@cs.vu.nl
09/09/98