Log_Msg.cpp

Go to the documentation of this file.
00001 // $Id: Log_Msg.cpp 79334 2007-08-14 08:46:38Z johnnyw $
00002 
00003 // We need this to get the status of ACE_NTRACE...
00004 #include "ace/config-all.h"
00005 
00006 // Turn off tracing for the duration of this file.
00007 #if defined (ACE_NTRACE)
00008 # undef ACE_NTRACE
00009 #endif /* ACE_NTRACE */
00010 #define ACE_NTRACE 1
00011 
00012 #include "ace/ACE.h"
00013 #include "ace/Thread_Manager.h"
00014 #include "ace/Guard_T.h"
00015 #include "ace/OS_NS_stdio.h"
00016 #include "ace/OS_NS_string.h"
00017 #include "ace/OS_NS_errno.h"
00018 #include "ace/OS_NS_sys_time.h"
00019 #include "ace/OS_NS_wchar.h"
00020 #include "ace/OS_NS_signal.h"
00021 #include "ace/OS_NS_unistd.h"
00022 
00023 #if !defined (ACE_MT_SAFE) || (ACE_MT_SAFE != 0)
00024 # include "ace/Object_Manager_Base.h"
00025 #endif /* ! ACE_MT_SAFE */
00026 
00027 #if !defined (ACE_LACKS_IOSTREAM_TOTALLY)
00028 // FUZZ: disable check_for_streams_include
00029 # include "ace/streams.h"
00030 #endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */
00031 
00032 #if defined (ACE_HAS_TRACE)
00033 # include "ace/Trace.h"
00034 #endif /* ACE_HAS_TRACE */
00035 
00036 #include "ace/Log_Msg.h"
00037 #include "ace/Log_Msg_Callback.h"
00038 #include "ace/Log_Msg_IPC.h"
00039 #include "ace/Log_Msg_NT_Event_Log.h"
00040 #include "ace/Log_Msg_UNIX_Syslog.h"
00041 #include "ace/Log_Record.h"
00042 #include "ace/Recursive_Thread_Mutex.h"
00043 
00044 ACE_RCSID(ace, Log_Msg, "$Id: Log_Msg.cpp 79334 2007-08-14 08:46:38Z johnnyw $")
00045 
00046 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00047 
00048 ACE_ALLOC_HOOK_DEFINE(ACE_Log_Msg)
00049 
00050 // only used here...  dhinton
00051 #if defined (ACE_HAS_SYS_SIGLIST)
00052 # if !defined (_sys_siglist)
00053 #   define _sys_siglist sys_siglist
00054 # endif /* !defined (sys_siglist) */
00055 //extern char **_sys_siglist;
00056 #endif /* ACE_HAS_SYS_SIGLIST */
00057 
00058 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00059   int ACE_Log_Msg::key_created_ = 0;
00060 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \
00061     defined (ACE_HAS_TSS_EMULATION)
00062 
00063 #if defined (ACE_MVS)
00064   static ACE_thread_key_t the_log_msg_tss_key =
00065   #if !defined(_LP64)
00066       { '\0','\0','\0','\0' };
00067   #else
00068       { '\0','\0','\0','\0','\0','\0','\0','\0' };
00069   #endif
00070 #else
00071   static ACE_thread_key_t the_log_msg_tss_key = 0;
00072 #endif /* defined (ACE_MVS) */
00073 
00074 ACE_thread_key_t *log_msg_tss_key (void)
00075 {
00076   return &the_log_msg_tss_key;
00077 }
00078 
00079 # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */
00080 #else
00081 static ACE_Cleanup_Adapter<ACE_Log_Msg>* log_msg_cleanup = 0;
00082 class ACE_Msg_Log_Cleanup: public ACE_Cleanup_Adapter<ACE_Log_Msg>
00083 {
00084 public:
00085   virtual ~ACE_Msg_Log_Cleanup (void) {
00086     if (this == log_msg_cleanup)
00087       log_msg_cleanup = 0;
00088   }
00089 };
00090 #endif /* ACE_MT_SAFE */
00091 
00092 #if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE) && !defined (ACE_HAS_PHARLAP)
00093 #  define ACE_LOG_MSG_SYSLOG_BACKEND ACE_Log_Msg_NT_Event_Log
00094 #elif !defined (ACE_LACKS_UNIX_SYSLOG) && !defined (ACE_HAS_WINCE)
00095 #  define ACE_LOG_MSG_SYSLOG_BACKEND ACE_Log_Msg_UNIX_Syslog
00096 #else
00097 #  define ACE_LOG_MSG_SYSLOG_BACKEND ACE_Log_Msg_IPC
00098 #endif /* ! ACE_WIN32 */
00099 
00100 // When doing ACE_OS::s[n]printf() calls in log(), we need to update
00101 // the space remaining in the output buffer based on what's returned from
00102 // the output function. If we could rely on more modern compilers, this
00103 // would be in an unnamed namespace, but it's a macro instead.
00104 // count is a size_t, len is an int and assumed to be non-negative.
00105 #define ACE_UPDATE_COUNT(COUNT, LEN) \
00106    do { if (static_cast<size_t> (LEN) > COUNT) COUNT = 0; \
00107      else COUNT -= static_cast<size_t> (LEN); \
00108    } while (0)
00109 
00110 /// Instance count for Log_Msg - used to know when dynamically
00111 /// allocated storage (program name and host name) can be safely
00112 /// deleted.
00113 int ACE_Log_Msg::instance_count_ = 0;
00114 
00115 /**
00116  * @class ACE_Log_Msg_Manager
00117  *
00118  * @brief Synchronize output operations.
00119  *
00120  * Provides global point of contact for all ACE_Log_Msg instances
00121  * in a process.
00122  *
00123  * For internal use by ACE, only!
00124  */
00125 class ACE_Log_Msg_Manager
00126 {
00127 public:
00128   static ACE_Log_Msg_Backend *log_backend_;
00129   static ACE_Log_Msg_Backend *custom_backend_;
00130 
00131   static u_long log_backend_flags_;
00132 
00133   static int init_backend (const u_long *flags = 0);
00134 
00135 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00136   static void close (void);
00137 
00138   static ACE_Recursive_Thread_Mutex *get_lock (void);
00139 
00140 private:
00141   static ACE_Recursive_Thread_Mutex *lock_;
00142 #endif /* ! ACE_MT_SAFE */
00143 };
00144 
00145 ACE_Log_Msg_Backend *ACE_Log_Msg_Manager::log_backend_ = 0;
00146 ACE_Log_Msg_Backend *ACE_Log_Msg_Manager::custom_backend_ = 0;
00147 
00148 u_long ACE_Log_Msg_Manager::log_backend_flags_ = 0;
00149 
00150 int ACE_Log_Msg_Manager::init_backend (const u_long *flags)
00151 {
00152   // If flags have been supplied, and they are different from the flags
00153   // we had last time, then we may have to re-create the backend as a
00154   // different type.
00155   if (flags)
00156     {
00157       // Sanity check for custom backend.
00158       if (ACE_BIT_ENABLED (*flags, ACE_Log_Msg::CUSTOM) &&
00159           ACE_Log_Msg_Manager::custom_backend_ == 0)
00160         {
00161           return -1;
00162         }
00163 
00164       if ((ACE_BIT_ENABLED (*flags, ACE_Log_Msg::SYSLOG)
00165             && ACE_BIT_DISABLED (ACE_Log_Msg_Manager::log_backend_flags_, ACE_Log_Msg::SYSLOG))
00166           || (ACE_BIT_DISABLED (*flags, ACE_Log_Msg::SYSLOG)
00167             && ACE_BIT_ENABLED (ACE_Log_Msg_Manager::log_backend_flags_, ACE_Log_Msg::SYSLOG)))
00168         {
00169           delete ACE_Log_Msg_Manager::log_backend_;
00170           ACE_Log_Msg_Manager::log_backend_ = 0;
00171         }
00172 
00173       ACE_Log_Msg_Manager::log_backend_flags_ = *flags;
00174     }
00175 
00176   if (ACE_Log_Msg_Manager::log_backend_ == 0)
00177     {
00178       ACE_NO_HEAP_CHECK;
00179 
00180 #if (defined (WIN32) || !defined (ACE_LACKS_UNIX_SYSLOG)) && !defined (ACE_HAS_WINCE) && !defined (ACE_HAS_PHARLAP)
00181       // Allocate the ACE_Log_Msg_Backend instance.
00182       if (ACE_BIT_ENABLED (ACE_Log_Msg_Manager::log_backend_flags_, ACE_Log_Msg::SYSLOG))
00183         ACE_NEW_RETURN (ACE_Log_Msg_Manager::log_backend_,
00184                         ACE_LOG_MSG_SYSLOG_BACKEND,
00185                         -1);
00186       else
00187 #endif /* defined (WIN32) && !defined (ACE_HAS_WINCE) && !defined (ACE_HAS_PHARLAP) */
00188         ACE_NEW_RETURN (ACE_Log_Msg_Manager::log_backend_,
00189                         ACE_Log_Msg_IPC,
00190                         -1);
00191     }
00192 
00193   return 0;
00194 }
00195 
00196 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00197 ACE_Recursive_Thread_Mutex *ACE_Log_Msg_Manager::lock_ = 0;
00198 
00199 ACE_Recursive_Thread_Mutex *
00200 ACE_Log_Msg_Manager::get_lock (void)
00201 {
00202   // This function is called by the first thread to create an ACE_Log_Msg
00203   // instance.  It makes the call while holding a mutex, so we don't have
00204   // to grab another one here.
00205 
00206   if (ACE_Log_Msg_Manager::lock_ == 0)
00207     {
00208       ACE_NO_HEAP_CHECK;
00209 
00210       ACE_NEW_RETURN (ACE_Log_Msg_Manager::lock_,
00211                       ACE_Recursive_Thread_Mutex,
00212                       0);
00213     }
00214 
00215   if (init_backend () == -1)
00216     return 0;
00217 
00218   return ACE_Log_Msg_Manager::lock_;
00219 }
00220 
00221 void
00222 ACE_Log_Msg_Manager::close (void)
00223 {
00224 #if defined (ACE_HAS_STHREADS) && ! defined (ACE_HAS_TSS_EMULATION) && ! defined (ACE_HAS_EXCEPTIONS)
00225   // Delete the (main thread's) Log_Msg instance.  I think that this
00226   // is only "necessary" if exception handling is not enabled.
00227   // Without exception handling, main thread TSS destructors don't
00228   // seem to be called.  It's not really necessary anyways, because
00229   // this one leak is harmless on Solaris.
00230   delete ACE_Log_Msg::instance ();
00231 #endif /* ACE_HAS_STHREADS && ! TSS_EMULATION && ! ACE_HAS_EXCEPTIONS */
00232 
00233   // Ugly, ugly, but don't know a better way.
00234   delete ACE_Log_Msg_Manager::lock_;
00235   ACE_Log_Msg_Manager::lock_ = 0;
00236 
00237   delete ACE_Log_Msg_Manager::log_backend_;
00238   ACE_Log_Msg_Manager::log_backend_ = 0;
00239 
00240   // we are never responsible for custom backend
00241   ACE_Log_Msg_Manager::custom_backend_ = 0;
00242 }
00243 
00244 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \
00245      defined (ACE_HAS_TSS_EMULATION)
00246 /* static */
00247 #  if defined (ACE_HAS_THR_C_DEST)
00248 #   define LOCAL_EXTERN_PREFIX extern "C"
00249 #  else
00250 #   define LOCAL_EXTERN_PREFIX
00251 #  endif /* ACE_HAS_THR_C_DEST */
00252 LOCAL_EXTERN_PREFIX
00253 void
00254 ACE_TSS_CLEANUP_NAME (void *ptr)
00255 {
00256   // Delegate to thr_desc if this not has terminated
00257   ACE_Log_Msg* log_msg = (ACE_Log_Msg*) ptr;
00258   if (log_msg->thr_desc()!=0)
00259     log_msg->thr_desc()->log_msg_cleanup(log_msg);
00260   else
00261     delete (ACE_Log_Msg *) ptr;
00262 }
00263 # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */
00264 #endif /* ! ACE_MT_SAFE */
00265 
00266 /* static */
00267 int
00268 ACE_Log_Msg::exists (void)
00269 {
00270 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00271 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \
00272      defined (ACE_HAS_TSS_EMULATION)
00273   void *tss_log_msg = 0; // The actual type is ACE_Log_Msg*, but we need this
00274                          // void to keep G++ from complaining.
00275 
00276   // Get the tss_log_msg from thread-specific storage.
00277   return key_created_
00278     && ACE_Thread::getspecific (*(log_msg_tss_key ()), &tss_log_msg) != -1
00279     && tss_log_msg != 0;
00280 # else
00281 #   error "Platform must support thread-specific storage if threads are used."
00282 # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */
00283 #else  /* ! ACE_MT_SAFE */
00284   return 1;
00285 #endif /* ! ACE_MT_SAFE */
00286 }
00287 
00288 ACE_Log_Msg *
00289 ACE_Log_Msg::instance (void)
00290 {
00291 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00292 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \
00293      defined (ACE_HAS_TSS_EMULATION)
00294   // TSS Singleton implementation.
00295 
00296   if (key_created_ == 0)
00297     {
00298       ACE_thread_mutex_t *lock =
00299         reinterpret_cast<ACE_thread_mutex_t *> (
00300           ACE_OS_Object_Manager::preallocated_object
00301             [ACE_OS_Object_Manager::ACE_LOG_MSG_INSTANCE_LOCK]);
00302 
00303       if (1 == ACE_OS_Object_Manager::starting_up())
00304         //This function is called before ACE_OS_Object_Manager is
00305         //initialized.  So the lock might not be valid.  Assume it's
00306         //single threaded and so don't need the lock.
00307         ;
00308       else
00309         ACE_OS::thread_mutex_lock (lock);
00310 
00311       if (key_created_ == 0)
00312         {
00313           // Allocate the Singleton lock.
00314           ACE_Log_Msg_Manager::get_lock ();
00315 
00316           {
00317             ACE_NO_HEAP_CHECK;
00318             if (ACE_Thread::keycreate (log_msg_tss_key (),
00319                                        &ACE_TSS_CLEANUP_NAME) != 0)
00320               {
00321                 if (1 == ACE_OS_Object_Manager::starting_up())
00322                   //This function is called before ACE_OS_Object_Manager is
00323                   //initialized.  So the lock might not be valid.  Assume it's
00324                   //single threaded and so don't need the lock.
00325                   ;
00326                 else
00327                 ACE_OS::thread_mutex_unlock (lock);
00328                 return 0; // Major problems, this should *never* happen!
00329               }
00330           }
00331 
00332           key_created_ = 1;
00333         }
00334 
00335       if (1 == ACE_OS_Object_Manager::starting_up())
00336         //This function is called before ACE_OS_Object_Manager is
00337         //initialized.  So the lock might not be valid.  Assume it's
00338         //single threaded and so don't need the lock.
00339         ;
00340       else
00341         ACE_OS::thread_mutex_unlock (lock);
00342     }
00343 
00344   ACE_Log_Msg *tss_log_msg = 0;
00345   void *temp = 0;
00346 
00347   // Get the tss_log_msg from thread-specific storage.
00348   if (ACE_Thread::getspecific (*(log_msg_tss_key ()), &temp) == -1)
00349     return 0; // This should not happen!
00350 
00351   tss_log_msg = static_cast <ACE_Log_Msg *> (temp);
00352 
00353   // Check to see if this is the first time in for this thread.
00354   if (tss_log_msg == 0)
00355     {
00356       // Allocate memory off the heap and store it in a pointer in
00357       // thread-specific storage (on the stack...).  Stop heap
00358       // checking, the memory will always be freed by the thread
00359       // rundown because of the TSS callback set up when the key was
00360       // created. This prevents from getting these blocks reported as
00361       // memory leaks.
00362       {
00363         ACE_NO_HEAP_CHECK;
00364 
00365         ACE_NEW_RETURN (tss_log_msg,
00366                         ACE_Log_Msg,
00367                         0);
00368         // Store the dynamically allocated pointer in thread-specific
00369         // storage.  It gets deleted via the ACE_TSS_cleanup function
00370         // when the thread terminates.
00371 
00372         if (ACE_Thread::setspecific (*(log_msg_tss_key()),
00373                                      reinterpret_cast<void *> (tss_log_msg))
00374             != 0)
00375           return 0; // Major problems, this should *never* happen!
00376       }
00377     }
00378 
00379   return tss_log_msg;
00380 # else
00381 #  error "Platform must support thread-specific storage if threads are used."
00382 # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */
00383 #else  /* ! ACE_MT_SAFE */
00384   // We don't have threads, we cannot call
00385   // ACE_Log_Msg_Manager::get_lock () to initialize the logger
00386   // callback, so instead we do it here.
00387   if (ACE_Log_Msg_Manager::init_backend () == -1)
00388     return 0;
00389 
00390   // Singleton implementation.
00391 
00392   if (log_msg_cleanup == 0)
00393     {
00394       ACE_NEW_RETURN (log_msg_cleanup, ACE_Msg_Log_Cleanup, 0);
00395       // Register the instance for destruction at program termination.
00396       ACE_Object_Manager::at_exit (log_msg_cleanup);
00397     }
00398 
00399   return &log_msg_cleanup->object ();
00400 #endif /* ! ACE_MT_SAFE */
00401 }
00402 
00403 // Not inlined to help prevent having to include OS.h just to
00404 // get ACE_DEBUG, et al, macros.
00405 int
00406 ACE_Log_Msg::last_error_adapter (void)
00407 {
00408   return ACE_OS::last_error ();
00409 }
00410 
00411 // Sets the flag in the default priority mask used to initialize
00412 // ACE_Log_Msg instances, as well as the current per-thread instance.
00413 
00414 void
00415 ACE_Log_Msg::enable_debug_messages (ACE_Log_Priority priority)
00416 {
00417   ACE_SET_BITS (ACE_Log_Msg::default_priority_mask_, priority);
00418   ACE_Log_Msg *i = ACE_Log_Msg::instance ();
00419   i->priority_mask (i->priority_mask () | priority);
00420 }
00421 
00422 // Clears the flag in the default priority mask used to initialize
00423 // ACE_Log_Msg instances, as well as the current per-thread instance.
00424 
00425 void
00426 ACE_Log_Msg::disable_debug_messages (ACE_Log_Priority priority)
00427 {
00428   ACE_CLR_BITS (ACE_Log_Msg::default_priority_mask_, priority);
00429   ACE_Log_Msg *i = ACE_Log_Msg::instance ();
00430   i->priority_mask (i->priority_mask () & ~priority);
00431 }
00432 
00433 const ACE_TCHAR *
00434 ACE_Log_Msg::program_name (void)
00435 {
00436   return ACE_Log_Msg::program_name_;
00437 }
00438 
00439 /// Name of the local host.
00440 const ACE_TCHAR *ACE_Log_Msg::local_host_ = 0;
00441 
00442 /// Records the program name.
00443 const ACE_TCHAR *ACE_Log_Msg::program_name_ = 0;
00444 
00445 /// Default is to use stderr.
00446 u_long ACE_Log_Msg::flags_ = ACE_Log_Msg::STDERR;
00447 
00448 /// Process id of the current process.
00449 pid_t ACE_Log_Msg::pid_ = -1;
00450 
00451 /// Current offset of msg_[].
00452 ptrdiff_t ACE_Log_Msg::msg_off_ = 0;
00453 
00454 /// Default per-thread priority mask
00455 /// By default, no priorities are enabled.
00456 u_long ACE_Log_Msg::default_priority_mask_ = 0;
00457 
00458 /// Default per-process priority mask
00459 /// By default, all priorities are enabled.
00460 u_long ACE_Log_Msg::process_priority_mask_ = LM_SHUTDOWN
00461                                              | LM_TRACE
00462                                              | LM_DEBUG
00463                                              | LM_INFO
00464                                              | LM_NOTICE
00465                                              | LM_WARNING
00466                                              | LM_STARTUP
00467                                              | LM_ERROR
00468                                              | LM_CRITICAL
00469                                              | LM_ALERT
00470                                              | LM_EMERGENCY;
00471 
00472 void
00473 ACE_Log_Msg::close (void)
00474 {
00475   // This call needs to go here to avoid memory leaks.
00476   ACE_MT (ACE_Log_Msg_Manager::close ());
00477 
00478   // Please note that this will be called by a statement that is
00479   // harded coded into the ACE_Object_Manager's shutdown sequence, in
00480   // its destructor.
00481 
00482 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) && \
00483     (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \
00484      defined (ACE_HAS_TSS_EMULATION))
00485 
00486      if (key_created_ == 1)
00487        {
00488          ACE_thread_mutex_t *lock =
00489            reinterpret_cast<ACE_thread_mutex_t *> (
00490              ACE_OS_Object_Manager::preallocated_object
00491              [ACE_OS_Object_Manager::ACE_LOG_MSG_INSTANCE_LOCK]);
00492          ACE_OS::thread_mutex_lock (lock);
00493 
00494          if (key_created_ == 1)
00495            {
00496              // The same as the ACE_TSS_Cleanup's own key doesn't get
00497              // detached, the log_msg_tss_key_ won't get detached
00498              // until ACE_TSS_Cleanup::free_all_keys_left, so it will
00499              // be in the ACE_TSS_Cleanup::table_.  However, there's
00500              // no resource associated with it, so we don't need to
00501              // keyfree it.  The dynamic memory associated with it was
00502              // already deleted by ACE_TSS_Cleanup::exit (), so we
00503              // don't want to access it again.
00504              key_created_ = 0;
00505 #ifdef ACE_HAS_BROKEN_THREAD_KEYFREE
00506              // for some systems, e.g. LynxOS, we need to ensure that
00507              // any registered thread destructor action for this thread
00508              // is disabled. Otherwise in the event of a dynamic library
00509              // unload of libACE, by a program not linked with libACE,
00510              // ACE_TSS_cleanup will be invoked after libACE has been unloaded.
00511             ACE_Log_Msg *tss_log_msg = 0;
00512             void *temp = 0;
00513 
00514              // Get the tss_log_msg from thread-specific storage.
00515              if (ACE_Thread::getspecific (*(log_msg_tss_key ()), &temp) != -1
00516                   && temp)
00517               {
00518                 tss_log_msg = static_cast <ACE_Log_Msg *> (temp);
00519                 // we haven't been cleaned up
00520                 ACE_TSS_CLEANUP_NAME(tss_log_msg);
00521                 if (ACE_Thread::setspecific(*(log_msg_tss_key()),
00522                                            reinterpret_cast <void *>(0)) != 0)
00523                 {
00524                   ACE_OS::printf ("ACE_Log_Msg::close failed to ACE_Thread::setspecific to 0\n");
00525                 }
00526              }
00527 #endif /* ACE_HAS_BROKEN_THREAD_KEYFREE */
00528            }
00529 
00530          ACE_OS::thread_mutex_unlock (lock);
00531        }
00532 #endif /* (ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION) && ACE_MT_SAFE */
00533 }
00534 
00535 void
00536 ACE_Log_Msg::sync_hook (const ACE_TCHAR *prg_name)
00537 {
00538   ACE_LOG_MSG->sync (prg_name);
00539 }
00540 
00541 ACE_OS_Thread_Descriptor *
00542 ACE_Log_Msg::thr_desc_hook (void)
00543 {
00544   return ACE_LOG_MSG->thr_desc ();
00545 }
00546 
00547 // Call after a fork to resynchronize the PID and PROGRAM_NAME
00548 // variables.
00549 void
00550 ACE_Log_Msg::sync (const ACE_TCHAR *prog_name)
00551 {
00552   ACE_TRACE ("ACE_Log_Msg::sync");
00553 
00554   if (prog_name)
00555     {
00556       // Must free if already allocated!!!
00557       ACE_OS::free ((void *) ACE_Log_Msg::program_name_);
00558 
00559       // Stop heap checking, block will be freed by the destructor when
00560       // the last ACE_Log_Msg instance is deleted.
00561       // Heap checking state will be restored when the block is left.
00562       {
00563         ACE_NO_HEAP_CHECK;
00564 
00565         ACE_Log_Msg::program_name_ = ACE_OS::strdup (prog_name);
00566       }
00567     }
00568 
00569   ACE_Log_Msg::pid_ = ACE_OS::getpid ();
00570   ACE_Log_Msg::msg_off_ = 0;
00571 }
00572 
00573 u_long
00574 ACE_Log_Msg::flags (void)
00575 {
00576   ACE_TRACE ("ACE_Log_Msg::flags");
00577   u_long result;
00578   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00579                             *ACE_Log_Msg_Manager::get_lock (), 0));
00580 
00581   result = ACE_Log_Msg::flags_;
00582   return result;
00583 }
00584 
00585 void
00586 ACE_Log_Msg::set_flags (u_long flgs)
00587 {
00588   ACE_TRACE ("ACE_Log_Msg::set_flags");
00589   ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
00590                      *ACE_Log_Msg_Manager::get_lock ()));
00591 
00592   ACE_SET_BITS (ACE_Log_Msg::flags_, flgs);
00593 }
00594 
00595 void
00596 ACE_Log_Msg::clr_flags (u_long flgs)
00597 {
00598   ACE_TRACE ("ACE_Log_Msg::clr_flags");
00599   ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
00600                      *ACE_Log_Msg_Manager::get_lock ()));
00601 
00602   ACE_CLR_BITS (ACE_Log_Msg::flags_, flgs);
00603 }
00604 
00605 int
00606 ACE_Log_Msg::acquire (void)
00607 {
00608   ACE_TRACE ("ACE_Log_Msg::acquire");
00609 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00610   return ACE_Log_Msg_Manager::get_lock ()->acquire ();
00611 #else  /* ! ACE_MT_SAFE */
00612   return 0;
00613 #endif /* ! ACE_MT_SAFE */
00614 }
00615 
00616 u_long
00617 ACE_Log_Msg::priority_mask (u_long n_mask, MASK_TYPE mask_type)
00618 {
00619   u_long o_mask;
00620 
00621   if (mask_type == THREAD)
00622     {
00623       o_mask = this->priority_mask_;
00624       this->priority_mask_ = n_mask;
00625     }
00626   else
00627     {
00628       o_mask = ACE_Log_Msg::process_priority_mask_;
00629       ACE_Log_Msg::process_priority_mask_ = n_mask;
00630     }
00631 
00632   return o_mask;
00633 }
00634 
00635 u_long
00636 ACE_Log_Msg::priority_mask (MASK_TYPE mask_type)
00637 {
00638   return mask_type == THREAD
00639     ? this->priority_mask_
00640     :  ACE_Log_Msg::process_priority_mask_;
00641 }
00642 
00643 int
00644 ACE_Log_Msg::log_priority_enabled (ACE_Log_Priority log_priority)
00645 {
00646   return ACE_BIT_ENABLED (this->priority_mask_ |
00647                           ACE_Log_Msg::process_priority_mask_,
00648                           log_priority);
00649 }
00650 
00651 int
00652 ACE_Log_Msg::release (void)
00653 {
00654   ACE_TRACE ("ACE_Log_Msg::release");
00655 
00656 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00657   return ACE_Log_Msg_Manager::get_lock ()->release ();
00658 #else  /* ! ACE_MT_SAFE */
00659   return 0;
00660 #endif /* ! ACE_MT_SAFE */
00661 }
00662 
00663 ACE_Log_Msg::ACE_Log_Msg (void)
00664   : status_ (0),
00665     errnum_ (0),
00666     linenum_ (0),
00667     msg_ (0),
00668     restart_ (1),  // Restart by default...
00669     ostream_ (0),
00670     msg_callback_ (0),
00671     trace_depth_ (0),
00672     trace_active_ (0),
00673     tracing_enabled_ (1), // On by default?
00674     delete_ostream_(0),
00675     thr_desc_ (0),
00676     priority_mask_ (default_priority_mask_),
00677     timestamp_ (0)
00678 {
00679   // ACE_TRACE ("ACE_Log_Msg::ACE_Log_Msg");
00680 
00681   ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
00682                      *ACE_Log_Msg_Manager::get_lock ()));
00683   ++instance_count_;
00684 
00685   if (this->instance_count_ == 1)
00686     ACE_Base_Thread_Adapter::set_log_msg_hooks (ACE_Log_Msg::init_hook,
00687                                                 ACE_Log_Msg::inherit_hook,
00688                                                 ACE_Log_Msg::close,
00689                                                 ACE_Log_Msg::sync_hook,
00690                                                 ACE_Log_Msg::thr_desc_hook);
00691 
00692   this->conditional_values_.is_set_ = false;
00693 
00694   char *timestamp = ACE_OS::getenv ("ACE_LOG_TIMESTAMP");
00695   if (timestamp != 0)
00696     {
00697       // If variable is set or is set to date tag so we print date and time.
00698       if (ACE_OS::strcmp (timestamp, "TIME") == 0)
00699         {
00700           this->timestamp_ = 1;
00701         }
00702       else if (ACE_OS::strcmp (timestamp, "DATE") == 0)
00703         {
00704           this->timestamp_ = 2;
00705         }
00706     }
00707 
00708   ACE_NEW_NORETURN (this->msg_, ACE_TCHAR[ACE_MAXLOGMSGLEN+1]);
00709 }
00710 
00711 ACE_Log_Msg::~ACE_Log_Msg (void)
00712 {
00713 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00714 
00715   int instance_count = 0;
00716 
00717   // Only hold the guard while updating the instance_count_.
00718   // If ACE_Log_Msg_Manager::close () is called, the lock will
00719   // be deleted.
00720   {
00721     ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
00722                        *ACE_Log_Msg_Manager::get_lock ()));
00723     instance_count = --instance_count_;
00724   }
00725   // Release the guard.
00726 
00727 #else  /* ! ACE_MT_SAFE */
00728   int instance_count = --instance_count_;
00729 #endif /* ! ACE_MT_SAFE */
00730 
00731   // If this is the last instance then cleanup.  Only the last
00732   // thread to destroy its ACE_Log_Msg instance should execute
00733   // this block.
00734   if (instance_count == 0)
00735     {
00736       // Destroy the message queue instance.
00737       if (ACE_Log_Msg_Manager::log_backend_ != 0)
00738         ACE_Log_Msg_Manager::log_backend_->close ();
00739 
00740       // Close down custom backend
00741       if (ACE_Log_Msg_Manager::custom_backend_ != 0)
00742         ACE_Log_Msg_Manager::custom_backend_->close ();
00743 
00744 #     if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00745 #       if defined (ACE_HAS_TSS_EMULATION)
00746           ACE_Log_Msg_Manager::close ();
00747 #       endif /* ACE_HAS_TSS_EMULATION */
00748 #     endif /* ACE_MT_SAFE */
00749 
00750       if (ACE_Log_Msg::program_name_)
00751         {
00752           ACE_OS::free ((void *) ACE_Log_Msg::program_name_);
00753           ACE_Log_Msg::program_name_ = 0;
00754         }
00755 
00756       if (ACE_Log_Msg::local_host_)
00757         {
00758           ACE_OS::free ((void *) ACE_Log_Msg::local_host_);
00759           ACE_Log_Msg::local_host_ = 0;
00760         }
00761     }
00762 
00763   //
00764   // do we need to close and clean up?
00765   //
00766   if (this->delete_ostream_ == 1)
00767 #if defined (ACE_LACKS_IOSTREAM_TOTALLY)
00768     {
00769       ACE_OS::fclose (this->ostream_);
00770     }
00771 #else
00772     {
00773       delete ostream_;
00774       ostream_ = 0;
00775     }
00776 #endif
00777 
00778   delete[] this->msg_;
00779 }
00780 
00781 // Open the sender-side of the message queue.
00782 
00783 int
00784 ACE_Log_Msg::open (const ACE_TCHAR *prog_name,
00785                    u_long flags,
00786                    const ACE_TCHAR *logger_key)
00787 {
00788   ACE_TRACE ("ACE_Log_Msg::open");
00789   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00790                             *ACE_Log_Msg_Manager::get_lock (), -1));
00791 
00792   if (prog_name)
00793     {
00794       ACE_OS::free ((void *) ACE_Log_Msg::program_name_);
00795 
00796       // Stop heap checking, block will be freed by the destructor.
00797       {
00798         ACE_NO_HEAP_CHECK;
00799 
00800         ACE_ALLOCATOR_RETURN (ACE_Log_Msg::program_name_,
00801                               ACE_OS::strdup (prog_name),
00802                               -1);
00803       }
00804     }
00805   else if (ACE_Log_Msg::program_name_ == 0)
00806     {
00807       // Stop heap checking, block will be freed by the destructor.
00808       ACE_NO_HEAP_CHECK;
00809       ACE_ALLOCATOR_RETURN (ACE_Log_Msg::program_name_,
00810                             ACE_OS::strdup (ACE_TEXT ("<unknown>")),
00811                             -1);
00812     }
00813 
00814   int status = 0;
00815 
00816   // Be sure that there is a message_queue_, with multiple threads.
00817   ACE_MT (ACE_Log_Msg_Manager::init_backend (&flags));
00818 
00819   // Always close the current handle before doing anything else.
00820   if (ACE_Log_Msg_Manager::log_backend_ != 0)
00821     ACE_Log_Msg_Manager::log_backend_->reset ();
00822 
00823   if (ACE_Log_Msg_Manager::custom_backend_ != 0)
00824     ACE_Log_Msg_Manager::custom_backend_->reset ();
00825 
00826   // Note that if we fail to open the message queue the default action
00827   // is to use stderr (set via static initialization in the
00828   // Log_Msg.cpp file).
00829 
00830   if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::LOGGER)
00831       || ACE_BIT_ENABLED (flags, ACE_Log_Msg::SYSLOG))
00832     {
00833       // The SYSLOG backends (both NT and UNIX) can get along fine
00834       // without the logger_key - they will default to prog_name if
00835       // logger key is 0.
00836       if (logger_key == 0 && ACE_BIT_ENABLED (flags, ACE_Log_Msg::LOGGER))
00837         status = -1;
00838       else
00839         status = ACE_Log_Msg_Manager::log_backend_->open (logger_key);
00840 
00841       if (status == -1)
00842         ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::STDERR);
00843       else
00844         {
00845           if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::LOGGER))
00846             ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::LOGGER);
00847           if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::SYSLOG))
00848             ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::SYSLOG);
00849         }
00850     }
00851   else if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::LOGGER)
00852            || ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::SYSLOG))
00853     {
00854       // If we are closing down logger, redirect logging to stderr.
00855       ACE_CLR_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::LOGGER);
00856       ACE_CLR_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::SYSLOG);
00857       ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::STDERR);
00858     }
00859 
00860   if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::CUSTOM))
00861     {
00862       status =
00863         ACE_Log_Msg_Manager::custom_backend_->open (logger_key);
00864 
00865       if (status != -1)
00866         ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::CUSTOM);
00867     }
00868 
00869   // Remember, ACE_Log_Msg::STDERR bit is on by default...
00870   if (status != -1
00871       && ACE_BIT_ENABLED (flags,
00872                           ACE_Log_Msg::STDERR) == 0)
00873     ACE_CLR_BITS (ACE_Log_Msg::flags_,
00874                   ACE_Log_Msg::STDERR);
00875 
00876   // VERBOSE takes precedence over VERBOSE_LITE...
00877   if (ACE_BIT_ENABLED (flags,
00878                        ACE_Log_Msg::VERBOSE_LITE))
00879     ACE_SET_BITS (ACE_Log_Msg::flags_,
00880                   ACE_Log_Msg::VERBOSE_LITE);
00881   else if (ACE_BIT_ENABLED (flags,
00882                             ACE_Log_Msg::VERBOSE))
00883     ACE_SET_BITS (ACE_Log_Msg::flags_,
00884                   ACE_Log_Msg::VERBOSE);
00885 
00886   if (ACE_BIT_ENABLED (flags,
00887                        ACE_Log_Msg::OSTREAM))
00888     {
00889       ACE_SET_BITS (ACE_Log_Msg::flags_,
00890                     ACE_Log_Msg::OSTREAM);
00891       // Only set this to cerr if it hasn't already been set.
00892       if (this->msg_ostream () == 0)
00893         this->msg_ostream (ACE_DEFAULT_LOG_STREAM);
00894     }
00895 
00896   if (ACE_BIT_ENABLED (flags,
00897                        ACE_Log_Msg::MSG_CALLBACK))
00898     ACE_SET_BITS (ACE_Log_Msg::flags_,
00899                   ACE_Log_Msg::MSG_CALLBACK);
00900 
00901   if (ACE_BIT_ENABLED (flags,
00902                        ACE_Log_Msg::SILENT))
00903     ACE_SET_BITS (ACE_Log_Msg::flags_,
00904                   ACE_Log_Msg::SILENT);
00905 
00906   return status;
00907 }
00908 
00909 /**
00910  * Valid Options (prefixed by '%', as in printf format strings) include:
00911  *   'A': print an ACE_timer_t value
00912  *   'a': exit the program at this point (var-argument is the exit status!)
00913  *   'b': print a ssize_t value
00914  *   'B': print a size_t value
00915  *   'c': print a character
00916  *   'C': print a character string
00917  *   'i', 'd': print a decimal number
00918  *   'I', indent according to nesting depth
00919  *   'e', 'E', 'f', 'F', 'g', 'G': print a double
00920  *   'l', print line number where an error occurred.
00921  *   'M': print the name of the priority of the message.
00922  *   'm': Return the message corresponding to errno value, e.g., as done by <strerror>
00923  *   'N': print file name where the error occurred.
00924  *   'n': print the name of the program (or "<unknown>" if not set)
00925  *   'o': print as an octal number
00926  *   'P': format the current process id
00927  *   'p': format the appropriate errno message from sys_errlist, e.g., as done by <perror>
00928  *   'Q': print out the uint64 number
00929  *   'q': print out the int64 number
00930  *   '@': print a void* pointer (in hexadecimal)
00931  *   'r': call the function pointed to by the corresponding argument
00932  *   'R': print return status
00933  *   'S': format the appropriate _sys_siglist entry corresponding to var-argument.
00934  *   's': format a character string
00935  *   'T': print timestamp in hour:minute:sec:usec format.
00936  *   'D': print timestamp in month/day/year hour:minute:sec:usec format.
00937  *   't': print thread id (1 if single-threaded)
00938  *   'u': print as unsigned int
00939  *   'x': print as a hex number
00940  *   'X': print as a hex number
00941  *   'w': print a wide character
00942  *   'W': print out a wide character string.
00943  *   'z': print an ACE_OS::WChar character
00944  *   'Z': print an ACE_OS::WChar character string
00945  *   ':': print a time_t value as an integral number
00946  *   '%': format a single percent sign, '%'
00947  */
00948 ssize_t
00949 ACE_Log_Msg::log (ACE_Log_Priority log_priority,
00950                   const ACE_TCHAR *format_str, ...)
00951 {
00952   ACE_TRACE ("ACE_Log_Msg::log");
00953 
00954   // Start of variable args section.
00955   va_list argp;
00956 
00957   va_start (argp, format_str);
00958 
00959   ssize_t const result = this->log (format_str,
00960                                     log_priority,
00961                                     argp);
00962   va_end (argp);
00963 
00964   return result;
00965 }
00966 
00967 #if defined (ACE_HAS_WCHAR)
00968 /**
00969  * Since this is the ANTI_TCHAR version, we need to convert
00970  * the format string over.
00971  */
00972 ssize_t
00973 ACE_Log_Msg::log (ACE_Log_Priority log_priority,
00974                   const ACE_ANTI_TCHAR *format_str, ...)
00975 {
00976   ACE_TRACE ("ACE_Log_Msg::log");
00977 
00978   // Start of variable args section.
00979   va_list argp;
00980 
00981   va_start (argp, format_str);
00982 
00983   ssize_t const result = this->log (ACE_TEXT_ANTI_TO_TCHAR (format_str),
00984                                     log_priority,
00985                                     argp);
00986   va_end (argp);
00987 
00988   return result;
00989 }
00990 #endif /* ACE_HAS_WCHAR */
00991 
00992 ssize_t
00993 ACE_Log_Msg::log (const ACE_TCHAR *format_str,
00994                   ACE_Log_Priority log_priority,
00995                   va_list argp)
00996 {
00997   ACE_TRACE ("ACE_Log_Msg::log");
00998   // External decls.
00999 
01000   typedef void (*PTF)(...);
01001 
01002   // Check if there were any conditional values set.
01003   bool const conditional_values = this->conditional_values_.is_set_;
01004 
01005   // Reset conditional values.
01006   this->conditional_values_.is_set_ = false;
01007 
01008   // Only print the message if <priority_mask_> hasn't been reset to
01009   // exclude this logging priority.
01010   if (this->log_priority_enabled (log_priority) == 0)
01011     return 0;
01012 
01013   // If conditional values were set and the log priority is correct,
01014   // then the values are actually set.
01015   if (conditional_values)
01016     this->set (this->conditional_values_.file_,
01017                this->conditional_values_.line_,
01018                this->conditional_values_.op_status_,
01019                this->conditional_values_.errnum_,
01020                this->restart (),
01021                this->msg_ostream (),
01022                this->msg_callback ());
01023 
01024   // Logging is supposed to be a benign activity (i.e., not interfer
01025   // with normal application operations), so don't inadvertently smash
01026   // errno!
01027   ACE_Errno_Guard guard (errno);
01028 
01029   ACE_Log_Record log_record (log_priority,
01030                              ACE_OS::gettimeofday (),
01031                              this->getpid ());
01032 
01033   // bp is pointer to where to put next part of logged message.
01034   // bspace is the number of characters remaining in msg_.
01035   ACE_TCHAR *bp = const_cast<ACE_TCHAR *> (this->msg ());
01036   size_t bspace = ACE_Log_Record::MAXLOGMSGLEN;  // Leave room for Nul term.
01037   if (this->msg_off_ <= ACE_Log_Record::MAXLOGMSGLEN)
01038     bspace -= static_cast<size_t> (this->msg_off_);
01039 
01040   // If this platform has snprintf() capability to prevent overrunning the
01041   // output buffer, use it. To avoid adding a maintenance-hassle compile-
01042   // time couple between here and OS.cpp, don't try to figure this out at
01043   // compile time. Instead, do a quick check now; if we get a -1 return,
01044   // the platform doesn't support the length-limiting capability.
01045   ACE_TCHAR test[2];
01046   bool can_check = ACE_OS::snprintf (test, 1, ACE_TEXT ("x")) != -1;
01047 
01048   bool abort_prog = false;
01049   int exit_value = 0;
01050 
01051   if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::VERBOSE))
01052     {
01053       // Prepend the program name onto this message
01054 
01055       if (ACE_Log_Msg::program_name_ != 0)
01056         {
01057           for (const ACE_TCHAR *s = ACE_Log_Msg::program_name_;
01058                bspace > 1 && (*bp = *s) != '\0';
01059                ++s, --bspace)
01060             bp++;
01061 
01062           *bp++ = '|';
01063           --bspace;
01064         }
01065     }
01066 
01067   if (timestamp_ > 0)
01068   {
01069      ACE_TCHAR day_and_time[35];
01070      const ACE_TCHAR *s;
01071      if (timestamp_ == 1)
01072      {
01073         // Print just the time
01074         s = ACE::timestamp (day_and_time, sizeof day_and_time, 1);
01075      }
01076      else
01077      {
01078         // Print time and date
01079         ACE::timestamp (day_and_time, sizeof day_and_time);
01080         s = day_and_time;
01081      }
01082 
01083      for (; bspace > 1 && (*bp = *s) != '\0'; ++s, --bspace)
01084        ++bp;
01085 
01086      *bp++ = '|';
01087      --bspace;
01088   }
01089 
01090   while (*format_str != '\0' && bspace > 0)
01091     {
01092       // Copy input to output until we encounter a %, however a
01093       // % followed by another % is not a format specification.
01094 
01095       if (*format_str != '%')
01096         {
01097           *bp++ = *format_str++;
01098           --bspace;
01099         }
01100       else if (format_str[1] == '%') // An "escaped" '%' (just print one '%').
01101         {
01102           *bp++ = *format_str++;    // Store first %
01103           ++format_str;             // but skip second %
01104           --bspace;
01105         }
01106       else
01107         {
01108           // This is most likely a format specification that ends with
01109           // one of the valid options described previously. To enable full
01110           // use of all sprintf capabilities, save the format specifier
01111           // from the '%' up to the format letter in a new char array.
01112           // This allows the full sprintf capability for padding, field
01113           // widths, alignment, etc.  Any width/precision requiring a
01114           // caller-supplied argument is extracted and placed as text
01115           // into the format array. Lastly, we convert the caller-supplied
01116           // format specifier from the ACE_Log_Msg-supported list to the
01117           // equivalent sprintf specifier, and run the new format spec
01118           // through sprintf, adding it to the bp string.
01119 
01120           const ACE_TCHAR *abort_str = ACE_TEXT ("Aborting...");
01121           const ACE_TCHAR *start_format = format_str;
01122           ACE_TCHAR format[128]; // Converted format string
01123           ACE_TCHAR *fp;         // Current format pointer
01124           int       wp = 0;      // Width/precision extracted from args
01125           int       done = 0;
01126           int       skip_nul_locate = 0;
01127           int       this_len = 0;    // How many chars s[n]printf wrote
01128 
01129           fp = format;
01130           *fp++ = *format_str++;   // Copy in the %
01131 
01132           // Initialization to satisfy VC6
01133           int tmp_indent = 0;
01134           // Work through the format string to copy in the format
01135           // from the caller. While it's going across, extract ints
01136           // for '*' width/precision values from the argument list.
01137           // When the real format specifier is located, change it to
01138           // one recognized by sprintf, if needed, and do the sprintf
01139           // call.
01140 
01141           while (!done)
01142             {
01143               done = 1;               // Unless a conversion spec changes it
01144 
01145               switch (*format_str)
01146                 {
01147                 // The initial set of cases are the conversion
01148                 // specifiers. Copy them in to the format array.
01149                 // Note we don't use 'l', a normal conversion spec,
01150                 // as a conversion because it is a ACE_Log_Msg format
01151                 // specifier.
01152                 case '-':
01153                 case '+':
01154                 case '0':
01155                 case ' ':
01156                 case '#':
01157                 case '1':
01158                 case '2':
01159                 case '3':
01160                 case '4':
01161                 case '5':
01162                 case '6':
01163                 case '7':
01164                 case '8':
01165                 case '9':
01166                 case '.':
01167                 case 'L':
01168                 case 'h':
01169                   *fp++ = *format_str;
01170                   done = 0;
01171                   break;
01172 
01173                 case '*':
01174                   wp = va_arg (argp, int);
01175                   ACE_OS::sprintf (fp, ACE_TEXT ("%d"), wp);
01176                   fp += ACE_OS::strlen (fp);
01177                   done = 0;
01178                   break;
01179 
01180                 case 'A':             // ACE_timer_t
01181                   {
01182                     ACE_OS::strcpy (fp, ACE_TEXT ("f"));
01183                     double value = va_arg (argp, double);
01184                     if (can_check)
01185                       this_len = ACE_OS::snprintf (bp, bspace, format, value);
01186                     else
01187                       this_len = ACE_OS::sprintf (bp, format, value);
01188                     ACE_UPDATE_COUNT (bspace, this_len);
01189                   }
01190                   break;
01191 
01192                 case 'a': // Abort program after handling all of format string.
01193                   abort_prog = true;
01194                   exit_value = va_arg (argp, int);
01195                   ACE_OS::strsncpy (bp, abort_str, bspace);
01196                   if (bspace > ACE_OS::strlen (abort_str))
01197                     bspace -= ACE_OS::strlen (abort_str);
01198                   else
01199                     bspace = 0;
01200                   break;
01201 
01202                 case 'l':             // Source file line number
01203                   ACE_OS::strcpy (fp, ACE_TEXT ("d"));
01204                   if (can_check)
01205                     this_len = ACE_OS::snprintf (bp,
01206                                                  bspace,
01207                                                  format,
01208                                                  this->linenum ());
01209                   else
01210                     this_len = ACE_OS::sprintf (bp, format, this->linenum ());
01211                   ACE_UPDATE_COUNT (bspace, this_len);
01212                   break;
01213 
01214                 case 'N':             // Source file name
01215 #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
01216                   ACE_OS::strcpy (fp, ACE_TEXT ("ls"));
01217 #else
01218                   ACE_OS::strcpy (fp, ACE_TEXT ("s"));
01219 #endif
01220                   if (can_check)
01221                     this_len = ACE_OS::snprintf (bp, bspace, format,
01222                                                  this->file () ?
01223                                                  ACE_TEXT_CHAR_TO_TCHAR (this->file ())
01224                                                  : ACE_TEXT ("<unknown file>"));
01225                   else
01226                     this_len = ACE_OS::sprintf (bp, format,
01227                                                 this->file () ?
01228                                                 ACE_TEXT_CHAR_TO_TCHAR (this->file ())
01229                                                 : ACE_TEXT ("<unknown file>"));
01230                   ACE_UPDATE_COUNT (bspace, this_len);
01231                   break;
01232 
01233                 case 'n':             // Program name
01234 #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
01235                   ACE_OS::strcpy (fp, ACE_TEXT ("ls"));
01236 #else /* ACE_WIN32 && ACE_USES_WCHAR */
01237                   ACE_OS::strcpy (fp, ACE_TEXT ("s"));
01238 #endif
01239                   if (can_check)
01240                     this_len = ACE_OS::snprintf (bp, bspace, format,
01241                                                  ACE_Log_Msg::program_name_ ?
01242                                                  ACE_Log_Msg::program_name_ :
01243                                                  ACE_TEXT ("<unknown>"));
01244                   else
01245                     this_len = ACE_OS::sprintf (bp, format,
01246                                                 ACE_Log_Msg::program_name_ ?
01247                                                 ACE_Log_Msg::program_name_ :
01248                                                 ACE_TEXT ("<unknown>"));
01249                   ACE_UPDATE_COUNT (bspace, this_len);
01250                   break;
01251 
01252                 case 'P':             // Process ID
01253                   ACE_OS::strcpy (fp, ACE_TEXT ("d"));
01254                   if (can_check)
01255                     this_len = ACE_OS::snprintf
01256                       (bp, bspace, format,
01257                        static_cast<int> (this->getpid ()));
01258                   else
01259                     this_len = ACE_OS::sprintf
01260                       (bp, format, static_cast<int> (this->getpid ()));
01261                   ACE_UPDATE_COUNT (bspace, this_len);
01262                   break;
01263 
01264                 case 'p':             // <errno> string, ala perror()
01265                   {
01266                     errno = 0;
01267                     char *msg = ACE_OS::strerror (ACE::map_errno (this->errnum ()));
01268                     // Windows can try to translate the errnum using
01269                     // system calls if strerror() doesn't get anything useful.
01270 #if defined (ACE_WIN32)
01271                     if (errno == 0)
01272                       {
01273 #endif
01274 
01275 #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
01276                         ACE_OS::strcpy (fp, ACE_TEXT ("ls: %ls"));
01277 #else
01278                         ACE_OS::strcpy (fp, ACE_TEXT ("s: %s"));
01279 #endif
01280                         if (can_check)
01281                           this_len = ACE_OS::snprintf
01282                             (bp, bspace, format, va_arg (argp, ACE_TCHAR *),
01283                              ACE_TEXT_CHAR_TO_TCHAR (msg));
01284                         else
01285                           this_len = ACE_OS::sprintf
01286                             (bp, format, va_arg (argp, ACE_TCHAR *),
01287                              ACE_TEXT_CHAR_TO_TCHAR (msg));
01288 #if defined (ACE_WIN32)
01289                       }
01290                     else
01291                       {
01292                         errno = ACE::map_errno (this->errnum ());
01293                         ACE_TCHAR *lpMsgBuf = 0;
01294 
01295      // PharLap can't do FormatMessage, so try for socket
01296      // error.
01297 # if !defined (ACE_HAS_PHARLAP)
01298                         ACE_TEXT_FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER
01299                                                   | FORMAT_MESSAGE_MAX_WIDTH_MASK
01300                                                   | FORMAT_MESSAGE_FROM_SYSTEM,
01301                                                   0,
01302                                                   errno,
01303                                                   MAKELANGID (LANG_NEUTRAL,
01304                                                               SUBLANG_DEFAULT),
01305                                                               // Default language
01306                                                   (ACE_TCHAR *) &lpMsgBuf,
01307                                                   0,
01308                                                   0);
01309 # endif /* ACE_HAS_PHARLAP */
01310 
01311                         // If we don't get a valid response from
01312                         // <FormatMessage>, we'll assume this is a
01313                         // WinSock error and so we'll try to convert
01314                         // it into a string.  If this doesn't work it
01315                         // returns "unknown error" which is fine for
01316                         // our purposes.
01317                         if (lpMsgBuf == 0)
01318                           {
01319                             const ACE_TCHAR *message =
01320                               ACE::sock_error (errno);
01321                             ACE_OS::strcpy (fp, ACE_TEXT ("s: %s"));
01322                             if (can_check)
01323                               this_len = ACE_OS::snprintf
01324                                 (bp, bspace, format,
01325                                  va_arg (argp, const ACE_TCHAR *),
01326                                  message);
01327                             else
01328                               this_len = ACE_OS::sprintf
01329                                 (bp, format,
01330                                  va_arg (argp, const ACE_TCHAR *),
01331                                  message);
01332                           }
01333                         else
01334                           {
01335                             ACE_OS::strcpy (fp, ACE_TEXT ("s: %s"));
01336                             if (can_check)
01337                               this_len = ACE_OS::snprintf
01338                                 (bp, bspace, format,
01339                                  va_arg (argp, ACE_TCHAR *),
01340                                  lpMsgBuf);
01341                             else
01342                               this_len = ACE_OS::sprintf
01343                                 (bp, format,
01344                                  va_arg (argp, ACE_TCHAR *),
01345                                  lpMsgBuf);
01346                             // Free the buffer.
01347                             ::LocalFree (lpMsgBuf);
01348                           }
01349                       }
01350 #endif /* ACE_WIN32 */
01351                     ACE_UPDATE_COUNT (bspace, this_len);
01352                     break;
01353                   }
01354 
01355                 case 'M': // Print the name of the priority of the message.
01356 #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
01357                   ACE_OS::strcpy (fp, ACE_TEXT ("ls"));
01358 #else
01359                   ACE_OS::strcpy (fp, ACE_TEXT ("s"));
01360 #endif
01361                   if (can_check)
01362                     this_len = ACE_OS::snprintf
01363                       (bp, bspace, format,
01364                        ACE_Log_Record::priority_name (log_priority));
01365                   else
01366                     this_len = ACE_OS::sprintf
01367                       (bp, format,
01368                        ACE_Log_Record::priority_name (log_priority));
01369                   ACE_UPDATE_COUNT (bspace, this_len);
01370                   break;
01371 
01372                 case 'm': // Format the string assocated with the errno value.
01373                   {
01374                     errno = 0;
01375                     char *msg = 0;
01376                     msg = ACE_OS::strerror (ACE::map_errno (this->errnum ()));
01377                     // Windows can try to translate the errnum using
01378                     // system calls if strerror() doesn't get anything useful.
01379 #if defined (ACE_WIN32)
01380                     if (errno == 0)
01381                       {
01382 #endif
01383 
01384 #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
01385                         ACE_OS::strcpy (fp, ACE_TEXT ("ls"));
01386 #else /* ACE_WIN32 && ACE_USES_WCHAR */
01387                         ACE_OS::strcpy (fp, ACE_TEXT ("s"));
01388 #endif
01389                         if (can_check)
01390                           this_len = ACE_OS::snprintf
01391                             (bp, bspace, format, ACE_TEXT_CHAR_TO_TCHAR (msg));
01392                         else
01393                           this_len = ACE_OS::sprintf
01394                             (bp, format, ACE_TEXT_CHAR_TO_TCHAR (msg));
01395 #if defined (ACE_WIN32)
01396                       }
01397                     else
01398                       {
01399                         errno = ACE::map_errno (this->errnum ());
01400                         ACE_TCHAR *lpMsgBuf = 0;
01401 
01402      // PharLap can't do FormatMessage, so try for socket
01403      // error.
01404 # if !defined (ACE_HAS_PHARLAP)
01405                         ACE_TEXT_FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER
01406                                                   | FORMAT_MESSAGE_MAX_WIDTH_MASK
01407                                                   | FORMAT_MESSAGE_FROM_SYSTEM,
01408                                                   0,
01409                                                   errno,
01410                                                   MAKELANGID (LANG_NEUTRAL,
01411                                                               SUBLANG_DEFAULT),
01412                                                               // Default language
01413                                                   (ACE_TCHAR *) &lpMsgBuf,
01414                                                   0,
01415                                                   0);
01416 # endif /* ACE_HAS_PHARLAP */
01417 
01418                         // If we don't get a valid response from
01419                         // <FormatMessage>, we'll assume this is a
01420                         // WinSock error and so we'll try to convert
01421                         // it into a string.  If this doesn't work it
01422                         // returns "unknown error" which is fine for
01423                         // our purposes.
01424                         if (lpMsgBuf == 0)
01425                           {
01426                             const ACE_TCHAR *message =
01427                               ACE::sock_error (errno);
01428                             ACE_OS::strcpy (fp, ACE_TEXT ("s"));
01429                             if (can_check)
01430                               this_len = ACE_OS::snprintf
01431                                 (bp, bspace, format, message);
01432                             else
01433                               this_len = ACE_OS::sprintf (bp, format, message);
01434                           }
01435                         else
01436                           {
01437                             ACE_OS::strcpy (fp, ACE_TEXT ("s"));
01438                             if (can_check)
01439                               this_len = ACE_OS::snprintf
01440                                 (bp, bspace, format, lpMsgBuf);
01441                             else
01442                               this_len = ACE_OS::sprintf
01443                                 (bp, format, lpMsgBuf);
01444                             // Free the buffer.
01445                             ::LocalFree (lpMsgBuf);
01446                           }
01447                       }
01448 #endif /* ACE_WIN32 */
01449                     ACE_UPDATE_COUNT (bspace, this_len);
01450                     break;
01451                   }
01452 
01453                 case 'R': // Format the return status of the operation.
01454                   this->op_status (va_arg (argp, int));
01455                   ACE_OS::strcpy (fp, ACE_TEXT ("d"));
01456                   if (can_check)
01457                     this_len = ACE_OS::snprintf
01458                       (bp, bspace, format, this->op_status ());
01459                   else
01460                     this_len = ACE_OS::sprintf
01461                       (bp, format, this->op_status ());
01462                   ACE_UPDATE_COUNT (bspace, this_len);
01463                   break;
01464 
01465                 case '{': // Increment the trace_depth, then indent
01466                   skip_nul_locate = 1;
01467                   (void) this->inc ();
01468                   break;
01469 
01470                 case '}': // indent, then decrement trace_depth
01471                   skip_nul_locate = 1;
01472                   (void) this->dec ();
01473                   break;
01474 
01475                 case '$': // insert a newline, then indent the next line
01476                           // according to %I
01477                   *bp++ = '\n';
01478                   --bspace;
01479                   /* fallthrough */
01480 
01481                 case 'I': // Indent with nesting_depth*width spaces
01482                   // Caller can do %*I to override nesting indent, and
01483                   // if %*I was done, wp has the extracted width.
01484 #if defined (ACE_HAS_TRACE)
01485                   if (0 == wp)
01486                     wp = ACE_Trace::get_nesting_indent ();
01487 #else
01488                   if (0 == wp)
01489                     wp = 4;
01490 #endif /* ACE_HAS_TRACE */
01491                   wp *= this->trace_depth_;
01492                   if (static_cast<size_t> (wp) > bspace)
01493                     wp = static_cast<int> (bspace);
01494                   for (tmp_indent = wp;
01495                        tmp_indent;
01496                        --tmp_indent)
01497                     *bp++ = ' ';
01498 
01499                   *bp = '\0';
01500                   bspace -= static_cast<size_t> (wp);
01501                   skip_nul_locate = 1;
01502                   break;
01503 
01504                 case 'r': // Run (invoke) this subroutine.
01505                   {
01506                     ptrdiff_t const osave = ACE_Log_Msg::msg_off_;
01507 
01508                     if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_,
01509                                          ACE_Log_Msg::SILENT) &&
01510                         bspace > 1)
01511                       {
01512                         *bp++ = '{';
01513                         --bspace;
01514                       }
01515                     ACE_Log_Msg::msg_off_ =  bp - this->msg_;
01516 
01517                     (*va_arg (argp, PTF))();
01518 
01519                     if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_,
01520                                          ACE_Log_Msg::SILENT) &&
01521                         bspace > (1 + ACE_OS::strlen (bp)))
01522                       {
01523                         bspace -= (ACE_OS::strlen (bp) + 1);
01524                         bp += ACE_OS::strlen (bp);
01525                         *bp++ =  '}';
01526                       }
01527                     *bp = '\0';
01528                     skip_nul_locate = 1;
01529                     ACE_Log_Msg::msg_off_ = osave;
01530                     break;
01531                   }
01532 
01533                 case 'S': // format the string for with this signal number.
01534                   {
01535                     int sig = va_arg (argp, int);
01536 #if defined (ACE_HAS_SYS_SIGLIST)
01537                     if (sig >= 0 && sig < ACE_NSIG)
01538                       {
01539                         ACE_OS::strcpy (fp, ACE_TEXT ("s"));
01540                         if (can_check)
01541                           this_len = ACE_OS::snprintf
01542                             (bp, bspace, format, _sys_siglist[sig]);
01543                         else
01544                           this_len = ACE_OS::sprintf
01545                             (bp, format, _sys_siglist[sig]);
01546                       }
01547                     else
01548                       {
01549                         if (can_check)
01550                           this_len = ACE_OS::snprintf
01551                             (bp, bspace,
01552                              ACE_TEXT("<unknown signal> %d"), sig);
01553                         else
01554                           this_len = ACE_OS::sprintf
01555                             (bp, ACE_TEXT ("<unknown signal> %d"), sig);
01556                       }
01557 #else
01558                     if (can_check)
01559                       this_len = ACE_OS::snprintf
01560                         (bp, bspace, ACE_TEXT ("signal %d"), sig);
01561                     else
01562                       this_len = ACE_OS::sprintf
01563                         (bp, ACE_TEXT ("signal %d"), sig);
01564 #endif /* ACE_HAS_SYS_SIGLIST */
01565                     ACE_UPDATE_COUNT (bspace, this_len);
01566                     break;
01567                   }
01568 
01569                 case 'D': // Format the timestamp in format:
01570                           // Weekday Month day year hour:minute:sec.usec
01571                   {
01572                     ACE_TCHAR day_and_time[35];
01573                     ACE::timestamp (day_and_time,
01574                                     sizeof day_and_time);
01575 #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
01576                     ACE_OS::strcpy (fp, ACE_TEXT ("ls"));
01577 #else
01578                     ACE_OS::strcpy (fp, ACE_TEXT ("s"));
01579 #endif
01580                     if (can_check)
01581                       this_len = ACE_OS::snprintf
01582                         (bp, bspace, format, day_and_time);
01583                     else
01584                       this_len = ACE_OS::sprintf (bp, format, day_and_time);
01585                     ACE_UPDATE_COUNT (bspace, this_len);
01586                     break;
01587                   }
01588 
01589                 case 'T': // Format the timestamp in
01590                           // hour:minute:sec:usec format.
01591                   {
01592                     ACE_TCHAR day_and_time[35];
01593                     ACE_OS::strcpy (fp, ACE_TEXT ("s"));
01594                     if (can_check)
01595                       this_len = ACE_OS::snprintf
01596                         (bp, bspace, format,
01597                          ACE::timestamp (day_and_time, sizeof day_and_time));
01598                     else
01599                       this_len = ACE_OS::sprintf
01600                         (bp, format, ACE::timestamp (day_and_time,
01601                                                      sizeof day_and_time));
01602                     ACE_UPDATE_COUNT (bspace, this_len);
01603                     break;
01604                   }
01605 
01606                 case 't': // Format thread id.
01607 #if defined (ACE_WIN32)
01608                   ACE_OS::strcpy (fp, ACE_TEXT ("u"));
01609                   if (can_check)
01610                     this_len = ACE_OS::snprintf
01611                       (bp, bspace, format,
01612                        static_cast<unsigned> (ACE_Thread::self ()));
01613                   else
01614                     this_len =
01615                       ACE_OS::sprintf (bp,
01616                                        format,
01617                                        static_cast <unsigned> (ACE_Thread::self ()));
01618 #elif defined (DIGITAL_UNIX)
01619                   ACE_OS::strcpy (fp, ACE_TEXT ("u"));
01620                   {
01621                     int id =
01622 #  if defined (ACE_HAS_THREADS)
01623                       pthread_getselfseq_np ();
01624 #  else
01625                       ACE_Thread::self ();
01626 #  endif /* ACE_HAS_THREADS */
01627 
01628                       if (can_check)
01629                         this_len = ACE_OS::snprintf (bp, bspace, format, id);
01630                       else
01631                         this_len = ACE_OS::sprintf (bp, format, id);
01632                   }
01633 #else
01634                   ACE_hthread_t t_id;
01635                   ACE_Thread::self (t_id);
01636 
01637 #  if defined (ACE_MVS) || defined (ACE_TANDEM_T1248_PTHREADS)
01638                   // MVS's pthread_t is a struct... yuck. So use the ACE 5.0
01639                   // code for it.
01640                   ACE_OS::strcpy (fp, ACE_TEXT ("u"));
01641                   if (can_check)
01642                     this_len = ACE_OS::snprintf (bp, bspace, format, t_id);
01643                   else
01644                     this_len = ACE_OS::sprintf (bp, format, t_id);
01645 #  else
01646                   // Yes, this is an ugly C-style cast, but the correct
01647                   // C++ cast is different depending on whether the t_id
01648                   // is an integral type or a pointer type. FreeBSD uses
01649                   // a pointer type, but doesn't have a _np function to
01650                   // get an integral type, like the OSes above.
01651                   ACE_OS::strcpy (fp, ACE_TEXT ("lu"));
01652                   if (can_check)
01653                     this_len = ACE_OS::snprintf
01654                       (bp, bspace, format, (unsigned long)t_id);
01655                   else
01656                     this_len = ACE_OS::sprintf
01657                       (bp, format, (unsigned long)t_id);
01658 #  endif /* ACE_MWS || ACE_TANDEM_T1248_PTHREADS */
01659 
01660 #endif /* ACE_WIN32 */
01661                   ACE_UPDATE_COUNT (bspace, this_len);
01662                   break;
01663 
01664                 case 's':                       // String
01665                   {
01666 #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
01667                     wchar_t *str = va_arg (argp, wchar_t *);
01668                     ACE_OS::strcpy (fp, ACE_TEXT ("ls"));
01669 #else /* ACE_WIN32 && ACE_USES_WCHAR */
01670                     ACE_TCHAR *str = va_arg (argp, ACE_TCHAR *);
01671                     ACE_OS::strcpy (fp, ACE_TEXT ("s"));
01672 #endif /* ACE_WIN32 && ACE_USES_WCHAR */
01673                     if (can_check)
01674                       this_len = ACE_OS::snprintf
01675                         (bp, bspace, format, str ? str : ACE_TEXT ("(null)"));
01676                     else
01677                       this_len = ACE_OS::sprintf
01678                         (bp, format, str ? str : ACE_TEXT ("(null)"));
01679                     ACE_UPDATE_COUNT (bspace, this_len);
01680                   }
01681                   break;
01682 
01683                 case 'C':         // Char string, Unicode for Win32/WCHAR
01684                   {
01685                     ACE_TCHAR *cstr = va_arg (argp, ACE_TCHAR *);
01686 #if defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
01687                     ACE_OS::strcpy (fp, ACE_TEXT ("S"));
01688 #else /* ACE_WIN32 && ACE_USES_WCHAR */
01689                     ACE_OS::strcpy (fp, ACE_TEXT ("s"));
01690 #endif /* ACE_WIN32 && ACE_USES_WCHAR */
01691                     if (can_check)
01692                       this_len = ACE_OS::snprintf
01693                         (bp, bspace, format, cstr ? cstr : ACE_TEXT ("(null)"));
01694                     else
01695                       this_len = ACE_OS::sprintf
01696                         (bp, format, cstr ? cstr : ACE_TEXT ("(null)"));
01697                     ACE_UPDATE_COUNT (bspace, this_len);
01698                   }
01699                   break;
01700 
01701                 case 'W':
01702                   {
01703 #if defined (ACE_HAS_WCHAR)
01704                     wchar_t *wchar_str = va_arg (argp, wchar_t *);
01705 # if defined (HPUX)
01706                     ACE_OS::strcpy (fp, ACE_TEXT ("S"));
01707 # elif defined (ACE_WIN32)
01708 #   if defined (ACE_USES_WCHAR)
01709                     ACE_OS::strcpy (fp, ACE_TEXT ("s"));
01710 #   else /* ACE_USES_WCHAR */
01711                     ACE_OS::strcpy (fp, ACE_TEXT ("S"));
01712 #   endif /* ACE_USES_WCHAR */
01713 # else
01714                     ACE_OS::strcpy (fp, ACE_TEXT ("ls"));
01715 # endif /* HPUX */
01716                     if (can_check)
01717                       this_len = ACE_OS::snprintf
01718                         (bp, bspace, format, wchar_str ? wchar_str : ACE_TEXT_WIDE("(null)"));
01719                     else
01720                       this_len = ACE_OS::sprintf
01721                         (bp, format, wchar_str ? wchar_str : ACE_TEXT_WIDE("(null)"));
01722 #endif /* ACE_HAS_WCHAR */
01723                     ACE_UPDATE_COUNT (bspace, this_len);
01724                   }
01725                   break;
01726 
01727                 case 'w':              // Wide character
01728 #if defined (ACE_WIN32)
01729 # if defined (ACE_USES_WCHAR)
01730                   ACE_OS::strcpy (fp, ACE_TEXT ("c"));
01731 # else /* ACE_USES_WCHAR */
01732                   ACE_OS::strcpy (fp, ACE_TEXT ("C"));
01733 # endif /* ACE_USES_WCHAR */
01734                   if (can_check)
01735                     this_len = ACE_OS::snprintf
01736                       (bp, bspace, format, va_arg (argp, int));
01737                   else
01738                     this_len = ACE_OS::sprintf
01739                       (bp, format, va_arg (argp, int));
01740 #elif defined (ACE_USES_WCHAR)
01741 # if defined (HPUX)
01742                   ACE_OS::strcpy (fp, ACE_TEXT ("C"));
01743 # else
01744                   ACE_OS::strcpy (fp, ACE_TEXT ("lc"));
01745 # endif /* HPUX */
01746                   if (can_check)
01747                     this_len = ACE_OS::snprintf
01748                       (bp, bspace, format, va_arg (argp, wint_t));
01749                   else
01750                     this_len = ACE_OS::sprintf
01751                       (bp, format, va_arg (argp, wint_t));
01752 #else /* ACE_WIN32 */
01753                   ACE_OS::strcpy (fp, ACE_TEXT ("u"));
01754                   if (can_check)
01755                     this_len = ACE_OS::snprintf
01756                       (bp, bspace, format, va_arg (argp, int));
01757                   else
01758                     this_len = ACE_OS::sprintf
01759                       (bp, format, va_arg (argp, int));
01760 #endif /* ACE_WIN32 */
01761                   ACE_UPDATE_COUNT (bspace, this_len);
01762                   break;
01763 
01764                 case 'z':              // ACE_OS::WChar character
01765                   {
01766                     // On some platforms sizeof (wchar_t) can be 2
01767                     // on the others 4 ...
01768                     wchar_t wtchar =
01769                       static_cast<wchar_t> (va_arg (argp, int));
01770 #if defined (ACE_WIN32)
01771 # if defined (ACE_USES_WCHAR)
01772                     ACE_OS::strcpy (fp, ACE_TEXT ("c"));
01773 # else /* ACE_USES_WCHAR */
01774                     ACE_OS::strcpy (fp, ACE_TEXT ("C"));
01775 # endif /* ACE_USES_WCHAR */
01776 #elif defined (ACE_USES_WCHAR)
01777 # if defined (HPUX)
01778                     ACE_OS::strcpy (fp, ACE_TEXT ("C"));
01779 # else
01780                     ACE_OS::strcpy (fp, ACE_TEXT ("lc"));
01781 # endif /* HPUX */
01782 #else /* ACE_WIN32 */
01783                     ACE_OS::strcpy (fp, ACE_TEXT ("u"));
01784 #endif /* ACE_WIN32 */
01785                     if (can_check)
01786                       this_len = ACE_OS::snprintf (bp, bspace, format, wtchar);
01787                     else
01788                       this_len = ACE_OS::sprintf (bp, format, wtchar);
01789                     ACE_UPDATE_COUNT (bspace, this_len);
01790                     break;
01791                   }
01792 
01793                  case 'Z':              // ACE_OS::WChar character string
01794                   {
01795                     ACE_OS::WChar *wchar_str = va_arg (argp, ACE_OS::WChar*);
01796                     if (wchar_str == 0)
01797                       break;
01798 
01799                     wchar_t *wchar_t_str = 0;
01800                     if (sizeof (ACE_OS::WChar) != sizeof (wchar_t))
01801                       {
01802                         size_t len = ACE_OS::wslen (wchar_str) + 1;
01803                         ACE_NEW_NORETURN(wchar_t_str, wchar_t[len]);
01804                         if (wchar_t_str == 0)
01805                           break;
01806 
01807                         for (size_t i = 0; i < len; ++i)
01808                           {
01809                             wchar_t_str[i] = wchar_str[i];
01810                           }
01811                       }
01812 
01813                     if (wchar_t_str == 0)
01814                       {
01815                         wchar_t_str = reinterpret_cast<wchar_t*> (wchar_str);
01816                       }
01817 #if defined (ACE_WIN32)
01818 # if defined (ACE_USES_WCHAR)
01819                   ACE_OS::strcpy (fp, ACE_TEXT ("s"));
01820 # else /* ACE_USES_WCHAR */
01821                   ACE_OS::strcpy (fp, ACE_TEXT ("S"));
01822 # endif /* ACE_USES_WCHAR */
01823 #elif defined (ACE_HAS_WCHAR)
01824 # if defined (HPUX)
01825                   ACE_OS::strcpy (fp, ACE_TEXT ("S"));
01826 # else
01827                   ACE_OS::strcpy (fp, ACE_TEXT ("ls"));
01828 # endif /* HPUX */
01829 #endif /* ACE_WIN32 / ACE_HAS_WCHAR */
01830                   if (can_check)
01831                     this_len = ACE_OS::snprintf
01832                       (bp, bspace, format, wchar_t_str);
01833                   else
01834                     this_len = ACE_OS::sprintf (bp, format, wchar_t_str);
01835                   if(sizeof(ACE_OS::WChar) != sizeof(wchar_t))
01836                     {
01837                       delete [] wchar_t_str;
01838                     }
01839                   ACE_UPDATE_COUNT (bspace, this_len);
01840                   break;
01841                   }
01842 
01843                 case 'c':
01844 #if defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
01845                   ACE_OS::strcpy (fp, ACE_TEXT ("C"));
01846 #else
01847                   ACE_OS::strcpy (fp, ACE_TEXT ("c"));
01848 #endif /* ACE_WIN32 && ACE_USES_WCHAR */
01849                   if (can_check)
01850                     this_len = ACE_OS::snprintf
01851                       (bp, bspace, format, va_arg (argp, int));
01852                   else
01853                     this_len = ACE_OS::sprintf
01854                       (bp, format, va_arg (argp, int));
01855                   ACE_UPDATE_COUNT (bspace, this_len);
01856                   break;
01857 
01858                 case 'd': case 'i': case 'o':
01859                 case 'u': case 'x': case 'X':
01860                   fp[0] = *format_str;
01861                   fp[1] = '\0';
01862                   if (can_check)
01863                     this_len = ACE_OS::snprintf
01864                       (bp, bspace, format, va_arg (argp, int));
01865                   else
01866                     this_len = ACE_OS::sprintf
01867                       (bp, format, va_arg (argp, int));
01868                   ACE_UPDATE_COUNT (bspace, this_len);
01869                   break;
01870 
01871                 case 'F': case 'f': case 'e': case 'E':
01872                 case 'g': case 'G':
01873                   fp[0] = *format_str;
01874                   fp[1] = '\0';
01875                   if (can_check)
01876                     this_len = ACE_OS::snprintf
01877                       (bp, bspace, format, va_arg (argp, double));
01878                   else
01879                     this_len = ACE_OS::sprintf
01880                       (bp, format, va_arg (argp, double));
01881                   ACE_UPDATE_COUNT (bspace, this_len);
01882                   break;
01883 
01884                 case 'Q':
01885 #if defined (ACE_LACKS_LONGLONG_T) || defined (ACE_LACKS_UNSIGNEDLONGLONG_T)
01886                   {
01887                     // This relies on the ACE_U_LongLong storage layout.
01888                     ACE_UINT32 hi = va_arg (argp, ACE_UINT32);
01889                     ACE_UINT32 lo = va_arg (argp, ACE_UINT32);
01890                     if (hi > 0)
01891                       this_len = ACE_OS::sprintf (bp,
01892                                                   "0x%lx%0*lx",
01893                                                   hi,
01894                                                   2 * sizeof lo,
01895                                                   lo);
01896                     else
01897                       this_len = ACE_OS::sprintf (bp, "0x%lx", lo);
01898                   }
01899 #else  /* ! ACE_LACKS_LONGLONG_T */
01900                   {
01901                     const ACE_TCHAR *fmt = ACE_UINT64_FORMAT_SPECIFIER;
01902                     ACE_OS::strcpy (fp, &fmt[1]);    // Skip leading %
01903                     if (can_check)
01904                       this_len = ACE_OS::snprintf (bp, bspace,
01905                                                    format,
01906                                                    va_arg (argp, ACE_UINT64));
01907                     else
01908                       this_len = ACE_OS::sprintf (bp,
01909                                                   format,
01910                                                   va_arg (argp, ACE_UINT64));
01911                   }
01912 #endif /* ! ACE_LACKS_LONGLONG_T || ACE_LACKS_UNSIGNEDLONGLONG_T */
01913                   ACE_UPDATE_COUNT (bspace, this_len);
01914                   break;
01915 
01916                 case 'q':
01917  #if defined (ACE_LACKS_LONGLONG_T)
01918                    // No implementation available yet, no ACE_INT64 emulation
01919                    // available yet
01920  #else  /* ! ACE_LACKS_LONGLONG_T */
01921                    {
01922                      const ACE_TCHAR *fmt = ACE_INT64_FORMAT_SPECIFIER;
01923                      ACE_OS::strcpy (fp, &fmt[1]);    // Skip leading %
01924                      if (can_check)
01925                        this_len = ACE_OS::snprintf (bp, bspace,
01926                                                     format,
01927                                                     va_arg (argp, ACE_INT64));
01928                      else
01929                        this_len = ACE_OS::sprintf (bp,
01930                                                    format,
01931                                                    va_arg (argp, ACE_INT64));
01932                    }
01933  #endif /* ! ACE_LACKS_LONGLONG_T */
01934                    ACE_UPDATE_COUNT (bspace, this_len);
01935                    break;
01936 
01937                 case 'b':
01938                   {
01939                     const ACE_TCHAR *fmt = ACE_SSIZE_T_FORMAT_SPECIFIER;
01940                     ACE_OS::strcpy (fp, &fmt[1]);    // Skip leading %
01941                   }
01942                   if (can_check)
01943                     this_len = ACE_OS::snprintf (bp, bspace,
01944                                                  format,
01945                                                  va_arg (argp, ssize_t));
01946                   else
01947                     this_len = ACE_OS::sprintf (bp,
01948                                                 format,
01949                                                 va_arg (argp, ssize_t));
01950                   ACE_UPDATE_COUNT (bspace, this_len);
01951                   break;
01952 
01953                 case 'B':
01954                   {
01955                     const ACE_TCHAR *fmt = ACE_SIZE_T_FORMAT_SPECIFIER;
01956                     ACE_OS::strcpy (fp, &fmt[1]);    // Skip leading %
01957                   }
01958                   if (can_check)
01959                     this_len = ACE_OS::snprintf (bp, bspace,
01960                                                  format,
01961                                                  va_arg (argp, size_t));
01962                   else
01963                     this_len = ACE_OS::sprintf (bp,
01964                                                 format,
01965                                                 va_arg (argp, size_t));
01966                   ACE_UPDATE_COUNT (bspace, this_len);
01967                   break;
01968 
01969                 case ':':
01970                   {
01971                     // Assume a 32 bit time_t and change if needed.
01972                     const ACE_TCHAR *fmt = ACE_TEXT ("%d");
01973                     if (sizeof (time_t) == 8)
01974                       fmt = ACE_INT64_FORMAT_SPECIFIER;
01975 
01976                     ACE_OS::strcpy (fp, &fmt[1]);    // Skip leading %
01977                   }
01978                   if (can_check)
01979                     this_len = ACE_OS::snprintf (bp, bspace,
01980                                                  format,
01981                                                  va_arg (argp, time_t));
01982                   else
01983                     this_len = ACE_OS::sprintf (bp,
01984                                                 format,
01985                                                 va_arg (argp, time_t));
01986                   ACE_UPDATE_COUNT (bspace, this_len);
01987                   break;
01988 
01989                 case '@':
01990                     ACE_OS::strcpy (fp, ACE_TEXT ("p"));
01991                     if (can_check)
01992                       this_len = ACE_OS::snprintf
01993                         (bp, bspace, format, va_arg (argp, void*));
01994                     else
01995                       this_len = ACE_OS::sprintf
01996                         (bp, format, va_arg (argp, void*));
01997                     ACE_UPDATE_COUNT (bspace, this_len);
01998                     break;
01999 
02000                 default:
02001                   // So, it's not a legit format specifier after all...
02002                   // Copy from the original % to where we are now, then
02003                   // continue with whatever comes next.
02004                   while (start_format != format_str && bspace > 0)
02005                     {
02006                       *bp++ = *start_format++;
02007                       --bspace;
02008                     }
02009                   if (bspace > 0)
02010                     {
02011                       *bp++ = *format_str;
02012                       --bspace;
02013                     }
02014                   break;
02015                 }
02016 
02017               // Bump to the next char in the caller's format_str
02018               ++format_str;
02019             }
02020 
02021           if (!skip_nul_locate)
02022             while (*bp != '\0') // Locate end of bp.
02023               ++bp;
02024         }
02025     }
02026 
02027   *bp = '\0'; // Terminate bp, but don't auto-increment this!
02028 
02029   ssize_t result = 0;
02030 
02031   // Check that memory was not corrupted, if it corrupted we can't log anything
02032   // anymore because all our members could be corrupted.
02033   if (bp >= (this->msg_ + ACE_MAXLOGMSGLEN+1))
02034     {
02035       abort_prog = true;
02036       ACE_OS::fprintf (stderr,
02037                        "The following logged message is too long!\n");
02038     }
02039   else
02040     {
02041       // Copy the message from thread-specific storage into the transfer
02042       // buffer (this can be optimized away by changing other code...).
02043       log_record.msg_data (this->msg ());
02044 
02045       // Write the <log_record> to the appropriate location.
02046       result = this->log (log_record,
02047                           abort_prog);
02048     }
02049 
02050   if (abort_prog)
02051     {
02052       // Since we are now calling abort instead of exit, this value is
02053       // not used.
02054       ACE_UNUSED_ARG (exit_value);
02055 
02056       // *Always* print a message to stderr if we're aborting.  We
02057       // don't use verbose, however, to avoid recursive aborts if
02058       // something is hosed.
02059       log_record.print (ACE_Log_Msg::local_host_, 0, stderr);
02060       ACE_OS::abort ();
02061     }
02062 
02063    return result;
02064 }
02065 
02066 #if !defined (ACE_WIN32)
02067 /**
02068  * @class ACE_Log_Msg_Sig_Guard
02069  *
02070  * @brief For use only by ACE_Log_Msg.
02071  *
02072  * Doesn't require the use of global variables or global
02073  * functions in an application).
02074  */
02075 class ACE_Log_Msg_Sig_Guard
02076 {
02077 private:
02078   ACE_Log_Msg_Sig_Guard (void);
02079   ~ACE_Log_Msg_Sig_Guard (void);
02080 
02081   /// Original signal mask.
02082   sigset_t omask_;
02083 
02084   friend ssize_t ACE_Log_Msg::log (ACE_Log_Record &log_record,
02085                                    int suppress_stderr);
02086 };
02087 
02088 ACE_Log_Msg_Sig_Guard::ACE_Log_Msg_Sig_Guard (void)
02089 {
02090 #if !defined (ACE_LACKS_UNIX_SIGNALS)
02091   ACE_OS::sigemptyset (&this->omask_);
02092 
02093 #  if defined (ACE_LACKS_PTHREAD_THR_SIGSETMASK)
02094   ACE_OS::sigprocmask (SIG_BLOCK,
02095                        ACE_OS_Object_Manager::default_mask (),
02096                        &this->omask_);
02097 #  else
02098   ACE_OS::thr_sigsetmask (SIG_BLOCK,
02099                           ACE_OS_Object_Manager::default_mask (),
02100                           &this->omask_);
02101 #  endif /* ACE_LACKS_PTHREAD_THR_SIGSETMASK */
02102 #endif /* ACE_LACKS_UNIX_SIGNALS */
02103 }
02104 
02105 ACE_Log_Msg_Sig_Guard::~ACE_Log_Msg_Sig_Guard (void)
02106 {
02107 #if !defined (ACE_LACKS_UNIX_SIGNALS)
02108 # if defined (ACE_LACKS_PTHREAD_THR_SIGSETMASK)
02109   ACE_OS::sigprocmask (SIG_SETMASK,
02110                        &this->omask_,
02111                        0);
02112 # else
02113   ACE_OS::thr_sigsetmask (SIG_SETMASK,
02114                           &this->omask_,
02115                           0);
02116 # endif /* ACE_LACKS_PTHREAD_THR_SIGSETMASK */
02117 #endif /* ! ACE_LACKS_UNIX_SIGNALS */
02118 }
02119 #endif /* ! ACE_WIN32 */
02120 
02121 ssize_t
02122 ACE_Log_Msg::log (ACE_Log_Record &log_record,
02123                   int suppress_stderr)
02124 {
02125   ssize_t result = 0;
02126 
02127   // Format the message and print it to stderr and/or ship it off to
02128   // the log_client daemon, and/or print it to the ostream.  Of
02129   // course, only print the message if "SILENT" mode is disabled.
02130   if (ACE_BIT_DISABLED (ACE_Log_Msg::flags_,
02131                         ACE_Log_Msg::SILENT))
02132     {
02133       int tracing = this->tracing_enabled ();
02134       this->stop_tracing ();
02135 
02136 #if !defined (ACE_WIN32)
02137       // Make this block signal-safe.
02138       ACE_Log_Msg_Sig_Guard sb;
02139 #endif /* !ACE_WIN32 */
02140 
02141       // Do the callback, if needed, before acquiring the lock
02142       // to avoid holding the lock during the callback so we don't
02143       // have deadlock if the callback uses the logger.
02144       if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_,
02145                            ACE_Log_Msg::MSG_CALLBACK)
02146           && this->msg_callback () != 0)
02147         this->msg_callback ()->log (log_record);
02148 
02149       // Make sure that the lock is held during all this.
02150       ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
02151                                 *ACE_Log_Msg_Manager::get_lock (),
02152                                 -1));
02153 
02154       if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_,
02155                            ACE_Log_Msg::STDERR)
02156           && !suppress_stderr) // This is taken care of by our caller.
02157         log_record.print (ACE_Log_Msg::local_host_,
02158                           ACE_Log_Msg::flags_,
02159                           stderr);
02160 
02161       if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::CUSTOM) ||
02162           ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::SYSLOG) ||
02163           ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::LOGGER))
02164         {
02165           // Be sure that there is a message_queue_, with multiple threads.
02166           ACE_MT (ACE_Log_Msg_Manager::init_backend ());
02167         }
02168 
02169 
02170       if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::LOGGER) ||
02171           ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::SYSLOG))
02172         {
02173           result =
02174             ACE_Log_Msg_Manager::log_backend_->log (log_record);
02175         }
02176 
02177       if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::CUSTOM) &&
02178           ACE_Log_Msg_Manager::custom_backend_ != 0)
02179         {
02180           result =
02181             ACE_Log_Msg_Manager::custom_backend_->log (log_record);
02182         }
02183 
02184 
02185       // This must come last, after the other two print operations
02186       // (see the <ACE_Log_Record::print> method for details).
02187       if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_,
02188                            ACE_Log_Msg::OSTREAM)
02189           && this->msg_ostream () != 0)
02190         log_record.print (ACE_Log_Msg::local_host_,
02191                           ACE_Log_Msg::flags_,
02192 #if defined (ACE_LACKS_IOSTREAM_TOTALLY)
02193                           static_cast<FILE *> (this->msg_ostream ())
02194 #else  /* ! ACE_LACKS_IOSTREAM_TOTALLY */
02195                           *this->msg_ostream ()
02196 #endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */
02197                           );
02198 
02199       if (tracing)
02200         this->start_tracing ();
02201    }
02202 
02203   return result;
02204 }
02205 
02206 // Calls log to do the actual print, but formats first.
02207 
02208 int
02209 ACE_Log_Msg::log_hexdump (ACE_Log_Priority log_priority,
02210                           const char *buffer,
02211                           size_t size,
02212                           const ACE_TCHAR *text)
02213 {
02214   // Only print the message if <priority_mask_> hasn't been reset to
02215   // exclude this logging priority.
02216   if (this->log_priority_enabled (log_priority) == 0)
02217     return 0;
02218 
02219   ACE_TCHAR* buf = 0;
02220   const size_t buf_sz =
02221     ACE_Log_Record::MAXLOGMSGLEN - ACE_Log_Record::VERBOSE_LEN - 58;
02222   ACE_NEW_RETURN (buf, ACE_TCHAR[buf_sz], -1);
02223 
02224   ACE_TCHAR *msg_buf = 0;
02225   const size_t text_sz = text ? ACE_OS::strlen(text) : 0;
02226   ACE_NEW_RETURN (msg_buf,
02227                   ACE_TCHAR[text_sz + 58],
02228                  -1);
02229 
02230   buf[0] = 0; // in case size = 0
02231 
02232   const size_t len = ACE::format_hexdump
02233     (buffer, size, buf, buf_sz / sizeof (ACE_TCHAR) - text_sz);
02234 
02235   int sz = 0;
02236 
02237   if (text)
02238     sz = ACE_OS::sprintf (msg_buf,
02239                           ACE_TEXT ("%s - "),
02240                           text);
02241 
02242   sz += ACE_OS::sprintf (msg_buf + sz,
02243                          ACE_TEXT ("HEXDUMP ")
02244                          ACE_SIZE_T_FORMAT_SPECIFIER
02245                          ACE_TEXT (" bytes"),
02246                          size);
02247 
02248   if (len < size)
02249     ACE_OS::sprintf (msg_buf + sz,
02250                      ACE_TEXT (" (showing first ")
02251                      ACE_SIZE_T_FORMAT_SPECIFIER
02252                      ACE_TEXT (" bytes)"),
02253                      len);
02254 
02255   // Now print out the formatted buffer.
02256   this->log (log_priority,
02257              ACE_TEXT ("%s\n%s"),
02258              msg_buf,
02259              buf);
02260 
02261   delete [] msg_buf;
02262   delete [] buf;
02263   return 0;
02264 }
02265 
02266 void
02267 ACE_Log_Msg::set (const char *filename,
02268                   int line,
02269                   int status,
02270                   int err,
02271                   int rs,
02272                   ACE_OSTREAM_TYPE *os,
02273                   ACE_Log_Msg_Callback *c)
02274 {
02275   ACE_TRACE ("ACE_Log_Msg::set");
02276   this->file (filename);
02277   this->linenum (line);
02278   this->op_status (status);
02279   this->errnum (err);
02280   this->restart (rs);
02281   this->msg_ostream (os);
02282   this->msg_callback (c);
02283 }
02284 
02285 void
02286 ACE_Log_Msg::conditional_set (const char *filename,
02287                               int line,
02288                               int status,
02289                               int err)
02290 {
02291   this->conditional_values_.is_set_ = true;
02292   this->conditional_values_.file_ = filename;
02293   this->conditional_values_.line_ = line;
02294   this->conditional_values_.op_status_ = status;
02295   this->conditional_values_.errnum_ = err;
02296 }
02297 
02298 void
02299 ACE_Log_Msg::dump (void) const
02300 {
02301 #if defined (ACE_HAS_DUMP)
02302   ACE_TRACE ("ACE_Log_Msg::dump");
02303 
02304   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
02305   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("status_ = %d\n"), this->status_));
02306   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nerrnum_ = %d\n"), this->errnum_));
02307   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nlinenum_ = %d\n"), this->linenum_));
02308   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nfile_ = %C\n"), this->file_));
02309   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nmsg_ = %s\n"), this->msg_));
02310   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nrestart_ = %d\n"), this->restart_));
02311   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nostream_ = %@\n"), this->ostream_));
02312   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nmsg_callback_ = %@\n"),
02313               this->msg_callback_));
02314   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nprogram_name_ = %s\n"),
02315               this->program_name_ ? this->program_name_
02316                                   : ACE_TEXT ("<unknown>")));
02317   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nlocal_host_ = %s\n"),
02318               this->local_host_ ? this->local_host_
02319                                 : ACE_TEXT ("<unknown>")));
02320   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\npid_ = %d\n"), this->getpid ()));
02321   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nflags_ = 0x%x\n"), this->flags_));
02322   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ntrace_depth_ = %d\n"),
02323               this->trace_depth_));
02324   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ntrace_active_ = %d\n"),
02325               this->trace_active_));
02326   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ntracing_enabled_ = %d\n"),
02327               this->tracing_enabled_));
02328   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\npriority_mask_ = 0x%x\n"),
02329               this->priority_mask_));
02330   if (this->thr_desc_ != 0 && this->thr_desc_->state () != 0)
02331     ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nthr_state_ = %d\n"),
02332                 this->thr_desc_->state ()));
02333   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nmsg_off_ = %d\n"), this->msg_off_));
02334 
02335   // Be sure that there is a message_queue_, with multiple threads.
02336   ACE_MT (ACE_Log_Msg_Manager::init_backend ());
02337 
02338   ACE_MT (ACE_Log_Msg_Manager::get_lock ()->dump ());
02339   // Synchronize output operations.
02340 
02341   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
02342 #endif /* ACE_HAS_DUMP */
02343 }
02344 
02345 void
02346 ACE_Log_Msg::op_status (int status)
02347 {
02348   this->status_ = status;
02349 }
02350 
02351 int
02352 ACE_Log_Msg::op_status (void)
02353 {
02354   return this->status_;
02355 }
02356 
02357 void
02358 ACE_Log_Msg::restart (int r)
02359 {
02360   this->restart_ = r;
02361 }
02362 
02363 int
02364 ACE_Log_Msg::restart (void)
02365 {
02366   return this->restart_;
02367 }
02368 
02369 int
02370 ACE_Log_Msg::errnum (void)
02371 {
02372   return this->errnum_;
02373 }
02374 
02375 void
02376 ACE_Log_Msg::errnum (int e)
02377 {
02378   this->errnum_ = e;
02379 }
02380 
02381 int
02382 ACE_Log_Msg::linenum (void)
02383 {
02384   return this->linenum_;
02385 }
02386 
02387 void
02388 ACE_Log_Msg::linenum (int l)
02389 {
02390   this->linenum_ = l;
02391 }
02392 
02393 int
02394 ACE_Log_Msg::inc (void)
02395 {
02396   return this->trace_depth_++;
02397 }
02398 
02399 int
02400 ACE_Log_Msg::dec (void)
02401 {
02402   return this->trace_depth_ == 0 ? 0 : --this->trace_depth_;
02403 }
02404 
02405 int
02406 ACE_Log_Msg::trace_depth (void)
02407 {
02408   return this->trace_depth_;
02409 }
02410 
02411 void
02412 ACE_Log_Msg::trace_depth (int depth)
02413 {
02414   this->trace_depth_ = depth;
02415 }
02416 
02417 int
02418 ACE_Log_Msg::trace_active (void)
02419 {
02420   return this->trace_active_;
02421 }
02422 
02423 void
02424 ACE_Log_Msg::trace_active (int value)
02425 {
02426   this->trace_active_ = value;
02427 }
02428 
02429 ACE_Thread_Descriptor *
02430 ACE_Log_Msg::thr_desc (void) const
02431 {
02432   return this->thr_desc_;
02433 }
02434 
02435 void
02436 ACE_Log_Msg::thr_desc (ACE_Thread_Descriptor *td)
02437 {
02438   this->thr_desc_ = td;
02439 
02440   if (td != 0)
02441     td->acquire_release ();
02442 }
02443 
02444 #if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS) && defined(ACE_LEGACY_MODE)
02445 ACE_SEH_EXCEPT_HANDLER
02446 ACE_Log_Msg::seh_except_selector (void)
02447 {
02448   return ACE_OS_Object_Manager::seh_except_selector ();
02449 }
02450 
02451 ACE_SEH_EXCEPT_HANDLER
02452 ACE_Log_Msg::seh_except_selector (ACE_SEH_EXCEPT_HANDLER n)
02453 {
02454   return ACE_OS_Object_Manager::seh_except_selector (n);
02455 }
02456 
02457 ACE_SEH_EXCEPT_HANDLER
02458 ACE_Log_Msg::seh_except_handler (void)
02459 {
02460   return ACE_OS_Object_Manager::seh_except_handler ();
02461 }
02462 
02463 ACE_SEH_EXCEPT_HANDLER
02464 ACE_Log_Msg::seh_except_handler (ACE_SEH_EXCEPT_HANDLER n)
02465 {
02466   return ACE_OS_Object_Manager::seh_except_handler (n);
02467 }
02468 #endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS && ACE_LEGACY_MODE */
02469 
02470 // Enable the tracing facility on a per-thread basis.
02471 
02472 void
02473 ACE_Log_Msg::start_tracing (void)
02474 {
02475   this->tracing_enabled_ = 1;
02476 }
02477 
02478 // Disable the tracing facility on a per-thread basis.
02479 
02480 void
02481 ACE_Log_Msg::stop_tracing (void)
02482 {
02483   this->tracing_enabled_ = 0;
02484 }
02485 
02486 int
02487 ACE_Log_Msg::tracing_enabled (void)
02488 {
02489   return this->tracing_enabled_;
02490 }
02491 
02492 const char *
02493 ACE_Log_Msg::file (void)
02494 {
02495   return this->file_;
02496 }
02497 
02498 void
02499 ACE_Log_Msg::file (const char *s)
02500 {
02501   ACE_OS::strsncpy (this->file_, s, sizeof this->file_);
02502 }
02503 
02504 const ACE_TCHAR *
02505 ACE_Log_Msg::msg (void)
02506 {
02507   return this->msg_ + ACE_Log_Msg::msg_off_;
02508 }
02509 
02510 void
02511 ACE_Log_Msg::msg (const ACE_TCHAR *m)
02512 {
02513   ACE_OS::strsncpy (this->msg_, m,
02514                     ((ACE_MAXLOGMSGLEN+1) / sizeof (ACE_TCHAR)));
02515 }
02516 
02517 ACE_Log_Msg_Callback *
02518 ACE_Log_Msg::msg_callback (void) const
02519 {
02520   return this->msg_callback_;
02521 }
02522 
02523 ACE_Log_Msg_Callback *
02524 ACE_Log_Msg::msg_callback (ACE_Log_Msg_Callback *c)
02525 {
02526   ACE_Log_Msg_Callback *old = this->msg_callback_;
02527   this->msg_callback_ = c;
02528   return old;
02529 }
02530 
02531 ACE_Log_Msg_Backend *
02532 ACE_Log_Msg::msg_backend (ACE_Log_Msg_Backend *b)
02533 {
02534   ACE_TRACE ("ACE_Log_Msg::msg_backend");
02535   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
02536                             *ACE_Log_Msg_Manager::get_lock (), 0));
02537 
02538   ACE_Log_Msg_Backend *tmp  = ACE_Log_Msg_Manager::custom_backend_;
02539   ACE_Log_Msg_Manager::custom_backend_ = b;
02540   return tmp;
02541 }
02542 
02543 ACE_Log_Msg_Backend *
02544 ACE_Log_Msg::msg_backend (void)
02545 {
02546   ACE_TRACE ("ACE_Log_Msg::msg_backend");
02547   ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
02548                             *ACE_Log_Msg_Manager::get_lock (), 0));
02549 
02550   return ACE_Log_Msg_Manager::custom_backend_;
02551 }
02552 
02553 ACE_OSTREAM_TYPE *
02554 ACE_Log_Msg::msg_ostream (void) const
02555 {
02556   return this->ostream_;
02557 }
02558 
02559 void
02560 ACE_Log_Msg::msg_ostream (ACE_OSTREAM_TYPE *m, int delete_ostream)
02561 {
02562   if (this->ostream_ == m)
02563     return;
02564 
02565   if (this->delete_ostream_)
02566     {
02567 #if defined (ACE_LACKS_IOSTREAM_TOTALLY)
02568       ACE_OS::fclose (this->ostream_);
02569 #else
02570       delete this->ostream_;
02571 #endif
02572     }
02573 
02574   this->delete_ostream_ = delete_ostream;
02575   this->ostream_ = m;
02576 }
02577 
02578 void
02579 ACE_Log_Msg::msg_ostream (ACE_OSTREAM_TYPE *m)
02580 {
02581   this->ostream_ = m;
02582 }
02583 
02584 void
02585 ACE_Log_Msg::local_host (const ACE_TCHAR *s)
02586 {
02587   if (s)
02588     {
02589       ACE_OS::free ((void *) ACE_Log_Msg::local_host_);
02590       {
02591         ACE_NO_HEAP_CHECK;
02592 
02593         ACE_ALLOCATOR (ACE_Log_Msg::local_host_, ACE_OS::strdup (s));
02594       }
02595     }
02596 }
02597 
02598 const ACE_TCHAR *
02599 ACE_Log_Msg::local_host (void) const
02600 {
02601   return ACE_Log_Msg::local_host_;
02602 }
02603 
02604 pid_t
02605 ACE_Log_Msg::getpid (void) const
02606 {
02607   if (ACE_Log_Msg::pid_ == -1)
02608     ACE_Log_Msg::pid_ = ACE_OS::getpid ();
02609 
02610   return ACE_Log_Msg::pid_;
02611 }
02612 
02613 int
02614 ACE_Log_Msg::log_priority_enabled (ACE_Log_Priority log_priority,
02615                                    const char *,
02616                                    ...)
02617 {
02618   return this->log_priority_enabled (log_priority);
02619 }
02620 
02621 #if defined (ACE_USES_WCHAR)
02622 int
02623 ACE_Log_Msg::log_priority_enabled (ACE_Log_Priority log_priority,
02624                                    const wchar_t *,
02625                                    ...)
02626 {
02627   return this->log_priority_enabled (log_priority);
02628 }
02629 #endif /* ACE_USES_WCHAR */
02630 
02631 // ****************************************************************
02632 
02633 void
02634 ACE_Log_Msg::init_hook (ACE_OS_Log_Msg_Attributes &attributes
02635 # if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
02636                         , ACE_SEH_EXCEPT_HANDLER selector
02637                         , ACE_SEH_EXCEPT_HANDLER handler
02638 # endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
02639                                    )
02640 {
02641 # if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
02642   attributes.seh_except_selector_ = selector;
02643   attributes.seh_except_handler_ = handler;
02644 # endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
02645   if (ACE_Log_Msg::exists ())
02646     {
02647       ACE_Log_Msg *inherit_log = ACE_LOG_MSG;
02648       attributes.ostream_ = inherit_log->msg_ostream ();
02649       attributes.priority_mask_ = inherit_log->priority_mask ();
02650       attributes.tracing_enabled_ = inherit_log->tracing_enabled ();
02651       attributes.restart_ = inherit_log->restart ();
02652       attributes.trace_depth_ = inherit_log->trace_depth ();
02653     }
02654 }
02655 
02656 void
02657 ACE_Log_Msg::inherit_hook (ACE_OS_Thread_Descriptor *thr_desc,
02658                            ACE_OS_Log_Msg_Attributes &attributes)
02659 {
02660 #if !defined (ACE_THREADS_DONT_INHERIT_LOG_MSG)  && \
02661     !defined (ACE_HAS_MINIMAL_ACE_OS)
02662   // Inherit the logging features if the parent thread has an
02663   // <ACE_Log_Msg>.  Note that all of the following operations occur
02664   // within thread-specific storage.
02665   ACE_Log_Msg *new_log = ACE_LOG_MSG;
02666 
02667   // Note that we do not inherit the callback because this might have
02668   // been allocated off of the stack of the original thread, in which
02669   // case all hell would break loose...
02670 
02671   if (attributes.ostream_)
02672     {
02673       new_log->msg_ostream (attributes.ostream_);
02674       new_log->priority_mask (attributes.priority_mask_);
02675 
02676       if (attributes.tracing_enabled_)
02677         new_log->start_tracing ();
02678 
02679       new_log->restart (attributes.restart_);
02680       new_log->trace_depth (attributes.trace_depth_);
02681     }
02682 
02683   // @@ Now the TSS Log_Msg has been created, cache my thread
02684   // descriptor in.
02685 
02686   if (thr_desc != 0)
02687     // This downcast is safe.  We do it to avoid having to #include
02688     // ace/Thread_Manager.h.
02689     new_log->thr_desc (static_cast<ACE_Thread_Descriptor *> (thr_desc));
02690   // Block the thread from proceeding until
02691   // thread manager has thread descriptor ready.
02692 #endif /* ! ACE_THREADS_DONT_INHERIT_LOG_MSG  &&  ! ACE_HAS_MINIMAL_ACE_OS */
02693 }
02694 
02695 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Sun Jan 27 12:05:29 2008 for ACE by doxygen 1.3.6