Log_Msg.cpp

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

Generated on Tue Feb 2 17:18:40 2010 for ACE by  doxygen 1.4.7