Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Log_Msg.cpp

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

Generated on Mon Jun 16 11:20:00 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002