summaryrefslogtreecommitdiff
path: root/trunk/ACE/ace/OS_NS_stdio.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/ACE/ace/OS_NS_stdio.cpp')
-rw-r--r--trunk/ACE/ace/OS_NS_stdio.cpp425
1 files changed, 425 insertions, 0 deletions
diff --git a/trunk/ACE/ace/OS_NS_stdio.cpp b/trunk/ACE/ace/OS_NS_stdio.cpp
new file mode 100644
index 00000000000..c4b23cb1904
--- /dev/null
+++ b/trunk/ACE/ace/OS_NS_stdio.cpp
@@ -0,0 +1,425 @@
+// $Id$
+
+#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_Thread.h"
+
+ACE_RCSID (ace,
+ OS_NS_stdio,
+ "$Id$")
+
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_stdio.inl"
+#endif /* ACE_HAS_INLINED_OSCALLS */
+
+# if defined (ACE_WIN32)
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+ACE_TEXT_OSVERSIONINFO ACE_OS::win32_versioninfo_;
+HINSTANCE ACE_OS::win32_resource_module_;
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+# if defined (ACE_HAS_DLL) && (ACE_HAS_DLL == 1) && !defined (ACE_HAS_WINCE)
+// This function is called by the OS when the ACE DLL is loaded. We
+// use it to determine the default module containing ACE's resources.
+extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID)
+{
+ if (reason == DLL_PROCESS_ATTACH)
+ {
+# if defined (ACE_DISABLES_THREAD_LIBRARY_CALLS) && (ACE_DISABLES_THREAD_LIBRARY_CALLS == 1)
+ ::DisableThreadLibraryCalls (instance);
+# endif /* ACE_DISABLES_THREAD_LIBRARY_CALLS */
+ ACE_OS::set_win32_resource_module(instance);
+ }
+ else if (reason == DLL_THREAD_DETACH)
+ {
+ ACE_OS::cleanup_tss (0);
+ }
+ return TRUE;
+}
+# endif /* ACE_HAS_DLL && ACE_HAS_DLL == 1 */
+# endif /* ACE_WIN32 */
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+void
+ACE_OS::ace_flock_t::dump (void) const
+{
+#if defined (ACE_HAS_DUMP)
+ ACE_OS_TRACE ("ACE_OS::ace_flock_t::dump");
+
+# if 0
+ ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("handle_ = %u"), this->handle_));
+# if defined (ACE_WIN32)
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nInternal = %d"),
+ this->overlapped_.Internal));
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nInternalHigh = %d"),
+ this->overlapped_.InternalHigh));
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nOffsetHigh = %d"),
+ this->overlapped_.OffsetHigh));
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nhEvent = %d"),
+ this->overlapped_.hEvent));
+# else
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nl_whence = %d"),
+ this->lock_.l_whence));
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nl_start = %d"), this->lock_.l_start));
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nl_len = %d"), this->lock_.l_len));
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nl_type = %d"), this->lock_.l_type));
+# endif /* ACE_WIN32 */
+ ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
+# endif /* 0 */
+#endif /* ACE_HAS_DUMP */
+}
+
+/*****************************************************************************/
+
+#if defined (ACE_USES_WCHAR)
+void ACE_OS::checkUnicodeFormat (FILE* fp)
+{
+ if (fp != 0)
+ {
+ // Due to the ACE_TCHAR definition, all default input files, such as
+ // svc.conf, have to be in Unicode format (small endian) on WinCE
+ // because ACE has all 'char' converted into ACE_TCHAR.
+ // However, for TAO, ASCII files, such as IOR file, can still be read
+ // and be written without any error since given buffers are all in 'char'
+ // type instead of ACE_TCHAR. Therefore, it is user's reponsibility to
+ // select correct buffer type.
+
+ // At this point, check if the file is Unicode or not.
+ ACE_UINT16 first_two_bytes;
+ size_t numRead =
+ ACE_OS::fread(&first_two_bytes, sizeof (first_two_bytes), 1, fp);
+
+ if (numRead == 1)
+ {
+ if ((first_two_bytes != 0xFFFE) && // not a small endian Unicode file
+ (first_two_bytes != 0xFEFF)) // not a big endian Unicode file
+ {
+ // set file pointer back to the beginning
+#if defined (ACE_WIN32)
+ ACE_OS::fseek(fp, 0, FILE_BEGIN);
+#else
+ ACE_OS::fseek(fp, 0, SEEK_SET);
+#endif /* ACE_WIN32 */
+ }
+ }
+ // if it is a Unicode file, file pointer will be right next to the first
+ // two-bytes
+ }
+}
+#endif // ACE_USES_WCHAR
+
+#if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
+namespace
+{
+ /// Translate fopen's mode char to open's mode. This helper function
+ /// is here to avoid maintaining several pieces of identical code.
+ void
+ fopen_mode_to_open_mode_converter (ACE_TCHAR x, int & hmode)
+ {
+ switch (x)
+ {
+ case ACE_LIB_TEXT ('r'):
+ if (ACE_BIT_DISABLED (hmode, _O_RDWR))
+ {
+ ACE_CLR_BITS (hmode, _O_WRONLY);
+ ACE_SET_BITS (hmode, _O_RDONLY);
+ }
+ break;
+ case ACE_LIB_TEXT ('w'):
+ if (ACE_BIT_DISABLED (hmode, _O_RDWR))
+ {
+ ACE_CLR_BITS (hmode, _O_RDONLY);
+ ACE_SET_BITS (hmode, _O_WRONLY);
+ }
+ ACE_SET_BITS (hmode, _O_CREAT | _O_TRUNC);
+ break;
+ case ACE_LIB_TEXT ('a'):
+ if (ACE_BIT_DISABLED (hmode, _O_RDWR))
+ {
+ ACE_CLR_BITS (hmode, _O_RDONLY);
+ ACE_SET_BITS (hmode, _O_WRONLY);
+ }
+ ACE_SET_BITS (hmode, _O_CREAT | _O_APPEND);
+ break;
+ case ACE_LIB_TEXT ('+'):
+ ACE_CLR_BITS (hmode, _O_RDONLY | _O_WRONLY);
+ ACE_SET_BITS (hmode, _O_RDWR);
+ break;
+ case ACE_LIB_TEXT ('t'):
+ ACE_CLR_BITS (hmode, _O_BINARY);
+ ACE_SET_BITS (hmode, _O_TEXT);
+ break;
+ case ACE_LIB_TEXT ('b'):
+ ACE_CLR_BITS (hmode, _O_TEXT);
+ ACE_SET_BITS (hmode, _O_BINARY);
+ break;
+ }
+ }
+} // Close anonymous namespace
+
+FILE *
+ACE_OS::fopen (const char *filename,
+ const ACE_TCHAR *mode)
+{
+ ACE_OS_TRACE ("ACE_OS::fopen");
+ int hmode = _O_TEXT;
+
+ // Let the chips fall where they may if the user passes in a NULL
+ // mode string. Convert to an empty mode string to prevent a
+ // crash.
+ ACE_TCHAR const empty_mode[] = ACE_TEXT ("");
+ if (!mode)
+ mode = empty_mode;
+
+ for (ACE_TCHAR const* mode_ptr = mode; *mode_ptr != 0; ++mode_ptr)
+ fopen_mode_to_open_mode_converter (*mode_ptr, hmode);
+
+ ACE_HANDLE const handle = ACE_OS::open (filename, hmode);
+ if (handle != ACE_INVALID_HANDLE)
+ {
+ hmode &= _O_TEXT | _O_RDONLY | _O_APPEND;
+
+ int const fd = ::_open_osfhandle (intptr_t (handle), hmode);
+
+ if (fd != -1)
+ {
+# if defined (__BORLANDC__) && !defined (ACE_USES_WCHAR)
+ FILE * const fp = ::_fdopen (fd, const_cast<ACE_TCHAR *> (mode));
+# elif defined (__BORLANDC__) && defined (ACE_USES_WCHAR)
+ FILE * const fp = ::_wfdopen (fd, const_cast<ACE_TCHAR *> (mode));
+# elif defined (ACE_USES_WCHAR)
+ FILE * const fp = ::_wfdopen (fd, mode);
+# else
+ FILE * const fp = ::fdopen (fd, mode);
+# endif /* defined(__BORLANDC__) && !defined (ACE_USES_WCHAR)) */
+ if (fp != 0)
+ {
+# if defined (ACE_USES_WCHAR)
+ checkUnicodeFormat(fp);
+# endif // ACE_USES_WCHAR
+ return fp;
+ }
+ ::_close (fd);
+ }
+
+ ACE_OS::close (handle);
+ }
+ return 0;
+}
+
+#if defined (ACE_HAS_WCHAR)
+FILE *
+ACE_OS::fopen (const wchar_t *filename,
+ const ACE_TCHAR *mode)
+{
+ ACE_OS_TRACE ("ACE_OS::fopen");
+ int hmode = _O_TEXT;
+
+ for (const ACE_TCHAR *mode_ptr = mode; *mode_ptr != 0; mode_ptr++)
+ fopen_mode_to_open_mode_converter (*mode_ptr, hmode);
+
+ ACE_HANDLE handle = ACE_OS::open (filename, hmode);
+ if (handle != ACE_INVALID_HANDLE)
+ {
+ hmode &= _O_TEXT | _O_RDONLY | _O_APPEND;
+
+ int const fd = ::_open_osfhandle (intptr_t (handle), hmode);
+
+ if (fd != -1)
+ {
+# if defined (__BORLANDC__) && !defined (ACE_USES_WCHAR)
+ FILE *fp = ::_fdopen (fd, const_cast<char *> (mode));
+# elif defined (__BORLANDC__) && defined (ACE_USES_WCHAR)
+ FILE *fp = ::_wfdopen (fd, const_cast<wchar_t *> (mode));
+# elif defined (ACE_USES_WCHAR)
+ FILE *fp = ::_wfdopen (fd, mode);
+# else
+ FILE *fp = ::fdopen (fd, mode);
+# endif /* defined(__BORLANDC__) && !defined (ACE_USES_WCHAR)) */
+ if (fp != 0)
+ {
+# if defined (ACE_USES_WCHAR)
+ checkUnicodeFormat(fp);
+# endif // ACE_USES_WCHAR
+ return fp;
+ }
+ ::_close (fd);
+ }
+
+ ACE_OS::close (handle);
+ }
+ return 0;
+}
+#endif /* ACE_HAS_WCHAR */
+
+#endif /* ACE_WIN32 */
+
+int
+ACE_OS::fprintf (FILE *fp, const char *format, ...)
+{
+ ACE_OS_TRACE ("ACE_OS::fprintf");
+ int result = 0;
+ va_list ap;
+ va_start (ap, format);
+ ACE_OSCALL (::vfprintf (fp, format, ap), int, -1, result);
+ va_end (ap);
+ return result;
+}
+
+#if defined (ACE_HAS_WCHAR)
+int
+ACE_OS::fprintf (FILE *fp, const wchar_t *format, ...)
+{
+ ACE_OS_TRACE ("ACE_OS::fprintf");
+
+# if !defined (ACE_HAS_VFWPRINTF)
+ ACE_UNUSED_ARG (fp);
+ ACE_UNUSED_ARG (format);
+ ACE_NOTSUP_RETURN (-1);
+
+# else
+ int result = 0;
+ va_list ap;
+ va_start (ap, format);
+ ACE_OSCALL (ACE_STD_NAMESPACE::vfwprintf (fp, format, ap), int, -1, result);
+ va_end (ap);
+ return result;
+
+# endif /* ACE_HAS_VFWPRINTF */
+}
+#endif /* ACE_HAS_WCHAR */
+
+
+// The following *printf functions aren't inline because
+// they use varargs.
+
+int
+ACE_OS::printf (const char *format, ...)
+{
+ // ACE_OS_TRACE ("ACE_OS::printf");
+ int result;
+ va_list ap;
+ va_start (ap, format);
+ ACE_OSCALL (::vprintf (format, ap), int, -1, result);
+ va_end (ap);
+ return result;
+}
+
+int
+ACE_OS::snprintf (char *buf, size_t maxlen, const char *format, ...)
+{
+ // ACE_OS_TRACE ("ACE_OS::snprintf");
+ int result;
+ va_list ap;
+ va_start (ap, format);
+ result = ACE_OS::vsnprintf (buf, maxlen, format, ap);
+ va_end (ap);
+ return result;
+}
+
+#if defined (ACE_HAS_WCHAR)
+
+int
+ACE_OS::snprintf (wchar_t *buf, size_t maxlen, const wchar_t *format, ...)
+{
+ // ACE_OS_TRACE ("ACE_OS::snprintf");
+# if (defined _XOPEN_SOURCE && (_XOPEN_SOURCE - 0) >= 500) || \
+ (defined (sun) && !defined (_XPG4) || defined(_XPG5)) || \
+ defined (ACE_WIN32)
+ int result;
+ va_list ap;
+ va_start (ap, format);
+# if defined (ACE_WIN32)
+ // Microsoft's vswprintf() doesn't have the maxlen argument that
+ // XPG4/UNIX98 define. They do, however, recommend use of _vsnwprintf()
+ // as a substitute, which does have the same signature as the UNIX98 one.
+ ACE_OSCALL (::_vsnwprintf (buf, maxlen, format, ap), int, -1, result);
+ // Win32 doesn't regard a full buffer with no 0-terminate as an overrun.
+ if (result == static_cast <int> (maxlen))
+ result = -1;
+
+ // Win32 doesn't 0-terminate the string if it overruns maxlen.
+ if (result == -1)
+ buf[maxlen-1] = '\0';
+# else
+ ACE_OSCALL (::vswprintf (buf, maxlen, format, ap), int, -1, result);
+# endif /* ACE_WIN32 */
+ va_end (ap);
+ // In out-of-range conditions, C99 defines vsnprintf to return the number
+ // of characters that would have been written if enough space was available.
+ // Earlier variants of the vsnprintf() (e.g. UNIX98) defined it to return
+ // -1. This method follows the C99 standard, but needs to guess at the
+ // value; uses maxlen + 1.
+ if (result == -1)
+ result = static_cast <int> (maxlen + 1);
+ return result;
+
+# else
+ ACE_UNUSED_ARG (buf);
+ ACE_UNUSED_ARG (maxlen);
+ ACE_UNUSED_ARG (format);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* _XOPEN_SOURCE ... */
+}
+#endif /* ACE_HAS_WCHAR */
+
+int
+ACE_OS::sprintf (char *buf, const char *format, ...)
+{
+ // ACE_OS_TRACE ("ACE_OS::sprintf");
+
+ int result;
+ va_list ap;
+ va_start (ap, format);
+ ACE_OSCALL (::vsprintf (buf, format, ap), int, -1, result);
+ va_end (ap);
+ return result;
+}
+
+#if defined (ACE_HAS_WCHAR)
+int
+ACE_OS::sprintf (wchar_t *buf, const wchar_t *format, ...)
+{
+ ACE_OS_TRACE ("ACE_OS::sprintf");
+
+# if (defined _XOPEN_SOURCE && (_XOPEN_SOURCE - 0) >= 500) || \
+ (defined (sun) && !defined (_XPG4) || defined(_XPG5)) || \
+ (defined ACE_HAS_DINKUM_STL) || defined (__DMC__)
+
+ // The XPG4/UNIX98/C99 signature of the wide-char sprintf has a
+ // maxlen argument. Since this method doesn't supply one, pass in
+ // a length that works (ULONG_MAX doesn't on all platform since some check
+ // to see if the operation will remain in bounds). If this isn't ok, use
+ // ACE_OS::snprintf().
+ int result;
+ va_list ap;
+ va_start (ap, format);
+ ACE_OSCALL (ACE_STD_NAMESPACE::vswprintf (buf, 4096, format, ap), int, -1, result);
+ va_end (ap);
+ return result;
+
+# elif defined (ACE_WIN32)
+ // Windows has vswprintf, but the signature is from the older ISO C
+ // standard. Also see ACE_OS::snprintf() for more info on this.
+
+ int result;
+ va_list ap;
+ va_start (ap, format);
+ ACE_OSCALL (::vswprintf (buf, format, ap), int, -1, result);
+ va_end (ap);
+ return result;
+
+# else
+
+ ACE_UNUSED_ARG (buf);
+ ACE_UNUSED_ARG (format);
+ ACE_NOTSUP_RETURN (-1);
+
+# endif /* XPG5 || ACE_HAS_DINKUM_STL */
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_END_VERSIONED_NAMESPACE_DECL