3 // ============================================================================
5 * @file Test_Output.cpp
7 * This file factors out common macros and other utilities used by the
8 * ACE automated regression tests.
10 * @author Prashant Jain <pjain@cs.wustl.edu>
11 * @author Tim Harrison <harrison@cs.wustl.edu>
12 * @author David Levine <levine@cs.wustl.edu>
13 * @author Don Hinton <dhinton@dresystems.com>
15 // ============================================================================
17 #include "test_config.h"
18 #include "ace/OS_NS_stdio.h"
19 #include "ace/OS_NS_string.h"
20 #include "ace/OS_NS_sys_stat.h"
21 #include "ace/Guard_T.h"
22 #include "ace/Object_Manager.h"
24 // FUZZ: disable check_for_streams_include
25 #include "ace/streams.h"
27 #include "ace/Framework_Component.h"
28 #include "ace/Log_Msg.h"
32 # include "ace/OS_NS_unistd.h"
33 # include "ace/OS_NS_fcntl.h"
36 ACE_Test_Output
*ACE_Test_Output::instance_
= 0;
38 ACE_Test_Output::ACE_Test_Output ()
41 #if !defined (ACE_LACKS_IOSTREAM_TOTALLY)
42 this->output_file_
= new OFSTREAM
;
43 #endif /* ACE_LACKS_IOSTREAM_TOTALLY */
46 ACE_Test_Output::~ACE_Test_Output ()
48 #if !defined (ACE_LACKS_IOSTREAM_TOTALLY)
49 ACE_LOG_MSG
->msg_ostream (&cerr
, 0);
50 #endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */
52 ACE_LOG_MSG
->clr_flags (ACE_Log_Msg::OSTREAM
);
53 ACE_LOG_MSG
->set_flags (ACE_Log_Msg::STDERR
);
55 #if !defined (ACE_LACKS_IOSTREAM_TOTALLY)
56 delete this->output_file_
;
57 #endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */
61 ACE_Test_Output::output_file ()
63 // the output_file_ is loaned to ACE_LOG_MSG
64 // and something else might destroy and/or change the stream
65 // so return what ACE_LOG_MSG is using.
66 #if defined (ACE_LACKS_IOSTREAM_TOTALLY)
67 return reinterpret_cast<OFSTREAM
*>(ACE_LOG_MSG
->msg_ostream ());
69 return dynamic_cast<OFSTREAM
*>(ACE_LOG_MSG
->msg_ostream ());
70 #endif /* ACE_LACKS_IOSTREAM_TOTALLY */
74 ACE_Test_Output::set_output (const ACE_TCHAR
*filename
, int append
)
76 ACE_TCHAR temp
[MAXPATHLEN
+ 1] = { 0 };
77 // Ignore the error value since the directory may already exist.
78 const ACE_TCHAR
*test_dir
= 0;
80 #if defined (ACE_WIN32) || !defined (ACE_USES_WCHAR)
81 test_dir
= ACE_OS::getenv (ACE_TEXT ("ACE_TEST_DIR"));
83 ACE_TCHAR tempenv
[MAXPATHLEN
+ 1] = { 0 };
84 char const * const test_dir_n
= ACE_OS::getenv ("ACE_TEST_DIR");
91 ACE_OS::strncpy (tempenv
,
92 ACE_TEXT_CHAR_TO_TCHAR (test_dir_n
),
97 #endif /* ACE_WIN32 */
99 test_dir
= ACE_DEFAULT_TEST_DIR
;
101 // This could be done with ACE_OS::sprintf() but it requires different
102 // format strings for wide-char POSIX vs. narrow-char POSIX and Windows.
103 // Easier to keep straight like this.
104 ACE_OS::strncpy (temp
, test_dir
, MAXPATHLEN
);
105 ACE_OS::strcat (temp
, ACE_LOG_DIRECTORY
);
106 ACE_OS::strcat (temp
,
107 ACE::basename (filename
, ACE_DIRECTORY_SEPARATOR_CHAR
));
108 ACE_OS::strcat (temp
, ACE_LOG_FILE_EXT_NAME
);
110 #if defined (ACE_VXWORKS)
111 // This is the only way I could figure out to avoid a console
112 // warning about opening an existing file (w/o O_CREAT), or
113 // attempting to unlink a non-existent one.
114 ACE_HANDLE fd
= ACE_OS::open (temp
,
116 S_IRUSR
|S_IWUSR
|S_IRGRP
|S_IROTH
);
120 ACE_OS::unlink (temp
);
122 #else /* ! ACE_VXWORKS */
123 // This doesn't seem to work on VxWorks if the directory doesn't
124 // exist: it creates a plain file instead of a directory. If the
125 // directory does exist, it causes a weird console error message
126 // about "cat: input error on standard input: Is a directory". So,
127 // VxWorks users must create the directory manually.
128 ACE_OS::mkdir (ACE_LOG_DIRECTORY_FOR_MKDIR
);
129 #endif /* ACE_VXWORKS */
131 # if !defined (ACE_LACKS_IOSTREAM_TOTALLY)
132 this->output_file_
->open (ACE_TEXT_ALWAYS_CHAR (temp
),
133 ios::out
| (append
? ios::app
: ios::trunc
));
134 if (!this->output_file_
->good ())
136 #else /* when ACE_LACKS_IOSTREAM_TOTALLY */
137 const ACE_TCHAR
*fmode
= 0;
139 fmode
= ACE_TEXT ("a");
141 fmode
= ACE_TEXT ("w");
142 this->output_file_
= ACE_OS::fopen (temp
, fmode
);
143 # endif /* ACE_LACKS_IOSTREAM_TOTALLY */
145 ACE_LOG_MSG
->msg_ostream (this->output_file_
, 0);
146 ACE_LOG_MSG
->clr_flags (ACE_Log_Msg::STDERR
| ACE_Log_Msg::LOGGER
);
147 ACE_LOG_MSG
->set_flags (ACE_Log_Msg::OSTREAM
);
153 ACE_Test_Output::close ()
155 if (this->output_file_
&&
156 (this->output_file_
== ACE_LOG_MSG
->msg_ostream ()))
158 #if !defined (ACE_LACKS_IOSTREAM_TOTALLY)
159 this->output_file_
->flush ();
160 this->output_file_
->close ();
162 ACE_OS::fflush (this->output_file_
);
163 ACE_OS::fclose (this->output_file_
);
164 #endif /* !ACE_LACKS_IOSTREAM_TOTALLY */
165 ACE_LOG_MSG
->msg_ostream (0, 0);
167 // else something else changed the stream and hence should
168 // have closed the output_file_
172 ACE_Test_Output::instance ()
174 if (ACE_Test_Output::instance_
== 0)
176 // Perform Double-Checked Locking Optimization.
177 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex
, ace_mon
,
178 *ACE_Static_Object_Lock::instance (), 0));
180 if (ACE_Test_Output::instance_
== 0)
182 ACE_NEW_RETURN (ACE_Test_Output::instance_
,
185 ACE_REGISTER_FRAMEWORK_COMPONENT(ACE_Test_Output
, ACE_Test_Output::instance_
)
188 return ACE_Test_Output::instance_
;
192 ACE_Test_Output::dll_name ()
194 return ACE_TEXT ("Test_Output");
198 ACE_Test_Output::name ()
200 return ACE_TEXT ("ACE_Test_Output");
204 ACE_Test_Output::close_singleton ()
206 delete ACE_Test_Output::instance_
;
207 ACE_Test_Output::instance_
= 0;