OS_NS_stdio.cpp

Go to the documentation of this file.
00001 // $Id: OS_NS_stdio.cpp 79134 2007-07-31 18:23:50Z johnnyw $
00002 
00003 #include "ace/OS_NS_stdio.h"
00004 #include "ace/OS_NS_Thread.h"
00005 
00006 ACE_RCSID (ace,
00007            OS_NS_stdio,
00008            "$Id: OS_NS_stdio.cpp 79134 2007-07-31 18:23:50Z johnnyw $")
00009 
00010 
00011 #if !defined (ACE_HAS_INLINED_OSCALLS)
00012 # include "ace/OS_NS_stdio.inl"
00013 #endif /* ACE_HAS_INLINED_OSCALLS */
00014 
00015 # if defined (ACE_WIN32)
00016 
00017 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00018 ACE_TEXT_OSVERSIONINFO ACE_OS::win32_versioninfo_;
00019 HINSTANCE ACE_OS::win32_resource_module_;
00020 ACE_END_VERSIONED_NAMESPACE_DECL
00021 
00022 #   if defined (ACE_HAS_DLL) && (ACE_HAS_DLL == 1) && !defined (ACE_HAS_WINCE)
00023 // This function is called by the OS when the ACE DLL is loaded. We
00024 // use it to determine the default module containing ACE's resources.
00025 extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID)
00026 {
00027   if (reason == DLL_PROCESS_ATTACH)
00028     {
00029 #     if defined (ACE_DISABLES_THREAD_LIBRARY_CALLS) && (ACE_DISABLES_THREAD_LIBRARY_CALLS == 1)
00030       ::DisableThreadLibraryCalls (instance);
00031 #     endif /* ACE_DISABLES_THREAD_LIBRARY_CALLS */
00032       ACE_OS::set_win32_resource_module(instance);
00033     }
00034   else if (reason == DLL_THREAD_DETACH)
00035     {
00036       ACE_OS::cleanup_tss (0);
00037     }
00038   return TRUE;
00039 }
00040 #   endif /* ACE_HAS_DLL && ACE_HAS_DLL == 1 */
00041 # endif /* ACE_WIN32 */
00042 
00043 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00044 
00045 void
00046 ACE_OS::ace_flock_t::dump (void) const
00047 {
00048 #if defined (ACE_HAS_DUMP)
00049   ACE_OS_TRACE ("ACE_OS::ace_flock_t::dump");
00050 
00051 # if 0
00052   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00053   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("handle_ = %u"), this->handle_));
00054 #   if defined (ACE_WIN32)
00055   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nInternal = %d"),
00056               this->overlapped_.Internal));
00057   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nInternalHigh = %d"),
00058               this->overlapped_.InternalHigh));
00059   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nOffsetHigh = %d"),
00060               this->overlapped_.OffsetHigh));
00061   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nhEvent = %d"),
00062               this->overlapped_.hEvent));
00063 #   else
00064   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nl_whence = %d"),
00065               this->lock_.l_whence));
00066   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nl_start = %d"), this->lock_.l_start));
00067   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nl_len = %d"), this->lock_.l_len));
00068   ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nl_type = %d"), this->lock_.l_type));
00069 #   endif /* ACE_WIN32 */
00070   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00071 # endif /* 0 */
00072 #endif /* ACE_HAS_DUMP */
00073 }
00074 
00075 /*****************************************************************************/
00076 
00077 #if defined (ACE_USES_WCHAR)
00078 void ACE_OS::checkUnicodeFormat (FILE* fp)
00079 {
00080   if (fp != 0)
00081     {
00082       // Due to the ACE_TCHAR definition, all default input files, such as
00083       // svc.conf, have to be in Unicode format (small endian) on WinCE
00084       // because ACE has all 'char' converted into ACE_TCHAR.
00085       // However, for TAO, ASCII files, such as IOR file, can still be read
00086       // and be written without any error since given buffers are all in 'char'
00087       // type instead of ACE_TCHAR.  Therefore, it is user's reponsibility to
00088       // select correct buffer type.
00089 
00090       // At this point, check if the file is Unicode or not.
00091       ACE_UINT16 first_two_bytes;
00092       size_t numRead =
00093         ACE_OS::fread(&first_two_bytes, sizeof (first_two_bytes), 1, fp);
00094 
00095       if (numRead == 1)
00096         {
00097           if ((first_two_bytes != 0xFFFE) && // not a small endian Unicode file
00098               (first_two_bytes != 0xFEFF))   // not a big endian Unicode file
00099             {
00100               // set file pointer back to the beginning
00101 #if defined (ACE_WIN32)
00102               ACE_OS::fseek(fp, 0, FILE_BEGIN);
00103 #else
00104               ACE_OS::fseek(fp, 0, SEEK_SET);
00105 #endif /* ACE_WIN32 */
00106             }
00107         }
00108       // if it is a Unicode file, file pointer will be right next to the first
00109       // two-bytes
00110     }
00111 }
00112 #endif  // ACE_USES_WCHAR
00113 
00114 #if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
00115 namespace
00116 {
00117   /// Translate fopen's mode char to open's mode.  This helper function
00118   /// is here to avoid maintaining several pieces of identical code.
00119   void
00120   fopen_mode_to_open_mode_converter (ACE_TCHAR x, int & hmode)
00121   {
00122     switch (x)
00123       {
00124       case ACE_TEXT ('r'):
00125         if (ACE_BIT_DISABLED (hmode, _O_RDWR))
00126           {
00127             ACE_CLR_BITS (hmode, _O_WRONLY);
00128             ACE_SET_BITS (hmode, _O_RDONLY);
00129           }
00130         break;
00131       case ACE_TEXT ('w'):
00132         if (ACE_BIT_DISABLED (hmode, _O_RDWR))
00133           {
00134             ACE_CLR_BITS (hmode, _O_RDONLY);
00135             ACE_SET_BITS (hmode, _O_WRONLY);
00136           }
00137         ACE_SET_BITS (hmode, _O_CREAT | _O_TRUNC);
00138         break;
00139       case ACE_TEXT ('a'):
00140         if (ACE_BIT_DISABLED (hmode, _O_RDWR))
00141           {
00142             ACE_CLR_BITS (hmode, _O_RDONLY);
00143             ACE_SET_BITS (hmode, _O_WRONLY);
00144           }
00145         ACE_SET_BITS (hmode, _O_CREAT | _O_APPEND);
00146         break;
00147       case ACE_TEXT ('+'):
00148         ACE_CLR_BITS (hmode, _O_RDONLY | _O_WRONLY);
00149         ACE_SET_BITS (hmode, _O_RDWR);
00150         break;
00151       case ACE_TEXT ('t'):
00152         ACE_CLR_BITS (hmode, _O_BINARY);
00153         ACE_SET_BITS (hmode, _O_TEXT);
00154         break;
00155       case ACE_TEXT ('b'):
00156         ACE_CLR_BITS (hmode, _O_TEXT);
00157         ACE_SET_BITS (hmode, _O_BINARY);
00158         break;
00159       }
00160   }
00161 }  // Close anonymous namespace
00162 
00163 FILE *
00164 ACE_OS::fopen (const char *filename,
00165                const ACE_TCHAR *mode)
00166 {
00167   ACE_OS_TRACE ("ACE_OS::fopen");
00168   int hmode = _O_TEXT;
00169 
00170   // Let the chips fall where they may if the user passes in a NULL
00171   // mode string.  Convert to an empty mode string to prevent a
00172   // crash.
00173   ACE_TCHAR const empty_mode[] = ACE_TEXT ("");
00174   if (!mode)
00175     mode = empty_mode;
00176 
00177   for (ACE_TCHAR const* mode_ptr = mode; *mode_ptr != 0; ++mode_ptr)
00178     fopen_mode_to_open_mode_converter (*mode_ptr, hmode);
00179 
00180   ACE_HANDLE const handle = ACE_OS::open (filename, hmode);
00181   if (handle != ACE_INVALID_HANDLE)
00182     {
00183       hmode &= _O_TEXT | _O_RDONLY | _O_APPEND;
00184 
00185       int const fd = ::_open_osfhandle (intptr_t (handle), hmode);
00186 
00187       if (fd != -1)
00188         {
00189 #   if defined (__BORLANDC__) && !defined (ACE_USES_WCHAR)
00190           FILE * const fp = ::_fdopen (fd, const_cast<ACE_TCHAR *> (mode));
00191 #   elif defined (__BORLANDC__) && defined (ACE_USES_WCHAR)
00192           FILE * const fp = ::_wfdopen (fd, const_cast<ACE_TCHAR *> (mode));
00193 #   elif defined (ACE_USES_WCHAR)
00194           FILE * const fp = ::_wfdopen (fd, mode);
00195 #   else
00196           FILE * const fp = ::fdopen (fd, mode);
00197 #   endif /* defined(__BORLANDC__) && !defined (ACE_USES_WCHAR)) */
00198           if (fp != 0)
00199           {
00200 #   if defined (ACE_USES_WCHAR)
00201             checkUnicodeFormat(fp);
00202 #   endif  // ACE_USES_WCHAR
00203             return fp;
00204           }
00205           ::_close (fd);
00206         }
00207 
00208       ACE_OS::close (handle);
00209     }
00210   return 0;
00211 }
00212 
00213 #if defined (ACE_HAS_WCHAR)
00214 FILE *
00215 ACE_OS::fopen (const wchar_t *filename,
00216                const ACE_TCHAR *mode)
00217 {
00218   ACE_OS_TRACE ("ACE_OS::fopen");
00219   int hmode = _O_TEXT;
00220 
00221   for (const ACE_TCHAR *mode_ptr = mode; *mode_ptr != 0; mode_ptr++)
00222     fopen_mode_to_open_mode_converter (*mode_ptr, hmode);
00223 
00224   ACE_HANDLE handle = ACE_OS::open (filename, hmode);
00225   if (handle != ACE_INVALID_HANDLE)
00226     {
00227       hmode &= _O_TEXT | _O_RDONLY | _O_APPEND;
00228 
00229       int const fd = ::_open_osfhandle (intptr_t (handle), hmode);
00230 
00231       if (fd != -1)
00232         {
00233 #   if defined (__BORLANDC__) && !defined (ACE_USES_WCHAR)
00234           FILE *fp = ::_fdopen (fd, const_cast<char *> (mode));
00235 #   elif defined (__BORLANDC__) && defined (ACE_USES_WCHAR)
00236           FILE *fp = ::_wfdopen (fd, const_cast<wchar_t *> (mode));
00237 #   elif defined (ACE_USES_WCHAR)
00238           FILE *fp = ::_wfdopen (fd, mode);
00239 #   else
00240           FILE *fp = ::fdopen (fd, mode);
00241 #   endif /* defined(__BORLANDC__) && !defined (ACE_USES_WCHAR)) */
00242           if (fp != 0)
00243           {
00244 #   if defined (ACE_USES_WCHAR)
00245             checkUnicodeFormat(fp);
00246 #   endif  // ACE_USES_WCHAR
00247             return fp;
00248           }
00249           ::_close (fd);
00250         }
00251 
00252       ACE_OS::close (handle);
00253     }
00254   return 0;
00255 }
00256 #endif /* ACE_HAS_WCHAR */
00257 
00258 #endif /* ACE_WIN32 */
00259 
00260 int
00261 ACE_OS::fprintf (FILE *fp, const char *format, ...)
00262 {
00263   ACE_OS_TRACE ("ACE_OS::fprintf");
00264   int result = 0;
00265   va_list ap;
00266   va_start (ap, format);
00267   ACE_OSCALL (::vfprintf (fp, format, ap), int, -1, result);
00268   va_end (ap);
00269   return result;
00270 }
00271 
00272 #if defined (ACE_HAS_WCHAR)
00273 int
00274 ACE_OS::fprintf (FILE *fp, const wchar_t *format, ...)
00275 {
00276   ACE_OS_TRACE ("ACE_OS::fprintf");
00277 
00278 # if !defined (ACE_HAS_VFWPRINTF)
00279   ACE_UNUSED_ARG (fp);
00280   ACE_UNUSED_ARG (format);
00281   ACE_NOTSUP_RETURN (-1);
00282 
00283 # else
00284   int result = 0;
00285   va_list ap;
00286   va_start (ap, format);
00287   ACE_OSCALL (ACE_STD_NAMESPACE::vfwprintf (fp, format, ap), int, -1, result);
00288   va_end (ap);
00289   return result;
00290 
00291 # endif /* ACE_HAS_VFWPRINTF */
00292 }
00293 #endif /* ACE_HAS_WCHAR */
00294 
00295 
00296 // The following *printf functions aren't inline because
00297 // they use varargs.
00298 
00299 int
00300 ACE_OS::printf (const char *format, ...)
00301 {
00302   // ACE_OS_TRACE ("ACE_OS::printf");
00303   int result;
00304   va_list ap;
00305   va_start (ap, format);
00306   ACE_OSCALL (::vprintf (format, ap), int, -1, result);
00307   va_end (ap);
00308   return result;
00309 }
00310 
00311 int
00312 ACE_OS::snprintf (char *buf, size_t maxlen, const char *format, ...)
00313 {
00314   // ACE_OS_TRACE ("ACE_OS::snprintf");
00315   int result;
00316   va_list ap;
00317   va_start (ap, format);
00318   result = ACE_OS::vsnprintf (buf, maxlen, format, ap);
00319   va_end (ap);
00320   return result;
00321 }
00322 
00323 #if defined (ACE_HAS_WCHAR)
00324 
00325 int
00326 ACE_OS::snprintf (wchar_t *buf, size_t maxlen, const wchar_t *format, ...)
00327 {
00328   // ACE_OS_TRACE ("ACE_OS::snprintf");
00329 # if (defined _XOPEN_SOURCE && (_XOPEN_SOURCE - 0) >= 500) || \
00330      (defined (sun) && !defined (_XPG4) || defined(_XPG5)) || \
00331      defined (ACE_WIN32) || defined (ACE_HAS_VSWPRINTF)
00332   int result;
00333   va_list ap;
00334   va_start (ap, format);
00335 #  if 0 /* defined (ACE_HAS_TR24731_2005_CRT) */
00336   // _vsnwprintf_s() doesn't report the length needed when it truncates. This
00337   // info is needed for the API contract return value, so don't use this.
00338   // There's adequate protection via the maxlen.
00339   result = _vsnwprintf_s (buf, maxlen, _TRUNCATE, format, ap);
00340 #  elif defined (ACE_WIN32)
00341   // Microsoft's vswprintf() doesn't have the maxlen argument that
00342   // XPG4/UNIX98 define. They do, however, recommend use of _vsnwprintf()
00343   // as a substitute, which does have the same signature as the UNIX98 one.
00344   ACE_OSCALL (::_vsnwprintf (buf, maxlen, format, ap), int, -1, result);
00345   // Win32 doesn't regard a full buffer with no 0-terminate as an overrun.
00346   if (result == static_cast <int> (maxlen))
00347     result = -1;
00348 
00349   // Win32 doesn't 0-terminate the string if it overruns maxlen.
00350   if (result == -1)
00351     buf[maxlen-1] = '\0';
00352 #  else
00353   ACE_OSCALL (::vswprintf (buf, maxlen, format, ap), int, -1, result);
00354 #  endif /* ACE_WIN32 */
00355   va_end (ap);
00356   // In out-of-range conditions, C99 defines vsnprintf to return the number
00357   // of characters that would have been written if enough space was available.
00358   // Earlier variants of the vsnprintf() (e.g. UNIX98) defined it to return
00359   // -1. This method follows the C99 standard, but needs to guess at the
00360   // value; uses maxlen + 1.
00361   if (result == -1)
00362     result = static_cast <int> (maxlen + 1);
00363   return result;
00364 
00365 # else
00366   ACE_UNUSED_ARG (buf);
00367   ACE_UNUSED_ARG (maxlen);
00368   ACE_UNUSED_ARG (format);
00369   ACE_NOTSUP_RETURN (-1);
00370 # endif /* _XOPEN_SOURCE ...  */
00371 }
00372 #endif /* ACE_HAS_WCHAR */
00373 
00374 int
00375 ACE_OS::sprintf (char *buf, const char *format, ...)
00376 {
00377   // ACE_OS_TRACE ("ACE_OS::sprintf");
00378 
00379   int result;
00380   va_list ap;
00381   va_start (ap, format);
00382   ACE_OSCALL (::vsprintf (buf, format, ap), int, -1, result);
00383   va_end (ap);
00384   return result;
00385 }
00386 
00387 #if defined (ACE_HAS_WCHAR)
00388 int
00389 ACE_OS::sprintf (wchar_t *buf, const wchar_t *format, ...)
00390 {
00391   ACE_OS_TRACE ("ACE_OS::sprintf");
00392 
00393 # if (defined _XOPEN_SOURCE && (_XOPEN_SOURCE - 0) >= 500) || \
00394      (defined (sun) && !defined (_XPG4) || defined(_XPG5)) || \
00395       defined (ACE_HAS_DINKUM_STL) || defined (__DMC__) || \
00396       defined (ACE_HAS_VSWPRINTF) || \
00397      (defined (ACE_WIN32_VC8) && !defined (ACE_HAS_WINCE) && \
00398       _MSC_FULL_VER > 140050000)
00399 
00400   // The XPG4/UNIX98/C99 signature of the wide-char sprintf has a
00401   // maxlen argument. Since this method doesn't supply one, pass in
00402   // a length that works (ULONG_MAX doesn't on all platform since some check
00403   // to see if the operation will remain in bounds). If this isn't ok, use
00404   // ACE_OS::snprintf().
00405   int result;
00406   va_list ap;
00407   va_start (ap, format);
00408   ACE_OSCALL (ACE_STD_NAMESPACE::vswprintf (buf, 4096, format, ap), int, -1, result);
00409   va_end (ap);
00410   return result;
00411 
00412 # elif defined (ACE_WIN32)
00413   // Pre-VC8 Windows has vswprintf, but the signature is from the older ISO C
00414   // standard. Also see ACE_OS::snprintf() for more info on this.
00415 
00416   int result;
00417   va_list ap;
00418   va_start (ap, format);
00419   ACE_OSCALL (::vswprintf (buf, format, ap), int, -1, result);
00420   va_end (ap);
00421   return result;
00422 
00423 # else
00424 
00425   ACE_UNUSED_ARG (buf);
00426   ACE_UNUSED_ARG (format);
00427   ACE_NOTSUP_RETURN (-1);
00428 
00429 # endif /* XPG5 || ACE_HAS_DINKUM_STL */
00430 }
00431 #endif /* ACE_HAS_WCHAR */
00432 
00433 ACE_END_VERSIONED_NAMESPACE_DECL

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