libt2n: (gerd) fixes, new logging concept (not working yet)
authorGerd v. Egidy <gerd.von.egidy@intra2net.com>
Wed, 18 Oct 2006 16:15:17 +0000 (16:15 +0000)
committerGerd v. Egidy <gerd.von.egidy@intra2net.com>
Wed, 18 Oct 2006 16:15:17 +0000 (16:15 +0000)
19 files changed:
src/Makefile.am
src/client.cpp
src/client.hxx
src/command.cpp
src/command.hxx
src/command_server.cpp
src/connection.cpp
src/connection.hxx
src/container.cpp
src/container.hxx
src/log.hxx [new file with mode: 0644]
src/server.cpp
src/server.hxx
src/socket_client.hxx
src/socket_handler.cpp
src/socket_handler.hxx
src/socket_server.cpp
src/socket_server.hxx
test/simplecmd.cpp

index ec5b0f7..9911bf0 100644 (file)
@@ -10,5 +10,5 @@ libt2n_la_SOURCES = server.cpp socket_server.cpp client.cpp connection.cpp \
        t2n_exception.cpp command.cpp container.cpp
 
 include_HEADERS = server.hxx socket_server.hxx t2n_exception.hxx client.hxx \
-               socket_client.hxx connection.hxx types.hxx socket_handler.hxx command.hxx container.hxx \
-       command_client.hxx command_server.hxx
+                       socket_client.hxx connection.hxx types.hxx socket_handler.hxx command.hxx container.hxx \
+               command_client.hxx command_server.hxx log.hxx
index 88a24f5..9c6e05b 100644 (file)
 namespace libt2n
 {
 
+client_connection::client_connection()
+    : connection()
+{
+    set_logging(NULL,none);
+}
+
+/// get pointer to logging stream, returns NULL if no logging needed
+std::ostream* client_connection::get_logstream(log_level_values level)
+{
+    if (logstream && level >= log_level)
+        return logstream;
+}
+
+/// activate logging to the given stream. everything above the given level is logged.
+void client_connection::set_logging(std::ostream *_logstream, log_level_values _log_level)
+{
+    log_level=_log_level;
+    logstream=_logstream;
+}
 
 };
index 293f548..91c17b9 100644 (file)
@@ -31,10 +31,16 @@ namespace libt2n
  */
 class client_connection : public connection
 {
+    private:
+        log_level_values log_level;
+        std::ostream *logstream;
+
     public:
-        client_connection()
-            : connection()
-            { }
+        client_connection();
+
+        void set_logging(std::ostream *_logstream, log_level_values _log_level);
+
+        std::ostream* get_logstream(log_level_values level);
 };
 
 }
index 59eae7c..8eba85f 100644 (file)
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
+#include <boost/archive/binary_oarchive.hpp>
+#include <boost/archive/binary_iarchive.hpp>
+#include <boost/archive/xml_oarchive.hpp>
+#include <boost/archive/xml_iarchive.hpp>
+
 #include "command.hxx"
-#include <boost/serialization/export.hpp>
 
-using namespace libt2n;
+#include <boost/serialization/export.hpp>
 
-BOOST_CLASS_EXPORT(result)
-BOOST_CLASS_EXPORT(command)
+BOOST_CLASS_EXPORT(libt2n::result)
+BOOST_CLASS_EXPORT(libt2n::command)
index ce67ebe..9d14ff4 100644 (file)
@@ -55,9 +55,7 @@ class command
         friend class boost::serialization::access;
         template<class Archive>
         void serialize(Archive & ar, const unsigned int version)
-        { 
-            std::cerr << "ser: command" << std::endl;
-        }
+        { }
 
     public:
         /// this calls the wanted target function on the server
index 15a19a7..d3721a8 100644 (file)
 #include <boost/archive/xml_oarchive.hpp>
 #include <boost/archive/xml_iarchive.hpp>
 #include <boost/serialization/serialization.hpp>
-#include <boost/serialization/export.hpp>
 
 #include "command_server.hxx"
 #include "container.hxx"
+#include "log.hxx"
 
 using namespace std;
 
@@ -39,6 +39,8 @@ namespace libt2n
 /// handle a command including deserialization and answering
 void command_server::handle_packet(const std::string& packet, server_connection* conn)
 {
+    OBJLOGSTREAM(s,debug,"handling packet from connection " << conn->get_id());
+
     // deserialize packet
     istringstream ifs(packet);
     boost::archive::binary_iarchive ia(ifs);
index a1b22a7..361cfda 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <string>
 #include <sstream>
+#include <iostream>
 
 #include "connection.hxx"
 
index 633798b..4092fde 100644 (file)
@@ -21,6 +21,9 @@
 
 #include <string>
 
+#include "types.hxx"
+
+
 namespace libt2n
 {
 
@@ -33,7 +36,7 @@ class connection
 
     protected:
         connection()
-        { closed=false; }
+            { closed=false; }
 
         std::string buffer;
 
@@ -43,6 +46,8 @@ class connection
 
         virtual void real_write(const std::string& data)=0;
 
+        virtual std::ostream* get_logstream(log_level_values level)=0;
+
     public:
         virtual ~connection()
             { close(); }
index 2973d54..c573bbe 100644 (file)
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
+#include <boost/archive/binary_oarchive.hpp>
+#include <boost/archive/binary_iarchive.hpp>
+#include <boost/archive/xml_oarchive.hpp>
+#include <boost/archive/xml_iarchive.hpp>
+
 #include "container.hxx"
 
 #include <boost/serialization/export.hpp>
 
-using namespace libt2n;
+BOOST_CLASS_EXPORT(libt2n::result_container)
+BOOST_CLASS_EXPORT(libt2n::command_container)
+
+namespace libt2n
+{
+
+template<class Archive>
+void result_container::serialize(Archive & ar, const unsigned int version)
+{
+    // When the class Archive corresponds to an output archive, the
+    // & operator is defined similar to <<.  Likewise, when the class Archive
+    // is a type of input archive the & operator is defined similar to >>.
+
+    ar & BOOST_SERIALIZATION_NVP(result_type);
+    ar & BOOST_SERIALIZATION_NVP(res);
+    ar & BOOST_SERIALIZATION_NVP(ex);
+}
+
+/// deletes the carried result or exception objects
+result_container::~result_container()
+{
+    if (res)
+        delete res;
+    if (ex)
+        delete ex;
+}
+
+/** @brief returns the result or throw the carried exception.
+            ATTENTION: the result object is deleted in the destructor
+*/
+result* result_container::get_result(void)
+{
+    if (result_type==exception)
+        ex->do_throw();
+    return res;
+}
+
+template<class Archive>
+void command_container::serialize(Archive & ar, const unsigned int version)
+{
+    ar & BOOST_SERIALIZATION_NVP(cmd);
+}
+
+/// deletes the carried command
+command_container::~command_container()
+{
+    if (cmd)
+        delete cmd;
+}
 
-BOOST_CLASS_EXPORT(result_container)
-BOOST_CLASS_EXPORT(command_container)
+} // namespace libt2n
index 8491926..2bf576b 100644 (file)
 #ifndef __LIBT2N_CONTAINER
 #define __LIBT2N_CONTAINER
 
+#include <boost/archive/binary_oarchive.hpp>
+#include <boost/archive/binary_iarchive.hpp>
+#include <boost/archive/xml_oarchive.hpp>
+#include <boost/archive/xml_iarchive.hpp>
+#include <boost/serialization/serialization.hpp>
+
 #include "command.hxx"
 #include "t2n_exception.hxx"
 
@@ -38,16 +44,8 @@ class result_container
         t2n_exception *ex;
 
         friend class boost::serialization::access;
-        // When the class Archive corresponds to an output archive, the
-        // & operator is defined similar to <<.  Likewise, when the class Archive
-        // is a type of input archive the & operator is defined similar to >>.
         template<class Archive>
-        void serialize(Archive & ar, const unsigned int version)
-        {
-            ar & BOOST_SERIALIZATION_NVP(result_type);
-            ar & BOOST_SERIALIZATION_NVP(res);
-            ar & BOOST_SERIALIZATION_NVP(ex);
-        }
+        void serialize(Archive & ar, const unsigned int version);
 
     public:
         result_container()
@@ -58,29 +56,14 @@ class result_container
         result_container(t2n_exception *_ex)
             { set_exception(_ex); }
 
+        ~result_container();
+
         void set_result(result *_res)
             { res=_res; ex=0; result_type=regular; }
         void set_exception(t2n_exception *_ex)
             { res=0; ex=_ex; result_type=exception; }
 
-        /** @brief returns the result or throw the carried exception.
-                   ATTENTION: the result object is deleted in the destructor
-        */
-        result* get_result(void)
-        {
-            if (result_type==exception)
-                ex->do_throw();
-            return res;
-        }
-
-        /// deletes the carried result or exception objects
-        ~result_container()
-        {
-            if (res)
-                delete res;
-            if (ex)
-                delete ex;
-        }
+        result* get_result(void);
 };
 
 /** @brief contains a command
@@ -92,11 +75,7 @@ class command_container
 
         friend class boost::serialization::access;
         template<class Archive>
-        void serialize(Archive & ar, const unsigned int version)
-        {
-            std::cerr << "ser: command_container" << std::endl;
-            ar & BOOST_SERIALIZATION_NVP(cmd);
-        }
+        void serialize(Archive & ar, const unsigned int version);
 
     public:
         command_container()
@@ -104,15 +83,11 @@ class command_container
         command_container(command *_cmd)
             { cmd=_cmd; }
 
+        ~command_container();
+
         /// return the contained command
         command* get_command()
             { return cmd; }
-
-        ~command_container()
-        {
-            if (cmd)
-                delete cmd;
-        }
 };
 
 } // namespace libt2n
diff --git a/src/log.hxx b/src/log.hxx
new file mode 100644 (file)
index 0000000..3c9210a
--- /dev/null
@@ -0,0 +1,61 @@
+/***************************************************************************
+ *   Copyright (C) 2006 by Gerd v. Egidy                                   *
+ *   gve@intra2net.com                                                     *
+ *                                                                         *
+ *   This library is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU Lesser General Public License version   *
+ *   2.1 as published by the Free Software Foundation.                     *
+ *                                                                         *
+ *   This library is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU Lesser General Public License for more details.                   *
+ *                                                                         *
+ *   You should have received a copy of the GNU Lesser General Public      *
+ *   License along with this program; if not, write to the                 *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+#ifndef __LIBT2N_LOG
+#define __LIBT2N_LOG
+
+#include <iostream>
+#include <sstream>
+
+#define LOGGING
+
+#ifdef LOGGING
+
+#define LOGSTREAM(level,pipe) \
+            do { \
+                std::ostream* streamptr; \
+                if ((streamptr=get_logstream(level))!=NULL) \
+                    (*streamptr) << pipe << std::endl; \
+            } while (0)
+
+#define OBJLOGSTREAM(obj,level,pipe) \
+            do { \
+                std::ostream* streamptr; \
+                if ((streamptr=obj.get_logstream(level))!=NULL) \
+                    (*streamptr) << pipe << std::endl; \
+            } while (0)
+
+#define EXCEPTIONSTREAM(loglevel,exception,pipe) \
+            do { \
+                std::ostringstream ostr; \
+                ostr << pipe; \
+                std::ostream* streamptr; \
+                if ((streamptr=get_logstream(loglevel))!=NULL) \
+                    (*streamptr) << ostr.str() << std::endl; \
+                throw exception(ostr.str()); \
+            } while (0)
+
+#else
+
+#define LOGSTREAM(level,pipe)
+#define OBJLOGSTREAM(obj,level,pipe)
+#define EXCEPTIONSTREAM(loglevel,exception,pipe)
+
+#endif
+
+#endif
index 20cce1e..14f4e2a 100644 (file)
 #include <sstream>
 
 #include "server.hxx"
+#include "log.hxx"
 
 namespace libt2n
 {
 
+server_connection::server_connection(int _timeout)
+    : connection()
+{
+    set_timeout(_timeout);
+    reset_timeout();
+    connection_id=0;
+    my_server=0;
+}
+
+
+/// get pointer to logging stream, returns NULL if no logging needed
+std::ostream* server_connection::get_logstream(log_level_values level)
+{
+    if (my_server != NULL)
+        return my_server->get_logstream(level);
+}
+
+/// check if timeout is expired, close connection if so
 void server_connection::check_timeout()
 {
-    if (timeout != -1 && last_action_time+timeout >= time(NULL))
+    if (timeout != -1 && last_action_time+timeout < time(NULL))
+    {
+        LOGSTREAM(debug,"timeout on connection " << connection_id << ", closing");
         this->close();
+    }
 }
 
+/// reset the timeout, e.g. if something is received
 void server_connection::reset_timeout()
 {
     last_action_time=time(NULL);
 }
 
+server::server()
+{
+    set_default_timeout(30);
+    set_logging(NULL,none);
+    next_id=1;
+}
+
 server::~server()
 {
     std::map<unsigned int, server_connection*>::iterator ie=connections.end();
@@ -48,9 +78,19 @@ int server::add_connection(server_connection* newconn)
     newconn->set_id(cid);
     newconn->set_server(this);
     connections[cid]=newconn;
+
+    LOGSTREAM(debug,"new connection accepted, id: " << cid);
+
     return cid;
 }
 
+/// activate logging to the given stream. everything above the given level is logged.
+void server::set_logging(std::ostream *_logstream, log_level_values _log_level)
+{
+    log_level=_log_level;
+    logstream=_logstream;
+}
+
 /**
     @brief Gets a connection by id
     
@@ -79,6 +119,8 @@ void server::cleanup()
         if (i->second->is_closed() && !i->second->packet_available())
         {
             // closed and no usable data in buffer -> remove
+            LOGSTREAM(debug,"removing conneciton " << i->first << " because it is closed and no more data waiting");
+
             delete i->second;
             connections.erase(i);
             i=connections.begin();
@@ -89,6 +131,12 @@ void server::cleanup()
     }
 }
 
+/** @brief get a complete data packet from any client. The packet is removed from the
+            connection buffer.
+    @param[out] data the data package
+    @param[out] conn_id the connection id we got this packet from
+    @retval true if packet found
+*/
 bool server::get_packet(std::string& data, unsigned int& conn_id)
 {
     // todo: this is somehow unfair: the first connections in the map get checked more
@@ -98,6 +146,8 @@ bool server::get_packet(std::string& data, unsigned int& conn_id)
     for(std::map<unsigned int, server_connection*>::iterator i=connections.begin(); i != ie; i++)
         if (i->second->get_packet(data))
         {
+            LOGSTREAM(debug,"got packet (" << data.size() << " bytes) from connection " << i->first);
+
             conn_id=i->first;
             return true;
         }
@@ -105,10 +155,10 @@ bool server::get_packet(std::string& data, unsigned int& conn_id)
     return false;
 }
 
-void server::log(log_level_values level, const char* message)
+/// get pointer to logging stream, returns NULL if no logging needed
+std::ostream* server::get_logstream(log_level_values level)
 {
     if (logstream && level >= log_level)
-        (*logstream) << message << std::endl;
+        return logstream;
 }
-
 };
index 786770f..172e98e 100644 (file)
@@ -53,24 +53,15 @@ class server_connection : public connection
             { connection_id=_connection_id; }
 
     protected:
-        server_connection(int _timeout)
-            : connection()
-        {
-            set_timeout(_timeout);
-            reset_timeout();
-            connection_id=0;
-            my_server=0;
-        }
-
         server *my_server;
 
+        server_connection(int _timeout);
+
+        std::ostream* get_logstream(log_level_values level);
+
     public:
-        /// check if timeout is expired, close connection if so
         void check_timeout();
-
-        /// reset the timeout, e.g. if something is received
         void reset_timeout();
-
         void set_timeout(int _timeout)
             { timeout=_timeout; }
 
@@ -96,12 +87,7 @@ class server
     protected:
         std::map<unsigned int, server_connection*> connections;
 
-        server()
-        {
-            set_default_timeout(30);
-            set_logging(NULL,none);
-            next_id=1;
-        }
+        server();
 
         virtual bool fill_connection_buffers(void)=0;
 
@@ -118,12 +104,7 @@ class server
         int get_default_timeout(void)
             { return default_timeout; }
 
-        /// activate logging to the given stream. everything above the given level is logged.
-        void set_logging(std::ostream *_logstream, log_level_values _log_level)
-        {
-            log_level=_log_level;
-            logstream=_logstream;
-        }
+        void set_logging(std::ostream *_logstream, log_level_values _log_level);
 
         server_connection* get_connection(unsigned int conn_id);
 
@@ -146,19 +127,9 @@ class server
         bool get_packet(std::string& data)
             { unsigned int x; return get_packet(data,x); }
 
-        /** @brief get a complete data packet from any client. The packet is removed from the
-                   connection buffer.
-            @param[out] data the data package
-            @param[out] conn_id the connection id we got this packet from
-            @retval true if packet found
-        */
         bool get_packet(std::string& data, unsigned int& conn_id);
 
-        /// write a message to the log if logging is enabled
-        void log(log_level_values level, const std::string& message)
-            { log(level,message.c_str()); }
-        /// write a message to the log if logging is enabled
-        void log(log_level_values level, const char* message);
+        std::ostream* get_logstream(log_level_values level);
 };
 
 }
index d680813..a35bbfd 100644 (file)
@@ -45,6 +45,9 @@ class socket_client_connection : public client_connection, public socket_handler
         std::string server;
         int port;
 
+        std::ostream* get_logstream(log_level_values level)
+            { return client_connection::get_logstream(level); }
+
     public:
         socket_client_connection(const std::string& _server, int _port, int _max_retries=max_retries_default);
         socket_client_connection(const std::string& _path, int _max_retries=max_retries_default);
index 2856adf..582cb0c 100644 (file)
@@ -38,6 +38,7 @@
 
 #include "socket_handler.hxx"
 #include "t2n_exception.hxx"
+#include "log.hxx"
 
 using namespace std;
 
@@ -51,59 +52,31 @@ void socket_handler::set_socket_options(int sock)
 
     /* fast reuse enable */
     if (setsockopt(sock,SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)) < 0)
-    {
-        string err="error setting socket option: ";
-        err+=strerror(errno);
-        log(error, err);
-        throw t2n_communication_error(err);
-    }
+        EXCEPTIONSTREAM(error,t2n_communication_error,"error setting socket option: " << strerror(errno));
 
     /* keepalive enable */
     if (setsockopt(sock,SOL_SOCKET, SO_KEEPALIVE, &i, sizeof(i)) < 0)
-    {
-        string err="error setting socket option: ";
-        err+=strerror(errno);
-        log(error, err);
-        throw t2n_communication_error(err);
-    }
+        EXCEPTIONSTREAM(error,t2n_communication_error,"error setting socket option: " << strerror(errno));
 
     /* close on exec */
     int fdflags;
     fdflags=fcntl(sock,F_GETFD, 0);
     if (fdflags < 0)
-    {
-        string err="fcntl error on socket: ";
-        err+=strerror(errno);
-        log(error, err);
-        throw t2n_communication_error(err);
-    }
+        EXCEPTIONSTREAM(error,t2n_communication_error,"fcntl error on socket: " << strerror(errno));
+
     fdflags |= FD_CLOEXEC;
     if (fcntl(sock,F_SETFD,fdflags) < 0)
-    {
-        string err="fcntl error on socket: ";
-        err+=strerror(errno);
-        log(error, err);
-        throw t2n_communication_error(err);
-    }
+        EXCEPTIONSTREAM(error,t2n_communication_error,"fcntl error on socket: " << strerror(errno));
 
     /* non-blocking mode */
     int flflags;
     flflags=fcntl(sock,F_GETFL,0);
     if (flflags < 0)
-    {
-        string err="fcntl error on socket: ";
-        err+=strerror(errno);
-        log(error, err);
-        throw t2n_communication_error(err);
-    }
+        EXCEPTIONSTREAM(error,t2n_communication_error,"fcntl error on socket: " << strerror(errno));
+
     flflags |= O_NONBLOCK;
     if (fcntl(sock,F_SETFL,flflags) < 0)
-    {
-        string err="fcntl error on socket: ";
-        err+=strerror(errno);
-        log(error, err);
-        throw t2n_communication_error(err);
-    }
+        EXCEPTIONSTREAM(error,t2n_communication_error,"fcntl error on socket: " << strerror(errno));
 }
 
 /// close the underlying socket connection. Don't call directly, use the version provided
@@ -189,11 +162,12 @@ bool socket_handler::fill_buffer(std::string& buffer)
         else if (errno == EINTR)
         {
             // interrupted, try again
+            LOGSTREAM(debug,"EINTR received on read(), trying again");
             try_again=true;
         }
         else
         {
-            log(error,string("error reading from socket : ")+strerror(errno));
+            LOGSTREAM(error,"error reading from socket : " << strerror(errno));
             // TODO: exception?
             return false;
         }
@@ -202,13 +176,17 @@ bool socket_handler::fill_buffer(std::string& buffer)
     // End-of-file
     if (nbytes == 0 && !try_again)
     {
+        LOGSTREAM(debug,"0 bytes received on read(), closing connection");
         close();
         return false;
     }
 
     // Data read -> store it
     if (nbytes > 0)
+    {
         buffer.assign(socket_buffer,nbytes);
+        LOGSTREAM(debug,nbytes << " read");
+    }
 
     // more data waiting -> recurse
     if (data_waiting(0))
@@ -237,22 +215,19 @@ void socket_handler::socket_write(const std::string& data)
                rtn == -1 && (errno == EAGAIN || errno == EINTR))
         {
             usleep (80000);
-            log(debug,"resuming write() call after EAGAIN or EINTR");
+            LOGSTREAM(debug,"resuming write() call after EAGAIN or EINTR");
         }
 
         if (rtn == -1)
         {
-            log(error,string("write() returned ")+strerror(errno));
+            LOGSTREAM(error,"write() returned " << strerror(errno));
             // TODO: exception?
             return;
         }
         else if (rtn != write_size)
         {
-            ostringstream msg;
-            msg << "write() wrote " << rtn << " bytes, should have been " 
-                << write_size << " (complete: " << data.size() << ")";
-
-            log(error,msg.str());
+            LOGSTREAM(error,"write() wrote " << rtn << " bytes, should have been " 
+                << write_size << " (complete: " << data.size() << ")");
 
             // TODO: exception?
             return;
@@ -261,6 +236,8 @@ void socket_handler::socket_write(const std::string& data)
         offset += write_size;
     }
 
+    LOGSTREAM(debug,"wrote " << data.size() << " bytes");
+
     return;
 }
 
index 8ea65a1..32fbbf4 100644 (file)
@@ -19,6 +19,8 @@
 #ifndef __LIBT2N_SOCKET_HANDLER
 #define __LIBT2N_SOCKET_HANDLER
 
+#include <iostream>
+
 #include "types.hxx"
 
 namespace libt2n
@@ -45,10 +47,8 @@ class socket_handler
 
         void set_socket_options(int sock);
 
-        void log(log_level_values level, const std::string& message)
-            { log(level,message.c_str()); }
-        virtual void log(log_level_values level, const char* message)
-            { return; }
+        virtual std::ostream* get_logstream(log_level_values level)
+            { return NULL; }
 
         void socket_write(const std::string& data);
 
index b807fdd..38c2ea9 100644 (file)
@@ -37,6 +37,7 @@
 
 #include "socket_server.hxx"
 #include "t2n_exception.hxx"
+#include "log.hxx"
 
 using namespace std;
 
@@ -53,12 +54,7 @@ socket_server::socket_server(int port, const std::string& ip)
     /* Create the socket. */
     sock = socket (PF_INET, SOCK_STREAM, 0);
     if (sock < 0)
-    {
-        string err="error opening socket: ";
-        err+=strerror(errno);
-        log(error, err);
-        throw t2n_server_error(err);
-    }
+        EXCEPTIONSTREAM(error,t2n_server_error,"error opening socket: " << strerror(errno));
 
     set_socket_options(sock);
 
@@ -68,20 +64,10 @@ socket_server::socket_server(int port, const std::string& ip)
     sockaddr.sin_port = htons(port);
 
     if (inet_aton(ip.c_str(),&sockaddr.sin_addr) == 0)
-    {
-        string err="failed listening on invalid ip ";
-        err+=ip;
-        log(error, err);
-        throw t2n_server_error(err);
-    }
+        EXCEPTIONSTREAM(error,t2n_server_error,"failed listening on invalid ip " << ip);
 
     if (bind (sock, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) < 0)
-    {
-        string err="error binding socket: ";
-        err+=strerror(errno);
-        log(error, err);
-        throw t2n_server_error(err);
-    }
+        EXCEPTIONSTREAM(error,t2n_server_error,"error binding socket: " << strerror(errno));
 
     start_listening();
 }
@@ -100,12 +86,7 @@ socket_server::socket_server(const std::string& path, mode_t filemode, const std
     /* Create the socket. */
     sock = socket (PF_UNIX, SOCK_STREAM, 0);
     if (sock < 0)
-    {
-        string err="error opening socket: ";
-        err+=strerror(errno);
-        log(error, err);
-        throw t2n_server_error(err);
-    }
+        EXCEPTIONSTREAM(error,t2n_server_error,"error opening socket: " << strerror(errno));
 
     set_socket_options(sock);
 
@@ -118,21 +99,11 @@ socket_server::socket_server(const std::string& path, mode_t filemode, const std
     unlink (unix_name.sun_path);
 
     if (bind (sock, (struct sockaddr *) &unix_name, sizeof (unix_name)) < 0)
-    {
-        string err="error binding socket: ";
-        err+=strerror(errno);
-        log(error, err);
-        throw t2n_server_error(err);
-    }
+        EXCEPTIONSTREAM(error,t2n_server_error,"error binding socket: " << strerror(errno));
 
     /* change permissions */
     if (chmod (unix_name.sun_path, filemode) != 0) 
-    {
-        string err="error changing permission: ";
-        err+=strerror(errno);
-        log(error, err);
-        throw t2n_server_error(err);
-    }
+        EXCEPTIONSTREAM(error,t2n_server_error,"error changing permission: " << strerror(errno));
 
     if (!user.empty() && !group.empty())
     {
@@ -140,29 +111,14 @@ socket_server::socket_server(const std::string& path, mode_t filemode, const std
 
         struct passwd *socket_user = getpwnam (user.c_str());
         if (socket_user == NULL) 
-        {
-            string err="error getting socket user: ";
-            err+=strerror(errno);
-            log(error, err);
-            throw t2n_server_error(err);
-        }
-    
+            EXCEPTIONSTREAM(error,t2n_server_error,"error getting socket user: " << strerror(errno));
+
         struct group *socket_group = getgrnam (group.c_str());
         if (socket_group == NULL) 
-        {
-            string err="error getting socket group: ";
-            err+=strerror(errno);
-            log(error, err);
-            throw t2n_server_error(err);
-        }
-    
+            EXCEPTIONSTREAM(error,t2n_server_error,"error getting socket group: " << strerror(errno));
+
         if (chown (unix_name.sun_path, socket_user->pw_uid, socket_group->gr_gid) != 0) 
-        {
-            string err="error changing socket ownership: ";
-            err+=strerror(errno);
-            log(error, err);
-            throw t2n_server_error(err);
-        }
+            EXCEPTIONSTREAM(error,t2n_server_error,"error changing socket ownership: " << strerror(errno));
     }
 
     start_listening();
@@ -180,12 +136,7 @@ socket_server::~socket_server()
 void socket_server::start_listening()
 {
     if (listen (sock, 5) < 0)
-    {
-        string err="error listening to socket: ";
-        err+=strerror(errno);
-        log(error, err);
-        throw t2n_server_error(err);
-    }
+        EXCEPTIONSTREAM(error,t2n_server_error,"error listening to socket: " << strerror(errno));
 
     /* clear & insert server sock into the fd_tab to prepare select */
     FD_ZERO(&connection_set);
@@ -203,15 +154,12 @@ void socket_server::new_connection()
     {
         if (errno == EAGAIN)
         {
-            log(error, "accept error (EAGAIN): no connection waiting");
+            LOGSTREAM(error,"accept error (EAGAIN): no connection waiting");
             return;
         }
 
         /* default: break */
-        string err="error accepting connection: ";
-        err+=strerror(errno);
-        log(error, err);
-        throw t2n_server_error(err);
+        EXCEPTIONSTREAM(error,t2n_server_error,"error accepting connection: " << strerror(errno));
     }
 
     FD_SET (newsock, &connection_set);
@@ -253,12 +201,7 @@ bool socket_server::fill_buffer(long long usec_timeout)
             ret=0;
         }
         else
-        {
-            string err="select error: ";
-            err+=strerror(errno);
-            log(error, err);
-            throw t2n_server_error(err);
-        }
+            EXCEPTIONSTREAM(error,t2n_server_error,"select error: " << strerror(errno));
     }
 
     if (ret > 0)
@@ -298,16 +241,6 @@ void socket_server::remove_connection_socket(int sock)
     FD_CLR(sock, &connection_set);
 }
 
-void socket_server_connection::log(log_level_values level, const char* message)
-{
-    if(my_server)
-    {
-        ostringstream msg;
-        msg << "connection id " << get_id() << ": " << message;
-        my_server->log(level,msg.str().c_str());
-    }
-}
-
 /// close this connection. complete data waiting in the buffer can still be retrieved.
 void socket_server_connection::close()
 {
index e3a4f34..6ebe983 100644 (file)
@@ -54,10 +54,8 @@ class socket_server : public socket_handler, public server
         void remove_connection_socket(int sock);
 
     protected:
-        void log(log_level_values level, const std::string& message)
-            { log(level,message.c_str()); }
-        void log(log_level_values level, const char* message)
-            { server::log(level,message); }
+        std::ostream* get_logstream(log_level_values level)
+            { return server::get_logstream(level); }
 
     public:
         socket_server(int port, const std::string& ip="0.0.0.0");
@@ -81,7 +79,8 @@ class socket_server_connection : public socket_handler, public server_connection
            : server_connection(_timeout), socket_handler(_sock,_stype)
            { }
 
-        void log(log_level_values level, const char* message);
+        std::ostream* get_logstream(log_level_values level)
+            { return server_connection::get_logstream(level); }
 
         void real_write(const std::string& data)
             { socket_write(data); }
index b48fab6..9c1472b 100644 (file)
 #include <cppunit/ui/text/TestRunner.h>
 #include <cppunit/extensions/HelperMacros.h>
 
+
+#include <boost/archive/binary_oarchive.hpp>
+#include <boost/archive/binary_iarchive.hpp>
+#include <boost/serialization/serialization.hpp>
+
 #include <container.hxx>
 #include <socket_client.hxx>
 #include <socket_server.hxx>
 #include <command_client.hxx>
 #include <command_server.hxx>
 
-#include <boost/serialization/serialization.hpp>
-#include <boost/serialization/level.hpp>
-#include <boost/serialization/tracking.hpp>
-#include <boost/serialization/export.hpp>
-
 using namespace std;
 using namespace libt2n;
 using namespace CppUnit;
@@ -69,6 +69,7 @@ class testfunc_res : public result
         }
 };
 
+
 class testfunc_cmd : public libt2n::command
 {
     private:
@@ -78,7 +79,6 @@ class testfunc_cmd : public libt2n::command
         template<class Archive>
         void serialize(Archive & ar, const unsigned int version)
         {
-            cerr << "ser: testfunc_cmd" << endl;
             ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::command);
             ar & BOOST_SERIALIZATION_NVP(param);
         }
@@ -98,6 +98,7 @@ class testfunc_cmd : public libt2n::command
         }
 };
 
+#include <boost/serialization/export.hpp>
 
 BOOST_CLASS_EXPORT(testfunc_cmd)
 BOOST_CLASS_EXPORT(testfunc_res)
@@ -134,7 +135,6 @@ class test_simplecmd : public TestFixture
             // child
             {
                 socket_server ss("./socket");
-                ss.set_logging(&cerr,debug);
                 command_server cs(ss);
 
                 // max 10 sec
@@ -151,6 +151,7 @@ class test_simplecmd : public TestFixture
                 // wait till server is up
                 sleep(1);
                 socket_client_connection sc("./socket");
+                sc.set_logging(&cerr,debug);
                 command_client cc(sc);
 
                 result_container rc;