You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4cxx-dev@logging.apache.org by ca...@apache.org on 2005/04/29 02:36:13 UTC

cvs commit: logging-log4cxx/src loglog.cpp socketimpl.cpp socketoutputstream.cpp telnetappender.cpp

carnold     2005/04/28 17:36:13

  Modified:    include/log4cxx/helpers socketimpl.h socketoutputstream.h
               include/log4cxx/net telnetappender.h
               src      loglog.cpp socketimpl.cpp socketoutputstream.cpp
                        telnetappender.cpp
  Log:
  LOGCXX-80: Migrate network appenders to APR
  
  Revision  Changes    Path
  1.17      +27 -14    logging-log4cxx/include/log4cxx/helpers/socketimpl.h
  
  Index: socketimpl.h
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/include/log4cxx/helpers/socketimpl.h,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- socketimpl.h	15 Dec 2004 00:38:47 -0000	1.16
  +++ socketimpl.h	29 Apr 2005 00:36:13 -0000	1.17
  @@ -21,6 +21,11 @@
   #include <log4cxx/helpers/objectptr.h>
   #include <log4cxx/helpers/inetaddress.h>
   #include <log4cxx/helpers/exception.h>
  +#include <log4cxx/helpers/pool.h>
  +
  +#include "apr_network_io.h"
  +#include "apr_lib.h"
  +
   
   namespace log4cxx
   {
  @@ -33,11 +38,23 @@
                   {
                   public:
                           SocketException();
  +                        SocketException(apr_status_t status);
                           SocketException(const SocketException&);
                           virtual ~SocketException() throw();
                           const char* what() const throw();
  +                        apr_status_t getErrorNumber() const;
  +
  +                protected:
  +                        SocketException(const char* what, apr_status_t status);
  +
                   private:
                           SocketException& operator=(const SocketException&);
  +
  +                        /** The APR error code */
  +                        apr_status_t errorNumber;
  +
  +                        /** The container for the message returned by what() */
  +                        std::string msg;
                   };
   
                   /**
  @@ -68,15 +85,14 @@
                   class LOG4CXX_EXPORT PlatformSocketException : public SocketException
                   {
                   public:
  -                        PlatformSocketException();
                           PlatformSocketException(const PlatformSocketException&);
                           virtual ~PlatformSocketException() throw();
  -                        const char* what() const throw();
  -                        long getErrorNumber() const;
  +
  +                protected:
  +                        PlatformSocketException(const char *what, apr_status_t status);
   
                   private:
                           PlatformSocketException& operator=(const PlatformSocketException&);
  -                        long errorNumber;
                   };
   
   
  @@ -88,9 +104,9 @@
                   {
                   public:
                       ConnectException();
  +                    ConnectException(apr_status_t status);
                       ConnectException(const ConnectException& src);
                       virtual ~ConnectException() throw();
  -                    const char* what() const throw();
   
                   private:
                      ConnectException& operator=(const ConnectException&);
  @@ -104,9 +120,9 @@
                   {
                   public:
                         BindException();
  +                      BindException(apr_status_t status);
                         BindException(const BindException&);
                         virtual ~BindException() throw();
  -                      const char* what() const throw();
   
                   private:
                        BindException& operator=(const BindException&);
  @@ -159,8 +175,11 @@
                           /** The IP address of the remote end of this socket. */
                           InetAddress address;
   
  -                        /** The file descriptor object for this socket. */
  -                        int fd;
  +                        /** The APR memory pool to use for this socket */
  +                        Pool memoryPool;
  +
  +                        /** The APR socket */
  +                        apr_socket_t *socket;
   
                           /** The local port number to which this socket is connected. */
                           int localport;
  @@ -169,8 +188,6 @@
                           this socket is connected. */
                           int port;
   
  -                        int timeout;
  -
                   public:
                           DECLARE_ABSTRACT_LOG4CXX_OBJECT(SocketImpl)
                           BEGIN_LOG4CXX_CAST_MAP()
  @@ -218,10 +235,6 @@
                           /** Creates either a stream or a datagram socket. */
                           void create(bool stream);
   
  -                        /** Returns the value of this socket's fd field. */
  -                        inline int getFileDescriptor() const
  -                                { return fd; }
  -
                           /** Returns the value of this socket's address field. */
                           inline InetAddress getInetAddress() const
                                   { return address; }
  
  
  
  1.14      +17 -0     logging-log4cxx/include/log4cxx/helpers/socketoutputstream.h
  
  Index: socketoutputstream.h
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/include/log4cxx/helpers/socketoutputstream.h,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- socketoutputstream.h	15 Feb 2005 23:55:59 -0000	1.13
  +++ socketoutputstream.h	29 Apr 2005 00:36:13 -0000	1.14
  @@ -47,7 +47,24 @@
                           void write(int value);
                           void write(unsigned long value);
                           void write(long value);
  +
  +                        /**
  +                         * Writes a LogString to a socket.
  +                         * The length of the string is written as the first
  +                         * two bytes to allow proper deserialization on the
  +                         * client side.
  +                         */
                           void write(const LogString& value);
  +
  +                        /**
  +                         * Writes a LogString to a socket.
  +                         * Only the contents of the String itself are written,
  +                         * no length byte is passed to the client. This is 
  +                         * usefull when the client does not need to properly
  +                         * deserialize the String, such as raw telnet clients.
  +                         */
  +                        void writeRaw(const LogString& value);
  +
                           // some write functions are missing ...
   
                           /** Close the stream and dereference the socket.
  
  
  
  1.21      +2 -1      logging-log4cxx/include/log4cxx/net/telnetappender.h
  
  Index: telnetappender.h
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/include/log4cxx/net/telnetappender.h,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- telnetappender.h	12 Mar 2005 21:00:37 -0000	1.20
  +++ telnetappender.h	29 Apr 2005 00:36:13 -0000	1.21
  @@ -65,7 +65,8 @@
                   friend class SocketHandler;
                   private:
                           log4cxx::helpers::Pool pool;
  -                        static int DEFAULT_PORT;
  +                        static const int DEFAULT_PORT;
  +                        static const int MAX_CONNECTIONS;
                           int port;
   
                   public:
  
  
  
  1.13      +3 -3      logging-log4cxx/src/loglog.cpp
  
  Index: loglog.cpp
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/src/loglog.cpp,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- loglog.cpp	11 Apr 2005 04:36:34 -0000	1.12
  +++ loglog.cpp	29 Apr 2005 00:36:13 -0000	1.13
  @@ -78,16 +78,16 @@
   
   
   void LogLog::emit(const std::string& msg) {
  -    std::cerr << msg << std::endl;
  +    std::cerr << "log4cxx: " << msg << std::endl;
   }
   
   #if LOG4CXX_HAS_WCHAR_T
   void LogLog::emit(const std::wstring& msg) {
   #if LOG4CXX_HAS_STD_WCOUT
  -    std::wcerr << msg << std::endl;
  +    std::wcerr << "log4cxx: " << msg << std::endl;
   #else
       LOG4CXX_ENCODE_CHAR(encoded, msg);
  -    std::err << encoded << std::endl;
  +    std::err << "log4cxx: " << encoded << std::endl;
   #endif
   }
   #endif
  
  
  
  1.23      +162 -179  logging-log4cxx/src/socketimpl.cpp
  
  Index: socketimpl.cpp
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/src/socketimpl.cpp,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- socketimpl.cpp	15 Feb 2005 23:56:01 -0000	1.22
  +++ socketimpl.cpp	29 Apr 2005 00:36:13 -0000	1.23
  @@ -15,25 +15,11 @@
   
   #include <log4cxx/portability.h>
   
  -#if defined(WIN32) || defined(_WIN32)
  -#include <windows.h>
  -#include <winsock.h>
  -#else
  -#include <sys/types.h>
  -#include <sys/socket.h>
  -#include <netinet/in.h>
  -#include <arpa/inet.h>
  -#include <unistd.h>
  -#include <netdb.h>
  -#include <sys/time.h>
  -#include <sys/types.h>
  -#endif
  -
   #include <log4cxx/helpers/socketimpl.h>
   #include <log4cxx/helpers/loglog.h>
  -#include <errno.h>
   #include <log4cxx/helpers/stringhelper.h>
   #include <log4cxx/helpers/pool.h>
  +#include <log4cxx/helpers/transcoder.h>
   
   using namespace log4cxx;
   using namespace log4cxx::helpers;
  @@ -43,65 +29,63 @@
   #include <string.h>
   #include <assert.h>
   
  +#include <apr_support.h>
  +#include <apr_signal.h>
   
   
  +SocketException::SocketException() : errorNumber(0), msg("SocketException") {
  +}
   
  -#if defined(WIN32) || defined(_WIN32)
  -namespace {
  -    class WinSockInitializer {
  -    public:
  -        WinSockInitializer() {
  -            WSAStartup(MAKEWORD(1, 1), &wsa);
  -        }
  -        ~WinSockInitializer() {
  -            WSACleanup();
  -        }
  -
  -        WSADATA wsa;
  -    } winSockInitializer;
  +SocketException::SocketException(const char *what, apr_status_t status) :
  +  errorNumber(status) {
   
  +  // build the error message text
  +  char buffer[200];
  +  apr_strerror(status, buffer, sizeof buffer);
  +  msg = std::string(what) + std::string(": ") + buffer;
   }
  -#endif
   
  -SocketException::SocketException() {
  +SocketException::SocketException(apr_status_t status) :
  +  errorNumber(status) {
  +
  +  // build the error message text
  +  char buffer[200];
  +  apr_strerror(status, buffer, sizeof buffer);
  +  msg = std::string("SocketException: ") + buffer;
   }
   
   SocketException::SocketException(const SocketException& src)
  -   : IOException(src) {
  +   : IOException(src), errorNumber(src.getErrorNumber()) {
   }
   
  -
   SocketException::~SocketException() throw() {
   }
   
   const char* SocketException::what() const throw() {
  -  return "SocketException";
  +   return msg.c_str();
   }
   
  -
  -PlatformSocketException::PlatformSocketException() {
  -   errorNumber = errno;
  +apr_status_t SocketException::getErrorNumber() const {
  +  return errorNumber;
   }
   
  -PlatformSocketException::PlatformSocketException(const PlatformSocketException& src)
  -   : SocketException(src), errorNumber(src.getErrorNumber()) {
  +PlatformSocketException::PlatformSocketException(const char* what, apr_status_t status) :
  +   SocketException(what, status) {
   }
   
  -long PlatformSocketException::getErrorNumber() const {
  -  return errorNumber;
  +PlatformSocketException::PlatformSocketException(const PlatformSocketException& src)
  +   : SocketException(src) {
   }
   
   PlatformSocketException::~PlatformSocketException() throw() {
   }
   
  -
  -const char* PlatformSocketException::what() const throw() {
  -   return "Socket exception";
  +ConnectException::ConnectException()
  +    : PlatformSocketException("ConnectException", 0) {
   }
   
  -
  -
  -ConnectException::ConnectException() {
  +ConnectException::ConnectException(apr_status_t status) 
  +   : PlatformSocketException("ConnectException", status) {
   }
   
   ConnectException::ConnectException(const ConnectException& src)
  @@ -111,12 +95,12 @@
   ConnectException::~ConnectException() throw() {
   }
   
  -
  -const char* ConnectException::what() const throw() {
  -   return "Connect exception";
  +BindException::BindException()
  +    : PlatformSocketException("BindException", 0) {
   }
   
  -BindException::BindException() {
  +BindException::BindException(apr_status_t status) 
  +   : PlatformSocketException("BindException", status) {
   }
   
   BindException::BindException(const BindException& src)
  @@ -126,12 +110,6 @@
   BindException::~BindException() throw() {
   }
   
  -
  -const char* BindException::what() const throw() {
  -   return "Bind exception";
  -}
  -
  -
   InterruptedIOException::InterruptedIOException() {
   }
   
  @@ -163,9 +141,7 @@
   }
   
   
  -
  -
  -SocketImpl::SocketImpl() : address(), fd(0), localport(-1), port(0), timeout(-1)
  +SocketImpl::SocketImpl() : address(), socket(0), localport(-1), port(0)
   {
   }
   
  @@ -183,45 +159,35 @@
   /** Accepts a connection. */
   void SocketImpl::accept(SocketImplPtr s)
   {
  -        sockaddr_in client_addr;
  -#if defined(WIN32) || defined(_WIN32) || defined(__hpux)
  -        int client_len;
  -#else
  -        socklen_t client_len;
  -#endif
  -
  -        client_len = sizeof(client_addr);
  -
  -        if (timeout > 0)
  -        {
  -                // convert timeout in milliseconds to struct timeval
  -                timeval tv;
  -                tv.tv_sec = timeout / 1000;
  -                tv.tv_usec = (timeout % 1000) * 1000;
  -
  -                fd_set rfds;
  -                FD_ZERO(&rfds);
  -                FD_SET(this->fd, &rfds);
  -
  -                int retval = ::select(this->fd+1, &rfds, NULL, NULL, &tv);
  -                if (retval == 0)
  -                {
  -                        throw SocketTimeoutException();
  -                }
  -
  -                assert(FD_ISSET(this->fd, &rfds));
  -        }
  -
  -        int fdClient = ::accept(this->fd, (sockaddr *)&client_addr, &client_len);
  -
  -        if (fdClient < 0)
  -        {
  -                throw SocketException();
  -        }
  -
  -        s->address.address = ntohl(client_addr.sin_addr.s_addr);
  -        s->fd = fdClient;
  -        s->port = ntohs(client_addr.sin_port);
  +      // If a timeout is set then wait at most for the specified timeout
  +      if (getSoTimeout() > 0) {
  +        apr_status_t status = apr_wait_for_io_or_timeout(NULL, socket, 0);
  +        if (status == APR_TIMEUP) {
  +          throw SocketTimeoutException();
  +        }
  +        if (status != APR_SUCCESS) {
  +          throw SocketException(status);
  +        }
  +      }
  +
  +      // Accept new connection
  +      apr_socket_t *clientSocket = 0;
  +      apr_status_t status = 
  +          apr_socket_accept(&clientSocket, socket, (apr_pool_t*) memoryPool.getAPRPool());
  +      if (status != APR_SUCCESS) {
  +        throw SocketException(status);
  +      }
  +
  +      // get client socket address
  +      apr_sockaddr_t *client_addr;
  +      status = apr_socket_addr_get(&client_addr, APR_REMOTE, clientSocket);
  +      if (status != APR_SUCCESS) {
  +        throw SocketException(status);
  +      }
  +
  +      s->address.address =  *((int*) client_addr->ipaddr_ptr);
  +      s->socket = clientSocket;
  +      s->port = client_addr->port;
   }
   
   /** Returns the number of bytes that can be read from this socket
  @@ -236,18 +202,23 @@
   /** Binds this socket to the specified port number
   on the specified host.
   */
  -void SocketImpl::bind(InetAddress host, int port)
  +void SocketImpl::bind(InetAddress address, int port)
   {
  -        struct sockaddr_in server_addr;
  -        int server_len = sizeof(server_addr);
  -
  -        server_addr.sin_family = AF_INET;
  -        server_addr.sin_addr.s_addr = htonl(host.address);
  -        server_addr.sin_port = htons(port);
  +        LOG4CXX_ENCODE_CHAR(host, address.getHostAddress());
   
  -        if (::bind(fd, (sockaddr *)&server_addr, server_len) == -1)
  -        {
  -                throw BindException();
  +        // Create server socket address
  +        apr_sockaddr_t *server_addr;
  +        apr_status_t status = 
  +            apr_sockaddr_info_get(&server_addr, host.c_str(), APR_INET,
  +                                  port, 0, (apr_pool_t*) memoryPool.getAPRPool());
  +        if (status != APR_SUCCESS) {
  +          throw ConnectException(status);
  +        }
  +
  +        // bind the socket to the address
  +        status = apr_socket_bind(socket, server_addr);
  +        if (status != APR_SUCCESS) {
  +          throw BindException(status);
           }
   
           this->localport = port;
  @@ -256,22 +227,17 @@
   /** Closes this socket. */
   void SocketImpl::close()
   {
  -        if (fd != 0)
  -        {
  -                LOGLOG_DEBUG(LOG4CXX_STR("closing socket"));
  -#if defined(WIN32) || defined(_WIN32)
  -                if (::closesocket(fd) == -1)
  -#else
  -                if (::close(fd) == -1)
  -#endif
  -                {
  -                        throw SocketException();
  -                }
  -
  -                address.address = 0;
  -                fd = 0;
  -                port = 0;
  -                localport = -1;
  +        if (socket != 0) {
  +          LOGLOG_DEBUG(LOG4CXX_STR("closing socket"));
  +          apr_status_t status = apr_socket_close(socket);
  +          if (status != APR_SUCCESS) {
  +            throw SocketException(status);
  +          }
  +
  +          address.address = 0;
  +          socket = 0;
  +          port = 0;
  +          localport = -1;
           }
   }
   
  @@ -280,16 +246,21 @@
   */
   void SocketImpl::connect(InetAddress address, int port)
   {
  -        sockaddr_in client_addr;
  -        int client_len = sizeof(client_addr);
  +        LOG4CXX_ENCODE_CHAR(host, address.getHostAddress());
   
  -        client_addr.sin_family = AF_INET;
  -        client_addr.sin_addr.s_addr = htonl(address.address);
  -        client_addr.sin_port = htons(port);
  +        // create socket address
  +        apr_sockaddr_t *client_addr;
  +        apr_status_t status = 
  +            apr_sockaddr_info_get(&client_addr, host.c_str(), APR_INET,
  +                                  port, 0, (apr_pool_t*) memoryPool.getAPRPool());
  +        if (status != APR_SUCCESS) {
  +          throw ConnectException(status);
  +        }
   
  -        if (::connect(fd, (sockaddr *)&client_addr, client_len) == -1)
  -        {
  -                throw ConnectException();
  +        // connect the socket
  +        status =  apr_socket_connect(socket, client_addr);
  +        if (status != APR_SUCCESS) {
  +          throw ConnectException();
           }
   
           this->address = address;
  @@ -305,10 +276,12 @@
   /** Creates either a stream or a datagram socket. */
   void SocketImpl::create(bool stream)
   {
  -        if ((fd = ::socket(AF_INET, stream ? SOCK_STREAM : SOCK_DGRAM, 0)) == -1)
  -        {
  -                throw SocketException();
  -        }
  +  apr_status_t status =
  +    apr_socket_create(&socket, APR_INET, stream ? SOCK_STREAM : SOCK_DGRAM, 
  +                      APR_PROTO_TCP, (apr_pool_t*) memoryPool.getAPRPool());
  +  if (status != APR_SUCCESS) {
  +    throw SocketException(status);
  +  }
   }
   
   /** Sets the maximum queue length for incoming connection
  @@ -316,10 +289,11 @@
   */
   void SocketImpl::listen(int backlog)
   {
  -        if (::listen(fd, backlog) == -1)
  -        {
  -                throw SocketException();
  -        }
  +
  +  apr_status_t status = apr_socket_listen (socket, backlog);
  +  if (status != APR_SUCCESS) {
  +    throw SocketException(status);
  +  }
   }
   
   /** Returns the address and port of this socket as a String.
  @@ -336,70 +310,79 @@
   // thanks to Yves Mettier (ymettier@libertysurf.fr) for this routine
   size_t SocketImpl::read(void * buf, size_t len) const
   {
  +
   // LOGLOG_DEBUG(LOG4CXX_STR("SocketImpl::reading ") << len << LOG4CXX_STR(" bytes."));
  -        int len_read = 0;
  -        unsigned char * p = (unsigned char *)buf;
  +        char * p = (char *)buf;
   
  -        while ((size_t)(p - (unsigned char *)buf) < len)
  +        while ((size_t)(p - (char *)buf) < len)
           {
  -#if defined(WIN32) || defined(_WIN32)
  -                len_read = ::recv(fd, (char *)p, len - (p - (unsigned char *)buf), 0);
  -#else
  -                len_read = ::read(fd, p, len - (p - (unsigned char *)buf));
  -#endif
  -                if (len_read < 0)
  -                {
  -                        throw SocketException();
  -                }
  -                if (len_read == 0)
  -                {
  -                        break;
  -                }
  -                p += len_read;
  +          apr_size_t len_read = len - (p - (const char *)buf);
  +          apr_status_t status = apr_socket_recv(socket, p, &len_read);
  +          if (status != APR_SUCCESS) {
  +            throw SocketException(status);
  +          }
  +          if (len_read == 0) {
  +            break;
  +          }
  +
  +          p += len_read;
           }
   
  -        return (p - (const unsigned char *)buf);
  +        return (p - (const char *)buf);
   }
   
   // thanks to Yves Mettier (ymettier@libertysurf.fr) for this routine
   size_t SocketImpl::write(const void * buf, size_t len)
   {
  -// LOGLOG_DEBUG(LOG4CXX_STR("SocketImpl::writing ") << len << LOG4CXX_STR(" bytes."));
  +// LOGLOG_DEBUG(LOG4CXX_STR("SocketImpl::write ") << len << LOG4CXX_STR(" bytes."));
   
  -        int len_written = 0;
  -        const unsigned char * p = (const unsigned char *)buf;
  +        const char * p = (const char *)buf;
   
  -        while ((size_t)(p - (const unsigned char *)buf) < len)
  +        while ((size_t)(p - (const char *)buf) < len)
           {
  -#if defined(WIN32) || defined(_WIN32)
  -                len_written = ::send(fd, (const char *)p, len - (p - (const unsigned char *)buf), 0);
  -#else
  -                len_written = ::write(fd, p, len - (p - (const unsigned char *)buf));
  -#endif
  -                if (len_written < 0)
  -                {
  -                        throw SocketException();
  -                }
  -                if (len_written == 0)
  -                {
  -                        break;
  -                }
  -                p += len_written;
  +          apr_size_t len_written = len - (p - (const char *)buf);
  +
  +          // while writing to the socket, we need to ignore the SIGPIPE
  +          // signal. Otherwise, when the client has closed the connection,
  +          // the send() function would not return an error but call the
  +          // SIGPIPE handler.
  +          apr_sigfunc_t* old = apr_signal(SIGPIPE, SIG_IGN);
  +          apr_status_t status = apr_socket_send(socket, p, &len_written);
  +          apr_signal(SIGPIPE, old);
  +
  +          if (status != APR_SUCCESS) {
  +            throw SocketException(status);
  +          }
  +          if (len_written == 0) {
  +            break;
  +          }
  +
  +          p += len_written;
           }
   
  -        return (p - (const unsigned char *)buf);
  +        return (p - (const char *)buf);
   }
   
   /** Retrive setting for SO_TIMEOUT.
   */
   int SocketImpl::getSoTimeout() const
   {
  -        return timeout;
  +  apr_interval_time_t timeout;
  +  apr_status_t status = apr_socket_timeout_get(socket, &timeout);
  +  if (status != APR_SUCCESS) {
  +    throw SocketException(status);
  +  }
  +
  +  return timeout / 1000;
   }
   
   /** Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds.
   */
   void SocketImpl::setSoTimeout(int timeout)
   {
  -        this->timeout = timeout;
  +  apr_interval_time_t time = timeout * 1000;
  +  apr_status_t status = apr_socket_timeout_set(socket, time);
  +  if (status != APR_SUCCESS) {
  +    throw SocketException(status);
  +  }
   }
  
  
  
  1.9       +21 -5     logging-log4cxx/src/socketoutputstream.cpp
  
  Index: socketoutputstream.cpp
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/src/socketoutputstream.cpp,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- socketoutputstream.cpp	15 Feb 2005 23:56:01 -0000	1.8
  +++ socketoutputstream.cpp	29 Apr 2005 00:36:13 -0000	1.9
  @@ -91,18 +91,34 @@
      LogString::size_type size;
   
      size = value.size();
  +   if (size > 1024)
  +   {
  +     size = 1024;
  +   }
  +
      write(&size, sizeof(LogString::size_type));
      if (size > 0)
      {
  -      if (size > 1024)
  -      {
  -         size = 1024;
  -      }
  -
         write(value.c_str(), size * sizeof(logchar));
      }
   }
   
  +void SocketOutputStream::writeRaw(const LogString& value)
  +{
  +  LogString::size_type size;
  +
  +  size = value.size();
  +  if (size > 0)
  +  {
  +    if (size > 1024)
  +    {
  +      size = 1024;
  +    }
  +
  +    write(value.c_str(), size * sizeof(logchar));
  +  }
  +}
  +
   void SocketOutputStream::close()
   {
      // force flushing
  
  
  
  1.20      +23 -22    logging-log4cxx/src/telnetappender.cpp
  
  Index: telnetappender.cpp
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/src/telnetappender.cpp,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- telnetappender.cpp	11 Apr 2005 04:36:35 -0000	1.19
  +++ telnetappender.cpp	29 Apr 2005 00:36:13 -0000	1.20
  @@ -32,15 +32,15 @@
   
   IMPLEMENT_LOG4CXX_OBJECT(TelnetAppender)
   
  -int TelnetAppender::DEFAULT_PORT = 23;
  +/** The default telnet server port */
  +const int TelnetAppender::DEFAULT_PORT = 23;
   
  +/** The maximum number of concurrent connections */
  +const int TelnetAppender::MAX_CONNECTIONS = 20;
   
   TelnetAppender::TelnetAppender()
  -   : port(23),
  -         connections(20),
  -         serverSocket(NULL),
  -     sh(),
  -         activeConnections(0)
  +  : port(DEFAULT_PORT), connections(MAX_CONNECTIONS),
  +    serverSocket(NULL), sh(), activeConnections(0)
   {
   }
   
  @@ -128,7 +128,7 @@
                            iter++) {
                           if (iter->first != NULL) {
                                   try {
  -                                        iter->second->write(os);
  +                                        iter->second->writeRaw(os);
                                           iter->second->flush();
                                   } catch(Exception& ex) {
                                           // The client has closed the connection, remove it from our list:
  @@ -141,34 +141,30 @@
           }
   }
   
  -
   void* APR_THREAD_FUNC TelnetAppender::acceptConnections(log4cxx_thread_t* thread, void* data) {
  -        TelnetAppender* pThis = (TelnetAppender*) data;
  +    TelnetAppender* pThis = (TelnetAppender*) data;
   
  +    // main loop; is left when This->closed is != 0 after an accept()
  +    while(true)
  +    {
           try
           {
                   SocketPtr newClient = pThis->serverSocket->accept();
                   SocketOutputStreamPtr os = newClient->getOutputStream();
                   apr_uint32_t done = apr_atomic_read32(&pThis->closed);
                   if (done) {
  -                        os->write(LOG4CXX_STR("Log closed.\r\n"));
  +                        os->writeRaw(LOG4CXX_STR("Log closed.\r\n"));
                           os->flush();
                           newClient->close();
                           return NULL;
                   }
   
                   apr_uint32_t count = apr_atomic_read32(&pThis->activeConnections);
  -                if (count > pThis->connections.size()) {
  -                        os->write(LOG4CXX_STR("Too many connections.\r\n"));
  +                if (count >= pThis->connections.size()) {
  +                        os->writeRaw(LOG4CXX_STR("Too many connections.\r\n"));
                           os->flush();
                           newClient->close();
                   } else {
  -                        LogString oss(LOG4CXX_STR("TelnetAppender v1.0 ("));
  -                        oss += StringHelper::toString((int) count, pThis->pool);
  -                        oss += LOG4CXX_STR(" active connections)\r\n\r\n");
  -                        os->write(oss);
  -                        os->flush();
  -
                           //
                           //   find unoccupied connection
                           //
  @@ -183,14 +179,19 @@
                                           break;
                                   }
                           }
  +
  +                        LogString oss(LOG4CXX_STR("TelnetAppender v1.0 ("));
  +                        oss += StringHelper::toString((int) count+1, pThis->pool);
  +                        oss += LOG4CXX_STR(" active connections)\r\n\r\n");
  +                        os->writeRaw(oss);
  +                        os->flush();
                   }
           } catch(Exception& e) {
                   LogLog::error(LOG4CXX_STR("Encountered error while in SocketHandler loop."), e);
           }
  -        return NULL;
  +    }
  +
  +    return NULL;
   }
   
   #endif
  -
  -
  -