Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / OS_NS_stdio.inl
blob065866f22c25808fd49b571e6f9fc50a0d833b1d
1 // -*- C++ -*-
2 #include "ace/OS_NS_unistd.h"
3 #include "ace/OS_NS_stdlib.h"
4 #include "ace/OS_NS_fcntl.h"
5 #include "ace/OS_NS_errno.h"
6 #include "ace/OS_NS_string.h"
7 #include "ace/OS_NS_pwd.h"
8 #include "ace/OS_NS_macros.h"
9 #include "ace/OS_NS_sys_stat.h"
10 #include "ace/OS_Memory.h"
12 #if defined (ACE_HAS_TRIO)
13 #  include <trio.h>
14 #endif /* ACE_HAS_TRIO */
16 #if defined (ACE_HAS_ALLOC_HOOKS)
17 # include "ace/Malloc_Base.h"
18 #endif /* ACE_HAS_ALLOC_HOOKS */
20 #ifdef ACE_MQX
21 #  include "ace/MQX_Filesystem.h"
22 #endif
24 /*****************************************************************************/
26 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
28 #if defined (ACE_WIN32)
29 ACE_INLINE void
30 ACE_OS::flock_adjust_params (ACE_OS::ace_flock_t *lock,
31                              short whence,
32                              ACE_OFF_T &start,
33                              ACE_OFF_T &len)
35   switch (whence)
36     {
37     case SEEK_SET:
38       break;
39     case SEEK_CUR:
40       {
41         LARGE_INTEGER offset;
42         LARGE_INTEGER distance;
43         distance.QuadPart = 0;
44         if (!::SetFilePointerEx (lock->handle_,
45                                  distance,
46                                  &offset,
47                                  FILE_CURRENT))
48           {
49             ACE_OS::set_errno_to_last_error ();
50             return;
51           }
53 # if defined (_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64
54         start += offset.QuadPart;
55 # else
56         start += offset.LowPart;
57 # endif /* _FILE_OFFSET_BITS == 64 */
58       }
59       break;
60     case SEEK_END:
61       {
62         ACE_OFF_T const size = ACE_OS::filesize (lock->handle_);
63         if (size == -1)
64           return;
66         start += size;
67       }
68       break;
69     }
70   lock->overlapped_.Offset = ACE_LOW_PART (start);
71   lock->overlapped_.OffsetHigh = ACE_HIGH_PART (start);
72   if (len == 0)
73     {
74       ACE_OFF_T const tlen = ACE_OS::filesize (lock->handle_);
75       if (tlen != -1)
76         len = tlen - start;
77     }
79 #endif /* ACE_WIN32 */
81 ACE_INLINE int
82 ACE_OS::flock_init (ACE_OS::ace_flock_t *lock,
83                     int flags,
84                     const ACE_TCHAR *name,
85                     mode_t perms)
87   ACE_OS_TRACE ("ACE_OS::flock_init");
88 #if defined (ACE_WIN32)
89   // Once initialized, these values are never changed.
90   lock->overlapped_.Internal = 0;
91   lock->overlapped_.InternalHigh = 0;
92   lock->overlapped_.OffsetHigh = 0;
93   lock->overlapped_.hEvent = 0;
94 #endif /* ACE_WIN32 */
95   lock->handle_ = ACE_INVALID_HANDLE;
96   lock->lockname_ = 0;
98   if (name != 0)
99     {
100       ACE_OSCALL (ACE_OS::open (name, flags, perms), ACE_HANDLE, lock->handle_);
101       if (lock->handle_ != ACE_INVALID_HANDLE)
102         lock->lockname_ = ACE_OS::strdup (name);
103       return lock->handle_ == ACE_INVALID_HANDLE ? -1 : 0;
104     }
105   else
106     return 0;
109 ACE_INLINE int
110 ACE_OS::flock_unlock (ACE_OS::ace_flock_t *lock,
111                       short whence,
112                       ACE_OFF_T start,
113                       ACE_OFF_T len)
115   ACE_OS_TRACE ("ACE_OS::flock_unlock");
116 #if defined (ACE_LACKS_FILELOCKS)
117   ACE_UNUSED_ARG (lock);
118   ACE_UNUSED_ARG (whence);
119   ACE_UNUSED_ARG (start);
120   ACE_UNUSED_ARG (len);
121   ACE_NOTSUP_RETURN (-1);
122 #elif defined (ACE_WIN32)
123   ACE_OS::flock_adjust_params (lock, whence, start, len);
124   DWORD low_len = ACE_LOW_PART (len);
125   DWORD high_len = ACE_HIGH_PART (len);
126   ACE_WIN32CALL_RETURN (
127     ACE_ADAPT_RETVAL (::UnlockFileEx (lock->handle_,
128                                       0,
129                                       low_len,
130                                       high_len,
131                                       &lock->overlapped_),
132                       ace_result_), int, -1);
133 #else
134   lock->lock_.l_whence = whence;
135   lock->lock_.l_start = start;
136   lock->lock_.l_len = len;
137   lock->lock_.l_type = F_UNLCK;   // Unlock file.
139   // release lock
140   return ACE_OS::fcntl (lock->handle_, F_SETLK, reinterpret_cast<long> (&lock->lock_));
141 #endif /* ACE_WIN32 */
144 ACE_INLINE int
145 ACE_OS::flock_destroy (ACE_OS::ace_flock_t *lock,
146                        int unlink_file)
148   ACE_OS_TRACE ("ACE_OS::flock_destroy");
149   if (lock->handle_ != ACE_INVALID_HANDLE)
150     {
151       ACE_OS::flock_unlock (lock);
152       // Close the handle.
153       ACE_OS::close (lock->handle_);
154       lock->handle_ = ACE_INVALID_HANDLE;
155       if (lock->lockname_ != 0)
156         {
157           if (unlink_file)
158             ACE_OS::unlink (lock->lockname_);
159 #if defined (ACE_HAS_ALLOC_HOOKS)
160           ACE_Allocator::instance()->free (
161             static_cast<void *> (const_cast<ACE_TCHAR *> (lock->lockname_)));
162 #else
163           ACE_OS::free (
164             static_cast<void *> (const_cast<ACE_TCHAR *> (lock->lockname_)));
165 #endif /* ACE_HAS_ALLOC_HOOKS */
166         }
167       lock->lockname_ = 0;
168     }
169   return 0;
172 ACE_INLINE int
173 ACE_OS::flock_rdlock (ACE_OS::ace_flock_t *lock,
174                       short whence,
175                       ACE_OFF_T start,
176                       ACE_OFF_T len)
178   ACE_OS_TRACE ("ACE_OS::flock_rdlock");
179 #if defined (ACE_LACKS_FILELOCKS)
180   ACE_UNUSED_ARG (lock);
181   ACE_UNUSED_ARG (whence);
182   ACE_UNUSED_ARG (start);
183   ACE_UNUSED_ARG (len);
184   ACE_NOTSUP_RETURN (-1);
185 #elif defined (ACE_WIN32)
186   ACE_OS::flock_adjust_params (lock, whence, start, len);
187   DWORD low_len = ACE_LOW_PART (len);
188   DWORD high_len = ACE_HIGH_PART (len);
189   ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::LockFileEx (lock->handle_,
190                                                         0,
191                                                         0,
192                                                         low_len,
193                                                         high_len,
194                                                         &lock->overlapped_),
195                                           ace_result_), int, -1);
196 #else
197   lock->lock_.l_whence = whence;
198   lock->lock_.l_start = start;
199   lock->lock_.l_len = len;
200   lock->lock_.l_type = F_RDLCK;         // set read lock
201   // block, if no access
202   return ACE_OS::fcntl (lock->handle_, F_SETLKW, reinterpret_cast<long> (&lock->lock_));
203 #endif /* ACE_WIN32 */
206 ACE_INLINE int
207 ACE_OS::flock_tryrdlock (ACE_OS::ace_flock_t *lock,
208                          short whence,
209                          ACE_OFF_T start,
210                          ACE_OFF_T len)
212   ACE_OS_TRACE ("ACE_OS::ace_flock_tryrdlock");
213 #if defined (ACE_LACKS_FILELOCKS)
214   ACE_UNUSED_ARG (lock);
215   ACE_UNUSED_ARG (whence);
216   ACE_UNUSED_ARG (start);
217   ACE_UNUSED_ARG (len);
218   ACE_NOTSUP_RETURN (-1);
219 #elif defined (ACE_WIN32)
220   ACE_OS::flock_adjust_params (lock, whence, start, len);
221   DWORD low_len = ACE_LOW_PART (len);
222   DWORD high_len = ACE_HIGH_PART (len);
223   ACE_WIN32CALL_RETURN (
224     ACE_ADAPT_RETVAL (::LockFileEx (lock->handle_,
225                                     LOCKFILE_FAIL_IMMEDIATELY,
226                                     0,
227                                     low_len,
228                                     high_len,
229                                     &lock->overlapped_),
230                       ace_result_), int, -1);
231 #else
232   lock->lock_.l_whence = whence;
233   lock->lock_.l_start = start;
234   lock->lock_.l_len = len;
235   lock->lock_.l_type = F_RDLCK;         // set read lock
237   int result = 0;
238   // Does not block, if no access, returns -1 and set errno = EBUSY;
239   ACE_OSCALL (ACE_OS::fcntl (lock->handle_, F_SETLK,
240                              reinterpret_cast<long> (&lock->lock_)),
241               int, result);
243   if (result == -1 && (errno == EACCES || errno == EAGAIN))
244     errno = EBUSY;
246   return result;
247 #endif /* ACE_WIN32 */
250 ACE_INLINE int
251 ACE_OS::flock_trywrlock (ACE_OS::ace_flock_t *lock,
252                          short whence,
253                          ACE_OFF_T start,
254                          ACE_OFF_T len)
256   ACE_OS_TRACE ("ACE_OS::ace_flock_trywrlock");
257 #if defined (ACE_LACKS_FILELOCKS)
258   ACE_UNUSED_ARG (lock);
259   ACE_UNUSED_ARG (whence);
260   ACE_UNUSED_ARG (start);
261   ACE_UNUSED_ARG (len);
262   ACE_NOTSUP_RETURN (-1);
263 #elif defined (ACE_WIN32)
264   ACE_OS::flock_adjust_params (lock, whence, start, len);
265   DWORD low_len = ACE_LOW_PART (len);
266   DWORD high_len = ACE_HIGH_PART (len);
267   ACE_WIN32CALL_RETURN (
268     ACE_ADAPT_RETVAL (::LockFileEx (lock->handle_,
269                                     LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK,
270                                     0,
271                                     low_len,
272                                     high_len,
273                                     &lock->overlapped_),
274                       ace_result_), int, -1);
275 #else
276   lock->lock_.l_whence = whence;
277   lock->lock_.l_start = start;
278   lock->lock_.l_len = len;
279   lock->lock_.l_type = F_WRLCK;         // set write lock
281   int result = 0;
282   // Does not block, if no access, returns -1 and set errno = EBUSY;
283   ACE_OSCALL (ACE_OS::fcntl (lock->handle_,
284                              F_SETLK,
285                              reinterpret_cast<long> (&lock->lock_)),
286               int, result);
288   if (result == -1 && (errno == EACCES || errno == EAGAIN))
289     errno = EBUSY;
291   return result;
292 #endif /* ACE_WIN32 */
295 ACE_INLINE int
296 ACE_OS::flock_wrlock (ACE_OS::ace_flock_t *lock,
297                       short whence,
298                       ACE_OFF_T start,
299                       ACE_OFF_T len)
301   ACE_OS_TRACE ("ACE_OS::flock_wrlock");
302 #if defined (ACE_LACKS_FILELOCKS)
303   ACE_UNUSED_ARG (lock);
304   ACE_UNUSED_ARG (whence);
305   ACE_UNUSED_ARG (start);
306   ACE_UNUSED_ARG (len);
307   ACE_NOTSUP_RETURN (-1);
308 #elif defined (ACE_WIN32)
309   ACE_OS::flock_adjust_params (lock, whence, start, len);
310   DWORD low_len = ACE_LOW_PART (len);
311   DWORD high_len = ACE_HIGH_PART (len);
312   ACE_WIN32CALL_RETURN (
313     ACE_ADAPT_RETVAL (::LockFileEx (lock->handle_,
314                                     LOCKFILE_EXCLUSIVE_LOCK,
315                                     0,
316                                     low_len,
317                                     high_len,
318                                     &lock->overlapped_),
319                       ace_result_), int, -1);
320 #else
321   lock->lock_.l_whence = whence;
322   lock->lock_.l_start = start;
323   lock->lock_.l_len = len;
324   lock->lock_.l_type = F_WRLCK;         // set write lock
325   // block, if no access
326   return ACE_OS::fcntl (lock->handle_, F_SETLKW, reinterpret_cast<long> (&lock->lock_));
327 #endif /* ACE_WIN32 */
330 ACE_INLINE void
331 ACE_OS::clearerr (FILE* fp)
333   std::clearerr (fp);
336 #if !defined (ACE_LACKS_CUSERID)
337 ACE_INLINE char *
338 ACE_OS::cuserid (char *user, size_t maxlen)
340   ACE_OS_TRACE ("ACE_OS::cuserid");
341 #if defined (ACE_VXWORKS)
342   ACE_UNUSED_ARG (maxlen);
343   if (user == 0)
344     {
345       // Require that the user field be non-null, i.e., don't
346       // allocate or use static storage.
347       ACE_NOTSUP_RETURN (0);
348     }
349   else
350     {
351       ::remCurIdGet (user, 0);
352       return user;
353     }
354 #elif defined (ACE_WIN32)
355   BOOL const result = GetUserNameA (user, (u_long *) &maxlen);
356   if (result == FALSE)
357     ACE_FAIL_RETURN (0);
358   else
359     return user;
360 #elif defined (ACE_HAS_ALT_CUSERID)
361 #  if defined (ACE_LACKS_PWD_FUNCTIONS)
362   ACE_UNUSED_ARG (user);
363   ACE_UNUSED_ARG (maxlen);
364   ACE_NOTSUP_RETURN (0);
365   //#    error Cannot use alternate cuserid() without POSIX password functions!
366 #  endif  /* ACE_LACKS_PWD_FUNCTIONS */
368   // POSIX.1 dropped the cuserid() function.
369   // GNU GLIBC and other platforms correctly deprecate the cuserid()
370   // function.
372   if (maxlen == 0)
373     {
374       // It doesn't make sense to have a zero length user ID.
375       errno = EINVAL;
376       return 0;
377     }
379   struct passwd *pw = 0;
381   // Make sure the file pointer is at the beginning of the password file
382   ACE_OS::setpwent ();
383   // Should use ACE_OS::setpwent() but I didn't want to move this
384   // method after it.
386   // Use the effective user ID to determine the user name.
387   pw = ::getpwuid (ACE_OS::geteuid ());
389   // Make sure the password file is closed.
390   ACE_OS::endpwent ();
392   if (pw == 0)
393     {
394       errno = ENOENT;
395       return 0;
396     }
398   size_t max_length = 0;
399   char *userid = 0;
401   if (user == 0)
402     {
403       // Not reentrant/thread-safe, but nothing else can be done if a
404       // zero pointer was passed in as the destination.
406 #if defined (_POSIX_SOURCE) && defined (L_cuserid)
407       const size_t ACE_L_cuserid = L_cuserid;
408 #else
409       const size_t ACE_L_cuserid = 9;  // 8 character user ID + NULL
410 #endif  /* _POSIX_SOURCE */
412       static char tmp[ACE_L_cuserid] = { '\0' };
413       max_length = ACE_L_cuserid - 1; // Do not include NULL in length
415       userid = tmp;
416     }
417   else
418     {
419       max_length = maxlen;
420       userid = user;
421     }
423   // Extract the user name from the passwd structure.
424   if (ACE_OS::strlen (pw->pw_name) <= max_length)
425     {
426       return ACE_OS::strcpy (userid, pw->pw_name);
427     }
428   else
429     {
430       errno = ENOSPC;  // Buffer is not large enough.
431       return 0;
432     }
433 #else
434   // Hackish because of missing buffer size!
435   ACE_UNUSED_ARG (maxlen);
436   return ::ace_cuserid(user);
437 #endif /* ACE_VXWORKS */
440 #if defined (ACE_HAS_WCHAR)
441 ACE_INLINE wchar_t *
442 ACE_OS::cuserid (wchar_t *user, size_t maxlen)
444 # if defined (ACE_WIN32)
445   BOOL const result = GetUserNameW (user, (u_long *) &maxlen);
446   if (result == FALSE)
447     ACE_FAIL_RETURN (0);
448   else
449     return user;
450 # else /* ACE_WIN32 */
451   char *char_user;
452   wchar_t *result = 0;
454   ACE_NEW_RETURN (char_user, char[maxlen + 1], 0);
456   if (ACE_OS::cuserid (char_user, maxlen))
457     {
458       ACE_OS::strcpy (user, ACE_Ascii_To_Wide (char_user).wchar_rep ());
459       result = user;
460     }
462   delete [] char_user;
464   return result;
465 # endif /* ACE_WIN32 */
467 #endif /* ACE_HAS_WCHAR  */
468 #endif /* ACE_LACKS_CUSERID */
470 ACE_INLINE int
471 ACE_OS::fclose (FILE *fp)
473   ACE_OS_TRACE ("ACE_OS::fclose");
474   return std::fclose (fp);
477 ACE_INLINE FILE *
478 ACE_OS::fdopen (ACE_HANDLE handle, const ACE_TCHAR *mode)
480   ACE_OS_TRACE ("ACE_OS::fdopen");
481 #if defined (ACE_WIN32)
482   // kernel file handle -> FILE* conversion...
483   // Options: _O_APPEND, _O_RDONLY and _O_TEXT are lost
485   FILE * file = 0;
487   int const crt_handle = ::_open_osfhandle (intptr_t (handle), 0);
489   if (crt_handle != -1)
490     {
491 #   if defined (ACE_USES_WCHAR)
492       file = ::_wfdopen (crt_handle, mode);
493 #   else
494       file = ::_fdopen (crt_handle, mode);
495 #   endif /* ACE_USES_WCHAR */
497       if (!file)
498         {
499           ::_close (crt_handle);
500         }
501     }
503   return file;
504 #elif defined (ACE_LACKS_FDOPEN)
505   ACE_UNUSED_ARG (handle);
506   ACE_UNUSED_ARG (mode);
507   ACE_NOTSUP_RETURN (0);
508 #else
509   return ::fdopen (handle, ACE_TEXT_ALWAYS_CHAR (mode));
510 #endif /* ACE_WIN32 */
513 ACE_INLINE int
514 ACE_OS::fflush (FILE *fp)
516   ACE_OS_TRACE ("ACE_OS::fflush");
517   return std::fflush (fp);
520 ACE_INLINE int
521 ACE_OS::fgetc (FILE *fp)
523   return std::fgetc (fp);
526 ACE_INLINE int
527 ACE_OS::getc (FILE *fp)
529 #ifdef ACE_LACKS_GETC
530   ACE_UNUSED_ARG (fp);
531   ACE_NOTSUP_RETURN (-1);
532 #else
533   return ace_getc_helper (fp);
534 #endif
537 ACE_INLINE int
538 ACE_OS::fgetpos (FILE *fp, fpos_t *pos)
540 #ifdef ACE_LACKS_FGETPOS
541   ACE_UNUSED_ARG (fp);
542   ACE_UNUSED_ARG (pos);
543   ACE_NOTSUP_RETURN (-1);
544 #else
545   return std::fgetpos (fp, pos);
546 #endif
549 ACE_INLINE char *
550 ACE_OS::fgets (char *buf, int size, FILE *fp)
552   ACE_OS_TRACE ("ACE_OS::fgets");
553 #if defined (ACE_LACKS_FGETS)
554   char *iter = buf;
555   int c = EOF;
556   for (int i = 0; i < size - 1 && c != '\n'; ++i)
557     {
558       c = std::fgetc (fp);
559       if (c != EOF)
560         *iter++ = static_cast<char> (c);
561     }
562   *iter = '\0';
563   return c == EOF ? 0 : buf;
564 #else
565   return std::fgets (buf, size, fp);
566 #endif /* ACE_LACKS_FGETS */
569 #if defined (ACE_HAS_WCHAR) && !defined(ACE_LACKS_FGETWS)
570 ACE_INLINE wchar_t *
571 ACE_OS::fgets (wchar_t *buf, int size, FILE *fp)
573   ACE_OS_TRACE ("ACE_OS::fgets");
574   return std::fgetws (buf, size, fp);
576 #endif /* ACE_HAS_WCHAR && !ACE_LACKS_FGETWS */
578 ACE_INLINE ACE_HANDLE
579 ACE_OS::fileno (FILE *stream)
581 #if defined ACE_FILENO_EQUIVALENT
582   return (ACE_HANDLE)((intptr_t)ACE_FILENO_EQUIVALENT (stream));
583 #else
584   return ace_fileno_helper (stream);
585 #endif
588 #if !defined (ACE_WIN32)
589 // Win32 PC implementation of fopen () is in OS_NS_stdio.cpp.
590 ACE_INLINE FILE *
591 ACE_OS::fopen (const char *filename, const char *mode)
593   ACE_OS_TRACE ("ACE_OS::fopen");
594   return ::fopen (filename, mode);
597 #if defined (ACE_HAS_WCHAR)
598 // Win32 PC implementation of fopen () is in OS_NS_stdio.cpp.
599 ACE_INLINE FILE *
600 ACE_OS::fopen (const char *filename, const wchar_t *mode)
602   ACE_OS_TRACE ("ACE_OS::fopen");
603   ACE_Wide_To_Ascii n_mode (mode);
604   return ::fopen (filename, n_mode.char_rep ());
607 // Win32 PC implementation of fopen () is in OS_NS_stdio.cpp.
608 ACE_INLINE FILE *
609 ACE_OS::fopen (const wchar_t *filename, const wchar_t *mode)
611   ACE_OS_TRACE ("ACE_OS::fopen");
612   // Non-Windows doesn't use wchar_t file systems.
613   ACE_Wide_To_Ascii n_filename (filename);
614   ACE_Wide_To_Ascii n_mode (mode);
615   return ::fopen (n_filename.char_rep (), n_mode.char_rep ());
618 // Win32 PC implementation of fopen () is in OS_NS_stdio.cpp.
619 ACE_INLINE FILE *
620 ACE_OS::fopen (const wchar_t *filename, const char *mode)
622   ACE_OS_TRACE ("ACE_OS::fopen");
623   // Non-Windows doesn't use wchar_t file systems.
624   ACE_Wide_To_Ascii n_filename (filename);
625   return ::fopen (n_filename.char_rep (), mode);
627 #endif /* ACE_HAS_WCHAR */
629 #endif /* ACE_WIN32 */
631 ACE_INLINE int
632 ACE_OS::ungetc (int c, FILE *fp)
634 #ifdef ACE_LACKS_UNGETC
635   ACE_UNUSED_ARG (c);
636   ACE_UNUSED_ARG (fp);
637   ACE_NOTSUP_RETURN (-1);
638 #else
639   return std::ungetc (c, fp);
640 #endif
643 ACE_INLINE int
644 ACE_OS::fputc (int c, FILE *fp)
646 #ifdef ACE_LACKS_FPUTC
647   ACE_UNUSED_ARG (c);
648   ACE_UNUSED_ARG (fp);
649   ACE_NOTSUP_RETURN (-1);
650 #else
651   return ace_fputc_helper (c, fp);
652 #endif
655 ACE_INLINE int
656 ACE_OS::putc (int c, FILE *fp)
658 #ifdef ACE_LACKS_PUTC
659   ACE_UNUSED_ARG (c);
660   ACE_UNUSED_ARG (fp);
661   ACE_NOTSUP_RETURN (-1);
662 #else
663   return std::putc (c, fp);
664 #endif
667 ACE_INLINE int
668 ACE_OS::fputs (const char *s, FILE *stream)
670   ACE_OS_TRACE ("ACE_OS::fputs");
671 #ifdef ACE_LACKS_FPUTS
672   ACE_UNUSED_ARG (s);
673   ACE_UNUSED_ARG (stream);
674   ACE_NOTSUP_RETURN (-1);
675 #else
676   return std::fputs (s, stream);
677 #endif
680 #if defined (ACE_HAS_WCHAR) && !defined(ACE_LACKS_FPUTWS)
681 ACE_INLINE int
682 ACE_OS::fputs (const wchar_t *s, FILE *stream)
684   ACE_OS_TRACE ("ACE_OS::fputs");
685   return std::fputws (s, stream);
687 #endif /* ACE_HAS_WCHAR && !ACE_LACKS_FPUTWS */
689 ACE_INLINE size_t
690 ACE_OS::fread (void *ptr, size_t size, size_t nelems, FILE *fp)
692   ACE_OS_TRACE ("ACE_OS::fread");
693   return std::fread (ptr, size, nelems, fp);
696 ACE_INLINE FILE *
697 ACE_OS::freopen (const ACE_TCHAR *filename, const ACE_TCHAR *mode, FILE* stream)
699   ACE_OS_TRACE ("ACE_OS::freopen");
700 #if defined (ACE_WIN32) && defined(ACE_USES_WCHAR)
701   return ::_wfreopen (ACE_TEXT_ALWAYS_WCHAR (filename), ACE_TEXT_ALWAYS_WCHAR (mode), stream);
702 #elif defined (ACE_LACKS_FREOPEN)
703   ACE_UNUSED_ARG (filename);
704   ACE_UNUSED_ARG (mode);
705   ACE_UNUSED_ARG (stream);
706   ACE_NOTSUP_RETURN (0);
707 #else
708   return std::freopen (ACE_TEXT_ALWAYS_CHAR (filename), ACE_TEXT_ALWAYS_CHAR (mode), stream);
709 #endif /* ACE_WIN32 && ACE_USES_WCHAR */
712 ACE_INLINE int
713 ACE_OS::fseek (FILE *fp, long offset, int whence)
715 #if defined (ACE_WIN32)
716 # if SEEK_SET != FILE_BEGIN || SEEK_CUR != FILE_CURRENT || SEEK_END != FILE_END
717   //#error Windows NT is evil AND rude!
718   switch (whence)
719     {
720     case SEEK_SET:
721       whence = FILE_BEGIN;
722       break;
723     case SEEK_CUR:
724       whence = FILE_CURRENT;
725       break;
726     case SEEK_END:
727       whence = FILE_END;
728       break;
729     default:
730       errno = EINVAL;
731       return -1; // rather safe than sorry
732     }
733 # endif  /* SEEK_SET != FILE_BEGIN || SEEK_CUR != FILE_CURRENT || SEEK_END != FILE_END */
734 #endif   /* ACE_WIN32 */
735   return std::fseek (fp, offset, whence);
738 ACE_INLINE int
739 ACE_OS::fsetpos (FILE* fp, fpos_t* pos)
741 #if defined (ACE_LACKS_FSETPOS)
742   ACE_UNUSED_ARG (fp);
743   ACE_UNUSED_ARG (pos);
744   ACE_NOTSUP_RETURN (-1);
745 #else
746   return ::fsetpos (fp, pos);
747 #endif /* ACE_LACKS_FSETPOS */
750 ACE_INLINE long
751 ACE_OS::ftell (FILE* fp)
753   return std::ftell (fp);
756 ACE_INLINE size_t
757 ACE_OS::fwrite (const void *ptr, size_t size, size_t nitems, FILE *fp)
759   ACE_OS_TRACE ("ACE_OS::fwrite");
760   return std::fwrite (ptr, size, nitems, fp);
763 ACE_INLINE void
764 ACE_OS::perror (const char *s)
766   ACE_OS_TRACE ("ACE_OS::perror");
767 #if defined (ACE_LACKS_PERROR)
768   ACE_UNUSED_ARG (s);
769 #else
770   ::perror (s);
771 #endif /* ACE_LACKS_PERROR */
774 #if defined (ACE_HAS_WCHAR)
775 ACE_INLINE void
776 ACE_OS::perror (const wchar_t *s)
778   ACE_OS_TRACE ("ACE_OS::perror");
779 #if defined (ACE_LACKS_PERROR)
780   ACE_UNUSED_ARG (s);
781 #elif defined (ACE_WIN32)
782   ::_wperror (s);
783 #else
784   ACE_Wide_To_Ascii n_s (s);
785   ::perror (n_s.char_rep ());
786 #endif /* ACE_LACKS_PERROR */
788 #endif /* ACE_HAS_WCHAR */
790 ACE_INLINE int
791 ACE_OS::puts (const char *s)
793   ACE_OS_TRACE ("ACE_OS::puts");
794 #if defined (ACE_LACKS_PUTS)
795   ACE_UNUSED_ARG (s);
796   ACE_NOTSUP_RETURN (-1);
797 #else
798   return std::puts (s);
799 #endif /* ACE_LACKS_PUTS */
802 #if defined (ACE_HAS_WCHAR)
803 ACE_INLINE int
804 ACE_OS::puts (const wchar_t *s)
806   ACE_OS_TRACE ("ACE_OS::puts");
807 #if defined (ACE_WIN32)
808   return ::_putws (s);
809 #else /* ACE_WIN32 */
810   // There's no putws()...
811   ACE_Wide_To_Ascii n_s (s);
812   return ::puts (n_s.char_rep ());
813 #endif /* ACE_WIN32 */
815 #endif /* ACE_HAS_WCHAR */
817 ACE_INLINE int
818 ACE_OS::rename (const char *old_name,
819                 const char *new_name,
820                 int flags)
822 # if defined (ACE_LACKS_RENAME)
823   ACE_UNUSED_ARG (old_name);
824   ACE_UNUSED_ARG (new_name);
825   ACE_UNUSED_ARG (flags);
826   ACE_NOTSUP_RETURN (-1);
827 # elif defined (ACE_WIN32)
828   // NT4 (and up) provides a way to rename/move a file with similar semantics
829   // to what's usually done on UNIX - if there's an existing file with
830   // <new_name> it is removed before the file is renamed/moved. The
831   // MOVEFILE_COPY_ALLOWED is specified to allow such a rename across drives.
832   if (flags == -1)
833     flags = MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING;
834   if (::MoveFileExA (old_name, new_name, flags) == 0)
835     ACE_FAIL_RETURN (-1);
836   return 0;
837 #elif defined (ACE_RENAME_EQUIVALENT)
838   return ACE_RENAME_EQUIVALENT (old_name, new_name);
839 # else
840   ACE_UNUSED_ARG (flags);
841   return ::rename (old_name, new_name);
842 # endif /* ACE_LACKS_RENAME */
845 #if defined (ACE_HAS_WCHAR)
846 ACE_INLINE int
847 ACE_OS::rename (const wchar_t *old_name,
848                 const wchar_t *new_name,
849                 int flags)
851 # if defined (ACE_LACKS_RENAME)
852   ACE_UNUSED_ARG (old_name);
853   ACE_UNUSED_ARG (new_name);
854   ACE_UNUSED_ARG (flags);
855   ACE_NOTSUP_RETURN (-1);
856 # elif defined (ACE_WIN32)
857   // NT4 (and up) provides a way to rename/move a file with similar semantics
858   // to what's usually done on UNIX - if there's an existing file with
859   // <new_name> it is removed before the file is renamed/moved. The
860   // MOVEFILE_COPY_ALLOWED is specified to allow such a rename across drives.
861   if (flags == -1)
862     flags = MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING;
863   if (::MoveFileExW (old_name, new_name, flags) == 0)
864     ACE_FAIL_RETURN (-1);
865   return 0;
866 # elif defined (ACE_WIN32)
867   ACE_UNUSED_ARG (flags);
868   return ::_wrename (old_name, new_name);
869 # else
870   ACE_Wide_To_Ascii nold_name (old_name);
871   ACE_Wide_To_Ascii nnew_name (new_name);
872   return ACE_OS::rename (nold_name.char_rep (), nnew_name.char_rep (), flags);
873 # endif /* ACE_LACKS_RENAME */
875 #endif /* ACE_HAS_WCHAR */
877 ACE_INLINE void
878 ACE_OS::rewind (FILE *fp)
880 #if !defined (ACE_MQX)
881   ACE_OS_TRACE ("ACE_OS::rewind");
882 # if defined (ACE_LACKS_REWIND)
883   ACE_UNUSED_ARG (fp);
884 # else
885   ::rewind (fp);
886 # endif /* ACE_LACKS_REWIND */
887 #else
888   // This isn't perfect since it doesn't reset EOF, but it's probably
889   // the closest we can get on MQX.
890   (void) std::fseek (fp, 0L, SEEK_SET);
891 #endif /* !ACE_MQX */
894 #if !defined (ACE_DISABLE_TEMPNAM)
895 ACE_INLINE char *
896 ACE_OS::tempnam (const char *dir, const char *pfx)
898   ACE_OS_TRACE ("ACE_OS::tempnam");
899 #if defined (ACE_LACKS_TEMPNAM)
900   ACE_UNUSED_ARG (dir);
901   ACE_UNUSED_ARG (pfx);
902   ACE_NOTSUP_RETURN (0);
903 #elif defined (ACE_HAS_NONCONST_TEMPNAM)
904   return ACE_STD_NAMESPACE::tempnam (const_cast <char *> (dir), const_cast<char *> (pfx));
905 #elif defined (ACE_TEMPNAM_EQUIVALENT)
906   return ACE_TEMPNAM_EQUIVALENT (dir, pfx);
907 #else /* ACE_LACKS_TEMPNAM */
908   return ACE_STD_NAMESPACE::tempnam (dir, pfx);
909 #endif /* ACE_LACKS_TEMPNAM */
912 #if defined (ACE_HAS_WCHAR)
913 ACE_INLINE wchar_t *
914 ACE_OS::tempnam (const wchar_t *dir, const wchar_t *pfx)
916   ACE_OS_TRACE ("ACE_OS::tempnam");
917 #if defined (ACE_LACKS_TEMPNAM)
918   ACE_UNUSED_ARG (dir);
919   ACE_UNUSED_ARG (pfx);
920   ACE_NOTSUP_RETURN (0);
921 #elif defined(ACE_WIN32)
922 #  if defined (ACE_HAS_NONCONST_TEMPNAM)
923   return ::_wtempnam (const_cast <wchar_t*> (dir), const_cast <wchar_t*> (pfx));
924 #  else
925   return ::_wtempnam (dir, pfx);
926 #  endif /* ACE_HAS_NONCONST_TEMPNAM */
927 #else /* ACE_LACKS_TEMPNAM */
928   // No native wide-char support; convert to narrow and call the char* variant.
929   ACE_Wide_To_Ascii wta_ndir(dir);
930   char *ndir = wta_ndir.char_rep ();
932   ACE_Wide_To_Ascii wta_npfx(pfx);
933   char *npfx = wta_npfx.char_rep ();
934   char *name = ACE_OS::tempnam (ndir, npfx);
935   // ACE_OS::tempnam returns a pointer to a malloc()-allocated space.
936   // Convert that string to wide-char and free() the original.
937   wchar_t *wname = 0;
938   if (name != 0)
939     {
940       size_t namelen = ACE_OS::strlen (name) + 1;
941       wname = reinterpret_cast<wchar_t *>
942         (ACE_OS::malloc (namelen * sizeof (wchar_t)));
943       if (wname != 0)
944         ACE_OS::strcpy (wname, ACE_Ascii_To_Wide (name).wchar_rep ());
945       ACE_OS::free (name);
946     }
947   return wname;
948 #endif /* ACE_LACKS_TEMPNAM */
950 #endif /* ACE_HAS_WCHAR */
951 #endif /* !ACE_DISABLE_TEMPNAM */
953 ACE_INLINE int
954 ACE_OS::vasprintf (char **bufp, const char* format, va_list argptr)
956 #if defined (ACE_HAS_VASPRINTF)
957   return ::vasprintf (bufp, format, argptr);
958 #elif defined (ACE_LACKS_VA_COPY)
959   ACE_UNUSED_ARG (bufp);
960   ACE_UNUSED_ARG (format);
961   ACE_UNUSED_ARG (argptr);
962   ACE_NOTSUP_RETURN (-1);
963 #else
964   return ACE_OS::vasprintf_emulation (bufp, format, argptr);
965 #endif /* ACE_HAS_VASPRINTF */
968 #if defined (ACE_HAS_WCHAR)
969 ACE_INLINE int
970 ACE_OS::vasprintf (wchar_t **bufp, const wchar_t* format, va_list argptr)
972 #if defined (ACE_HAS_VASWPRINTF)
973   return ::vaswprintf (bufp, format, argptr);
974 #elif defined (ACE_LACKS_VA_COPY)
975   ACE_UNUSED_ARG (bufp);
976   ACE_UNUSED_ARG (format);
977   ACE_UNUSED_ARG (argptr);
978   ACE_NOTSUP_RETURN (-1);
979 #else
980   return ACE_OS::vaswprintf_emulation (bufp, format, argptr);
981 #endif /* ACE_HAS_VASWPRINTF */
983 #endif /* ACE_HAS_WCHAR */
985 ACE_INLINE int
986 ACE_OS::vprintf (const char *format, va_list argptr)
988 #if defined (ACE_LACKS_VPRINTF)
989   ACE_UNUSED_ARG (format);
990   ACE_UNUSED_ARG (argptr);
991   ACE_NOTSUP_RETURN (-1);
992 #else
993   return std::vprintf (format, argptr);
994 #endif /* ACE_LACKS_VPRINTF */
997 #if defined (ACE_HAS_WCHAR)
998 ACE_INLINE int
999 ACE_OS::vprintf (const wchar_t *format, va_list argptr)
1001 #if defined (ACE_HAS_VWPRINTF)
1002   return ::vwprintf (format, argptr);
1003 #else
1004   ACE_UNUSED_ARG (format);
1005   ACE_UNUSED_ARG (argptr);
1006   ACE_NOTSUP_RETURN (-1);
1007 #endif /* ACE_HAS_VWPRINTF */
1009 #endif /* ACE_HAS_WCHAR */
1011 ACE_INLINE int
1012 ACE_OS::vfprintf (FILE *fp, const char *format, va_list argptr)
1014 #ifdef ACE_LACKS_VFPRINTF
1015   ACE_UNUSED_ARG (fp);
1016   ACE_UNUSED_ARG (format);
1017   ACE_UNUSED_ARG (argptr);
1018   ACE_NOTSUP_RETURN (-1);
1019 #else
1020   return std::vfprintf (fp, format, argptr);
1021 #endif
1024 #if defined (ACE_HAS_WCHAR)
1025 ACE_INLINE int
1026 ACE_OS::vfprintf (FILE *fp, const wchar_t *format, va_list argptr)
1028 #if defined (ACE_HAS_VFWPRINTF)
1029   return ::vfwprintf (fp, format, argptr);
1030 #else
1031   ACE_UNUSED_ARG (fp);
1032   ACE_UNUSED_ARG (format);
1033   ACE_UNUSED_ARG (argptr);
1034   ACE_NOTSUP_RETURN (-1);
1035 #endif /* ACE_HAS_VFWPRINTF */
1037 #endif /* ACE_HAS_WCHAR */
1039 ACE_INLINE int
1040 ACE_OS::vsprintf (char *buffer, const char *format, va_list argptr)
1042 #ifdef ACE_LACKS_VSPRINTF
1043   ACE_UNUSED_ARG (buffer);
1044   ACE_UNUSED_ARG (format);
1045   ACE_UNUSED_ARG (argptr);
1046   ACE_NOTSUP_RETURN (-1);
1047 #else
1048   return std::vsprintf (buffer, format, argptr);
1049 #endif /* ACE_LACKS_VSPRINTF */
1052 #if defined (ACE_HAS_WCHAR)
1053 ACE_INLINE int
1054 ACE_OS::vsprintf (wchar_t *buffer, const wchar_t *format, va_list argptr)
1056 # if (defined _XOPEN_SOURCE && (_XOPEN_SOURCE - 0) >= 500) || \
1057       defined (ACE_HAS_VSWPRINTF) || \
1058       (defined (_MSC_VER))
1060   // The XPG4/UNIX98/C99 signature of the wide-char sprintf has a
1061   // maxlen argument. Since this method doesn't supply one, pass in
1062   // a length that works (ULONG_MAX doesn't on all platform since some check
1063   // to see if the operation will remain in bounds). If this isn't ok, use
1064   // ACE_OS::snprintf().
1065   return vswprintf (buffer, 4096, format, argptr);
1067 # elif defined (__MINGW64_VERSION_MAJOR) && !defined (WIN64)
1068   // the MingW64 32bit version causes link errors when using the
1069   // 'standard' vswprint(). Luckily they have a mingw special.
1071   return __mingw_vswprintf (buffer, format, argptr);
1073 # elif defined (ACE_WIN32)
1074   // Windows has vswprintf, but the pre-VC8 signature is from the older
1075   // ISO C standard. Also see ACE_OS::snprintf() for more info on this.
1077   return vswprintf (buffer, format, argptr);
1079 # else
1080   ACE_UNUSED_ARG (buffer);
1081   ACE_UNUSED_ARG (format);
1082   ACE_UNUSED_ARG (argptr);
1083   ACE_NOTSUP_RETURN (-1);
1085 # endif /* XPG5 */
1087 #endif /* ACE_HAS_WCHAR */
1089 ACE_INLINE int
1090 ACE_OS::vsnprintf (char *buffer, size_t maxlen, const char *format, va_list ap)
1092 #if !defined (ACE_LACKS_VSNPRINTF)
1093   int result;
1094 # if defined (ACE_WIN32) && !defined (ACE_HAS_C99_VSNPRINTF)
1095   result = ::_vsnprintf (buffer, maxlen, format, ap);
1097   // Win32 doesn't regard a full buffer with no 0-terminate as an overrun.
1098   if (result == static_cast<int> (maxlen) && maxlen > 0)
1099     buffer[maxlen-1] = '\0';
1101   // Win32 doesn't 0-terminate the string if it overruns maxlen.
1102   if (result == -1 && maxlen > 0)
1103     buffer[maxlen-1] = '\0';
1104 # else
1105   result = ::vsnprintf (buffer, maxlen, format, ap);
1106 # endif
1107   // In out-of-range conditions, C99 defines vsnprintf() to return the number
1108   // of characters that would have been written if enough space was available.
1109   // Earlier variants of the vsnprintf() (e.g. UNIX98) defined it to return
1110   // -1. This method follows the C99 standard, but needs to guess at the
1111   // value; uses maxlen + 1.
1112   if (result == -1)
1113     {
1114       result = static_cast <int> (maxlen + 1);
1115     }
1117   return result;
1118 #elif defined (ACE_HAS_TRIO)
1119   return trio_vsnprintf (buffer, maxlen, format, ap);
1120 #elif defined (ACE_HAS_VSNPRINTF_EMULATION)
1121   return vsnprintf_emulation (buffer, maxlen, format, ap);
1122 #else
1123   ACE_UNUSED_ARG (buffer);
1124   ACE_UNUSED_ARG (maxlen);
1125   ACE_UNUSED_ARG (format);
1126   ACE_UNUSED_ARG (ap);
1127   ACE_NOTSUP_RETURN (-1);
1128 #endif /* ACE_LACKS_VSNPRINTF */
1131 #if defined (ACE_HAS_WCHAR)
1132 ACE_INLINE int
1133 ACE_OS::vsnprintf (wchar_t *buffer, size_t maxlen, const wchar_t *format, va_list ap)
1135 # if (defined _XOPEN_SOURCE && (_XOPEN_SOURCE - 0) >= 500) || \
1136       defined (ACE_HAS_VSWPRINTF) || \
1137       defined (ACE_WIN32)
1138   int result;
1140 # if defined (ACE_WIN32) && !defined (ACE_HAS_C99_VSNWPRINTF)
1141   // Microsoft's vswprintf() doesn't have the maxlen argument that
1142   // XPG4/UNIX98 define. They do, however, recommend use of _vsnwprintf()
1143   // as a substitute, which does have the same signature as the UNIX98 one.
1144   result = ::_vsnwprintf (buffer, maxlen, format, ap);
1146   // Win32 doesn't regard a full buffer with no 0-terminate as an overrun.
1147   if (result == static_cast<int> (maxlen) && maxlen > 0)
1148     buffer[maxlen-1] = '\0';
1150   // Win32 doesn't 0-terminate the string if it overruns maxlen.
1151   if (result == -1 && maxlen > 0)
1152     buffer[maxlen-1] = '\0';
1153 # else
1154   result = vswprintf (buffer, maxlen, format, ap);
1155 #endif
1157   // In out-of-range conditions, C99 defines vsnprintf() to return the
1158   // number of characters that would have been written if enough space
1159   // was available.  Earlier variants of the vsnprintf() (e.g. UNIX98)
1160   // defined it to return -1. This method follows the C99 standard,
1161   // but needs to guess at the value; uses maxlen + 1.
1162   // Note that a formatting failure also returns -1. On RHEL this is
1163   // errno EINVAL. Don't indicate a simple memory shortage for that.
1164   if (result == -1 && errno != EINVAL)
1165     result = static_cast <int> (maxlen + 1);
1167   return result;
1168 # else
1169   ACE_UNUSED_ARG (buffer);
1170   ACE_UNUSED_ARG (maxlen);
1171   ACE_UNUSED_ARG (format);
1172   ACE_UNUSED_ARG (ap);
1173   ACE_NOTSUP_RETURN (-1);
1174 # endif /* platforms with a variant of vswprintf */
1176 #endif /* ACE_HAS_WCHAR */
1178 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
1179 #if defined (ACE_WIN32)
1180 ACE_INLINE const ACE_TEXT_OSVERSIONINFO &
1181 ACE_OS::get_win32_versioninfo ()
1183   return ACE_OS::win32_versioninfo_;
1186 ACE_INLINE HINSTANCE
1187 ACE_OS::get_win32_resource_module ()
1189   return ACE_OS::win32_resource_module_;
1192 ACE_INLINE void
1193 ACE_OS::set_win32_resource_module (HINSTANCE instance)
1195   ACE_OS::win32_resource_module_ = instance;
1198 ACE_INLINE LPSECURITY_ATTRIBUTES
1199 ACE_OS::default_win32_security_attributes (LPSECURITY_ATTRIBUTES sa)
1201 #if defined (ACE_DEFINES_DEFAULT_WIN32_SECURITY_ATTRIBUTES)
1202   if (sa == 0)
1203     {
1204       // @@ This is a good place to use pthread_once.
1205       static SECURITY_ATTRIBUTES default_sa;
1206       static SECURITY_DESCRIPTOR sd;
1207       InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
1208       SetSecurityDescriptorDacl(&sd, TRUE, 0, FALSE);
1209       default_sa.nLength = sizeof(SECURITY_ATTRIBUTES);
1210       default_sa.lpSecurityDescriptor = &sd;
1211       default_sa.bInheritHandle       = TRUE;
1212       sa = &default_sa;
1213     }
1214   return sa;
1215 #else /* !ACE_DEFINES_DEFAULT_WIN32_SECURITY_ATTRIBUTES */
1216   return sa;
1217 #endif /* ACE_DEFINES_DEFAULT_WIN32_SECURITY_ATTRIBUTES */
1220 ACE_INLINE LPSECURITY_ATTRIBUTES
1221 ACE_OS::default_win32_security_attributes_r (LPSECURITY_ATTRIBUTES sa,
1222                                              LPSECURITY_ATTRIBUTES sa_buffer,
1223                                              SECURITY_DESCRIPTOR* sd_buffer)
1225 #if defined (ACE_DEFINES_DEFAULT_WIN32_SECURITY_ATTRIBUTES)
1226   if (sa == 0)
1227     {
1228       if (sa_buffer != 0 && sd_buffer != 0)
1229         {
1230           InitializeSecurityDescriptor
1231             (sd_buffer, SECURITY_DESCRIPTOR_REVISION);
1232           SetSecurityDescriptorDacl (sd_buffer, TRUE, 0, FALSE);
1233           sa_buffer->nLength = sizeof(SECURITY_ATTRIBUTES);
1234           sa_buffer->lpSecurityDescriptor = sd_buffer;
1235           sa_buffer->bInheritHandle       = TRUE;
1236           sa = sa_buffer;
1237         }
1238     }
1239   return sa;
1240 #else /* !ACE_DEFINES_DEFAULT_WIN32_SECURITY_ATTRIBUTES */
1241   ACE_UNUSED_ARG(sa_buffer);
1242   ACE_UNUSED_ARG(sd_buffer);
1243   return sa;
1244 #endif /* ACE_DEFINES_DEFAULT_WIN32_SECURITY_ATTRIBUTES */
1247 #endif /* ACE_WIN32 */
1248 #endif
1250 ACE_END_VERSIONED_NAMESPACE_DECL