int
Logging_Handler::handle_input (ACE_HANDLE)
{
  ssize_t n;
  size_t len;

  // Perform two recv's to emulate record-oriented semantics.  Note
  // that this code is not entirely portable since it relies on the
  // fact that sizeof (ssize_t) is the same on both the sender and
  // receiver side.  To correctly handle this is painful, and we leave
  // it as an exercise for the reader ;-).

  switch (n = this->cli_stream_.recv ((void *) &len, sizeof len))
    {
    case -1:
      ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p at host %s\n",
                         "client logger", this->host_name_), -1);
      /* NOTREACHED */
    case 0:
      ACE_ERROR_RETURN ((LM_ERROR,
                         "(%P|%t) closing log daemon at host %s (fd = %d)\n",
                         this->host_name_, this->get_handle ()), -1);
      /* NOTREACHED */
    case sizeof (size_t):
      {
        ACE_Log_Record lp;

        len = ntohl (len);
        n = this->cli_stream_.recv_n ((void *) &lp, len);
        if (n != (ssize_t) len)
          ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p at host %s\n",
                             "client logger", this->host_name_), -1);
        /* NOTREACHED */

        lp.decode ();

        if (lp.length () == n)
          {
            ACE_DEBUG ((LM_DEBUG, "(%P|%t) "));
            lp.print (this->host_name_, 1);
          }
        else
          ACE_ERROR ((LM_ERROR, "(%P|%t) error, lp.length = %d, n = %d\n",
                      lp.length (), n));
        break;
      }
    default:
      ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p at host %s\n",
                         "client logger", this->host_name_), -1);
      /* NOTREACHED */
    }

  return 0;
}
Пример #2
0
template <ACE_PEER_STREAM_1, class COUNTER, ACE_SYNCH_DECL, class LMR> int
ACE_Server_Logging_Handler_T<ACE_PEER_STREAM_2, COUNTER, ACE_SYNCH_USE, LMR>::handle_logging_record (void)
{
  ACE_INT32 length;

  // We need to use the ol' two-read trick here since TCP sockets
  // don't support framing natively.  Note that the first call is just
  // a "peek" -- we don't actually remove the data until the second
  // call.  Note that this code is portable as long as ACE_UNIT32 is
  // always 32 bits on both the sender and receiver side.

  switch (this->peer ().recv ((void *) &length,
                              sizeof length,
                              MSG_PEEK))
    {
    default:
    case -1:
      ACE_ERROR_RETURN ((LM_ERROR,
                         "%p at host %s\n",
                         "server logger",
                         this->host_name ()),
                        -1);
      /* NOTREACHED */
    case 0:
      ACE_ERROR_RETURN ((LM_ERROR,
                         "closing log daemon at host %s\n",
                         this->host_name ()),
                        -1);
      /* NOTREACHED */
    case sizeof length:
      {
        ACE_Log_Record lp;

        // Use ACE_NTOHL to get around bug in egcs 2.91.6x.
        length = ACE_NTOHL (length);

#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
        u_long count = ++this->request_count_;
#  if 0
        ACE_DEBUG ((LM_DEBUG,
                    "request count = %d, length = %d\n",
                    count,
                    length));
#  endif /* 0 */
#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */

        // Perform the actual <recv> this time.
        ssize_t n = this->peer ().recv_n ((void *) &lp,
                                          length);
        if (n != length)
          ACE_ERROR_RETURN ((LM_ERROR,
                             "%d != %d, %p at host %s\n",
                             n,
                             length,
                             "server logger",
                             this->host_name ()),
                            -1);

        lp.decode ();

        if (lp.length () == n)
          {
            // Send the log record to the log message receiver for
            // processing.
            if (ACE_BIT_ENABLED (ACE_Log_Msg::instance ()->flags (),
                                 ACE_Log_Msg::STDERR))
                receiver ().log_record (this->host_name (),
                                        lp);
            ostream *orig_ostream = ACE_Log_Msg::instance ()->msg_ostream ();
            receiver ().log_output (this->host_name (),
                                    lp,
                                    orig_ostream);
          }
        else
          ACE_ERROR ((LM_ERROR,
                      "error, lp.length = %d, n = %d\n",
                      lp.length (),
                      n));
        return n;
      }
    }

  ACE_NOTREACHED (return -1;)
}