[6916] Fixed typos in spell checking code.
[getmangos.git] / dep / ACE_wrappers / ace / OS_NS_stdlib.cpp
blob737be33ec5a6d1eb844c97e4ec74776e6713b5e8
1 // $Id: OS_NS_stdlib.cpp 81804 2008-05-29 16:12:07Z vzykov $
3 #include "ace/OS_NS_stdlib.h"
5 ACE_RCSID (ace,
6 OS_NS_stdlib,
7 "$Id: OS_NS_stdlib.cpp 81804 2008-05-29 16:12:07Z vzykov $")
9 #include "ace/Default_Constants.h"
11 #if !defined (ACE_HAS_INLINED_OSCALLS)
12 # include "ace/OS_NS_stdlib.inl"
13 #endif /* ACE_HAS_INLINED_OSCALLS */
15 #include "ace/OS_Memory.h"
17 #include "ace/OS_NS_unistd.h"
18 #include "ace/OS_NS_ctype.h"
20 #if defined (ACE_LACKS_MKTEMP) \
21 || defined (ACE_LACKS_MKSTEMP) \
22 || defined (ACE_LACKS_REALPATH)
23 # include "ace/OS_NS_stdio.h"
24 # include "ace/OS_NS_sys_stat.h"
25 #endif /* ACE_LACKS_MKTEMP || ACE_LACKS_MKSTEMP || ACE_LACKS_REALPATH */
27 #if defined (ACE_LACKS_MKSTEMP)
28 # include "ace/OS_NS_fcntl.h"
29 # include "ace/OS_NS_ctype.h"
30 # include "ace/OS_NS_sys_time.h"
31 # include "ace/OS_NS_Thread.h"
32 # include "ace/Numeric_Limits.h"
33 #endif /* ACE_LACKS_MKSTEMP */
35 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
37 ACE_EXIT_HOOK ACE_OS::exit_hook_ = 0;
39 void *
40 ACE_OS::calloc (size_t elements, size_t sizeof_elements)
42 #if !defined (ACE_HAS_WINCE)
43 return ACE_CALLOC_FUNC (elements, sizeof_elements);
44 #else
45 // @@ This will probably not work since it doesn't consider
46 // alignment properly.
47 return ACE_MALLOC_FUNC (elements * sizeof_elements);
48 #endif /* ACE_HAS_WINCE */
51 void
52 ACE_OS::exit (int status)
54 ACE_OS_TRACE ("ACE_OS::exit");
56 #if defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER) && !defined (ACE_HAS_WINCE) && !defined (ACE_DOESNT_INSTANTIATE_NONSTATIC_OBJECT_MANAGER)
57 // Shut down the ACE_Object_Manager, if it had registered its exit_hook.
58 // With ACE_HAS_NONSTATIC_OBJECT_MANAGER, the ACE_Object_Manager is
59 // instantiated on the main's stack. ::exit () doesn't destroy it.
60 if (exit_hook_)
61 (*exit_hook_) ();
62 #endif /* ACE_HAS_NONSTATIC_OBJECT_MANAGER && !ACE_HAS_WINCE && !ACE_DOESNT_INSTANTIATE_NONSTATIC_OBJECT_MANAGER */
64 #if !defined (ACE_HAS_WINCE)
65 # if defined (ACE_WIN32)
66 ::ExitProcess ((UINT) status);
67 # else
68 ::exit (status);
69 # endif /* ACE_WIN32 */
70 #else
71 // @@ This is not exactly the same as ExitProcess. But this is the
72 // closest one I can get.
73 ::TerminateProcess (::GetCurrentProcess (), status);
74 #endif /* ACE_HAS_WINCE */
77 void
78 ACE_OS::free (void *ptr)
80 ACE_FREE_FUNC (ACE_MALLOC_T (ptr));
83 // You may be asking yourself, why are we doing this? Well, in winbase.h,
84 // MS didn't follow their normal Api_FunctionA and Api_FunctionW style,
85 // so we have to #undef their define to get access to the unicode version.
86 // And because we don't want to #undef this for the users code, we keep
87 // this method in the .cpp file.
88 #if defined (ACE_WIN32) && defined (UNICODE) && !defined (ACE_USES_TCHAR)
89 #undef GetEnvironmentStrings
90 #endif /* ACE_WIN32 && UNICODE !ACE_USES_TCHAR */
92 ACE_TCHAR *
93 ACE_OS::getenvstrings (void)
95 #if defined (ACE_LACKS_ENV)
96 ACE_NOTSUP_RETURN (0);
97 #elif defined (ACE_WIN32)
98 # if defined (ACE_USES_WCHAR)
99 return ::GetEnvironmentStringsW ();
100 # else /* ACE_USES_WCHAR */
101 return ::GetEnvironmentStrings ();
102 # endif /* ACE_USES_WCHAR */
103 #else /* ACE_WIN32 */
104 ACE_NOTSUP_RETURN (0);
105 #endif /* ACE_WIN32 */
108 // Return a dynamically allocated duplicate of <str>, substituting the
109 // environment variables of form $VAR_NAME. Note that the pointer is
110 // allocated with <ACE_OS::malloc> and must be freed by
111 // <ACE_OS::free>.
113 ACE_TCHAR *
114 ACE_OS::strenvdup (const ACE_TCHAR *str)
116 #if defined (ACE_HAS_WINCE)
117 // WinCE doesn't have environment variables so we just skip it.
118 return ACE_OS::strdup (str);
119 #elif defined (ACE_LACKS_ENV)
120 ACE_UNUSED_ARG (str);
121 ACE_NOTSUP_RETURN (0);
122 #else
123 const ACE_TCHAR * start = 0;
124 if ((start = ACE_OS::strchr (str, ACE_TEXT ('$'))) != 0)
126 ACE_TCHAR buf[ACE_DEFAULT_ARGV_BUFSIZ];
127 size_t var_len = ACE_OS::strcspn (&start[1],
128 ACE_TEXT ("$~!#%^&*()-+=\\|/?,.;:'\"`[]{} \t\n\r"));
129 ACE_OS::strncpy (buf, &start[1], var_len);
130 buf[var_len++] = ACE_TEXT ('\0');
131 # if defined (ACE_WIN32)
132 // Always use the ACE_TCHAR for Windows.
133 ACE_TCHAR *temp = ACE_OS::getenv (buf);
134 # else
135 // Use char * for environment on non-Windows.
136 char *temp = ACE_OS::getenv (ACE_TEXT_ALWAYS_CHAR (buf));
137 # endif /* ACE_WIN32 */
138 size_t buf_len = ACE_OS::strlen (str) + 1;
139 if (temp != 0)
140 buf_len += ACE_OS::strlen (temp) - var_len;
141 ACE_TCHAR * buf_p = buf;
142 if (buf_len > ACE_DEFAULT_ARGV_BUFSIZ)
144 buf_p =
145 (ACE_TCHAR *) ACE_OS::malloc (buf_len * sizeof (ACE_TCHAR));
146 if (buf_p == 0)
148 errno = ENOMEM;
149 return 0;
152 ACE_TCHAR * p = buf_p;
153 size_t len = start - str;
154 ACE_OS::strncpy (p, str, len);
155 p += len;
156 if (temp != 0)
158 # if defined (ACE_WIN32)
159 p = ACE_OS::strecpy (p, temp) - 1;
160 # else
161 p = ACE_OS::strecpy (p, ACE_TEXT_CHAR_TO_TCHAR (temp)) - 1;
162 # endif /* ACE_WIN32 */
164 else
166 ACE_OS::strncpy (p, start, var_len);
167 p += var_len;
168 *p = ACE_TEXT ('\0');
170 ACE_OS::strcpy (p, &start[var_len]);
171 return (buf_p == buf) ? ACE_OS::strdup (buf) : buf_p;
173 else
174 return ACE_OS::strdup (str);
175 #endif /* ACE_HAS_WINCE */
178 #if !defined (ACE_HAS_ITOA)
179 char *
180 ACE_OS::itoa_emulation (int value, char *string, int radix)
182 char *e = string;
183 char *b = string;
185 // Short circuit if 0
187 if (value == 0)
189 string[0] = '0';
190 string[1] = 0;
191 return string;
194 // If negative and base 10, print a - and then do the
195 // number.
197 if (value < 0 && radix == 10)
199 string[0] = '-';
200 ++b;
201 ++e; // Don't overwrite the negative sign.
202 value = -value; // Drop negative sign so character selection is correct.
205 // Convert to base <radix>, but in reverse order
207 while (value != 0)
209 int mod = value % radix;
210 value = value / radix;
212 *e++ = (mod < 10) ? '0' + mod : 'a' + mod - 10;
215 *e-- = 0;
217 // Now reverse the string to get the correct result
219 while (e > b)
221 char temp = *e;
222 *e = *b;
223 *b = temp;
224 ++b;
225 --e;
228 return string;
230 #endif /* !ACE_HAS_ITOA */
232 #if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_ITOW)
233 wchar_t *
234 ACE_OS::itow_emulation (int value, wchar_t *string, int radix)
236 wchar_t *e = string;
237 wchar_t *b = string;
239 // Short circuit if 0
241 if (value == 0)
243 string[0] = '0';
244 string[1] = 0;
245 return string;
248 // If negative and base 10, print a - and then do the
249 // number.
251 if (value < 0 && radix == 10)
253 string[0] = '-';
254 b++;
257 // Convert to base <radix>, but in reverse order
259 while (value != 0)
261 int mod = value % radix;
262 value = value / radix;
264 *e++ = (mod < 10) ? '0' + mod : 'a' + mod - 10;
267 *e-- = 0;
269 // Now reverse the string to get the correct result
271 while (e > b)
273 wchar_t temp = *e;
274 *e = *b;
275 *b = temp;
276 ++b;
277 --e;
280 return string;
282 #endif /* ACE_HAS_WCHAR && ACE_LACKS_ITOW */
284 void *
285 ACE_OS::malloc (size_t nbytes)
287 return ACE_MALLOC_FUNC (nbytes);
290 #if defined (ACE_LACKS_MKTEMP)
291 ACE_TCHAR *
292 ACE_OS::mktemp (ACE_TCHAR *s)
294 ACE_OS_TRACE ("ACE_OS::mktemp");
295 if (s == 0)
296 // check for null template string failed!
297 return 0;
298 else
300 ACE_TCHAR *xxxxxx = ACE_OS::strstr (s, ACE_TEXT ("XXXXXX"));
302 if (xxxxxx == 0)
303 // the template string doesn't contain "XXXXXX"!
304 return s;
305 else
307 ACE_TCHAR unique_letter = ACE_TEXT ('a');
308 ACE_stat sb;
310 // Find an unused filename for this process. It is assumed
311 // that the user will open the file immediately after
312 // getting this filename back (so, yes, there is a race
313 // condition if multiple threads in a process use the same
314 // template). This appears to match the behavior of the
315 // SunOS 5.5 mktemp().
316 ACE_OS::sprintf (xxxxxx,
317 ACE_TEXT ("%05d%c"),
318 ACE_OS::getpid (),
319 unique_letter);
320 while (ACE_OS::stat (s, &sb) >= 0)
322 if (++unique_letter <= ACE_TEXT ('z'))
323 ACE_OS::sprintf (xxxxxx,
324 ACE_TEXT ("%05d%c"),
325 ACE_OS::getpid (),
326 unique_letter);
327 else
329 // maximum of 26 unique files per template, per process
330 ACE_OS::sprintf (xxxxxx, ACE_TEXT ("%s"), ACE_TEXT (""));
331 return s;
335 return s;
338 #endif /* ACE_LACKS_MKTEMP */
340 void *
341 ACE_OS::realloc (void *ptr, size_t nbytes)
343 return ACE_REALLOC_FUNC (ACE_MALLOC_T (ptr), nbytes);
346 #if defined (ACE_LACKS_REALPATH) && !defined (ACE_HAS_WINCE)
347 char *
348 ACE_OS::realpath (const char *file_name,
349 char *resolved_name)
351 ACE_OS_TRACE ("ACE_OS::realpath");
353 if (file_name == 0)
355 // Single Unix Specification V3:
356 // Return an error if parameter is a null pointer.
357 errno = EINVAL;
358 return 0;
361 if (*file_name == '\0')
363 // Single Unix Specification V3:
364 // Return an error if the file_name argument points
365 // to an empty string.
366 errno = ENOENT;
367 return 0;
370 char* rpath;
372 if (resolved_name == 0)
374 // Single Unix Specification V3:
375 // Return an error if parameter is a null pointer.
377 // To match glibc realpath() and Win32 _fullpath() behavior,
378 // allocate room for the return value if resolved_name is
379 // a null pointer.
380 rpath = static_cast<char*>(ACE_OS::malloc (PATH_MAX));
381 if (rpath == 0)
383 errno = ENOMEM;
384 return 0;
387 else
389 rpath = resolved_name;
392 char* dest;
394 if (*file_name != '/')
396 // file_name is relative path so CWD needs to be added
397 if (ACE_OS::getcwd (rpath, PATH_MAX) == 0)
399 if (resolved_name == 0)
400 ACE_OS::free (rpath);
401 return 0;
403 dest = ACE_OS::strchr (rpath, '\0');
405 else
407 dest = rpath;
410 #if !defined (ACE_LACKS_SYMLINKS)
411 char expand_buf[PATH_MAX]; // Extra buffer needed to expand symbolic links
412 int nlinks = 0;
413 #endif
415 while (*file_name)
417 *dest++ = '/';
419 // Skip multiple separators
420 while (*file_name == '/')
421 ++file_name;
423 char* start = dest;
425 // Process one path component
426 while (*file_name && *file_name != '/')
428 *dest++ = *file_name++;
429 if (dest - rpath > PATH_MAX)
431 errno = ENAMETOOLONG;
432 if (resolved_name == 0)
433 ACE_OS::free (rpath);
434 return 0;
438 if (start == dest) // Are we done?
440 if (dest - rpath > 1)
441 --dest; // Remove trailing separator if not at root
442 break;
444 else if (dest - start == 1 && *start == '.')
446 dest -= 2; // Remove "./"
448 else if (dest - start == 2 && *start == '.' && *(start +1) == '.')
450 dest -= 3; // Remove "../"
451 if (dest > rpath) // Remove the last path component if not at root
452 while (*--dest != '/')
455 # if !defined (ACE_LACKS_SYMLINKS)
456 else
458 ACE_stat st;
460 *dest = '\0';
461 if (ACE_OS::lstat(rpath, &st) < 0)
463 if (resolved_name == 0)
464 ACE_OS::free (rpath);
465 return 0;
468 // Check if current path is a link
469 if (S_ISLNK (st.st_mode))
471 if (++nlinks > MAXSYMLINKS)
473 errno = ELOOP;
474 if (resolved_name == 0)
475 ACE_OS::free (rpath);
476 return 0;
479 char link_buf[PATH_MAX];
481 ssize_t link_len = ACE_OS::readlink (rpath, link_buf, PATH_MAX);
482 int tail_len = ACE_OS::strlen (file_name) + 1;
484 // Check if there is room to expand link?
485 if (link_len + tail_len > PATH_MAX)
487 errno = ENAMETOOLONG;
488 if (resolved_name == 0)
489 ACE_OS::free (rpath);
490 return 0;
493 // Move tail and prefix it with expanded link
494 ACE_OS::memmove (expand_buf + link_len, file_name, tail_len);
495 ACE_OS::memcpy (expand_buf, link_buf, link_len);
497 if (*link_buf == '/') // Absolute link?
499 dest = rpath;
501 else // Relative link, remove expanded link component
503 --dest;
504 while (*--dest != '/')
507 file_name = expand_buf; // Source path is now in expand_buf
510 # endif /* ACE_LACKS_SYMLINKS */
513 *dest = '\0';
515 return rpath;
517 #endif /* ACE_LACKS_REALPATH && !ACE_HAS_WINCE */
519 #if defined (ACE_LACKS_STRTOL)
520 long
521 ACE_OS::strtol_emulation (const char *nptr, char **endptr, int base)
523 register const char *s = nptr;
524 register unsigned long acc;
525 register int c;
526 register unsigned long cutoff;
527 register int neg = 0, any, cutlim;
530 * Skip white space and pick up leading +/- sign if any.
531 * If base is 0, allow 0x for hex and 0 for octal, else
532 * assume decimal; if base is already 16, allow 0x.
534 do {
535 c = *s++;
536 } while (ACE_OS::ace_isspace(c));
537 if (c == '-') {
538 neg = 1;
539 c = *s++;
540 } else if (c == '+')
541 c = *s++;
542 if ((base == 0 || base == 16) &&
543 c == '0' && (*s == 'x' || *s == 'X')) {
544 c = s[1];
545 s += 2;
546 base = 16;
548 if (base == 0)
549 base = c == '0' ? 8 : 10;
552 * Compute the cutoff value between legal numbers and illegal
553 * numbers. That is the largest legal value, divided by the
554 * base. An input number that is greater than this value, if
555 * followed by a legal input character, is too big. One that
556 * is equal to this value may be valid or not; the limit
557 * between valid and invalid numbers is then based on the last
558 * digit. For instance, if the range for longs is
559 * [-2147483648..2147483647] and the input base is 10,
560 * cutoff will be set to 214748364 and cutlim to either
561 * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
562 * a value > 214748364, or equal but the next digit is > 7 (or 8),
563 * the number is too big, and we will return a range error.
565 * Set any if any `digits' consumed; make it negative to indicate
566 * overflow.
568 cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
569 cutlim = cutoff % (unsigned long)base;
570 cutoff /= (unsigned long)base;
571 for (acc = 0, any = 0;; c = *s++) {
572 if (ACE_OS::ace_isdigit(c))
573 c -= '0';
574 else if (ACE_OS::ace_isalpha(c))
575 c -= ACE_OS::ace_isupper(c) ? 'A' - 10 : 'a' - 10;
576 else
577 break;
578 if (c >= base)
579 break;
580 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
581 any = -1;
582 else {
583 any = 1;
584 acc *= base;
585 acc += c;
588 if (any < 0) {
589 acc = neg ? LONG_MIN : LONG_MAX;
590 errno = ERANGE;
591 } else if (neg)
592 acc = -acc;
593 if (endptr != 0)
594 *endptr = any ? (char *)s - 1 : (char *)nptr;
595 return (acc);
597 #endif /* ACE_LACKS_STRTOL */
599 #if defined (ACE_LACKS_STRTOUL)
600 unsigned long
601 ACE_OS::strtoul_emulation (const char *nptr,
602 char **endptr,
603 register int base)
605 register const char *s = nptr;
606 register unsigned long acc;
607 register int c;
608 register unsigned long cutoff;
609 register int neg = 0, any, cutlim;
612 * See strtol for comments as to the logic used.
615 c = *s++;
616 while (ACE_OS::ace_isspace(c));
617 if (c == '-')
619 neg = 1;
620 c = *s++;
622 else if (c == '+')
623 c = *s++;
624 if ((base == 0 || base == 16) &&
625 c == '0' && (*s == 'x' || *s == 'X'))
627 c = s[1];
628 s += 2;
629 base = 16;
631 if (base == 0)
632 base = c == '0' ? 8 : 10;
633 cutoff = (unsigned long) ULONG_MAX / (unsigned long) base;
634 cutlim = (unsigned long) ULONG_MAX % (unsigned long) base;
636 for (acc = 0, any = 0;; c = *s++)
638 if (ACE_OS::ace_isdigit(c))
639 c -= '0';
640 else if (ACE_OS::ace_isalpha(c))
641 c -= ACE_OS::ace_isupper(c) ? 'A' - 10 : 'a' - 10;
642 else
643 break;
644 if (c >= base)
645 break;
646 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
647 any = -1;
648 else
650 any = 1;
651 acc *= base;
652 acc += c;
655 if (any < 0)
657 acc = ULONG_MAX;
658 errno = ERANGE;
660 else if (neg)
661 acc = -acc;
662 if (endptr != 0)
663 *endptr = any ? (char *) s - 1 : (char *) nptr;
664 return (acc);
666 #endif /* ACE_LACKS_STRTOUL */
668 #if defined (ACE_LACKS_STRTOULL)
669 ACE_UINT64
670 ACE_OS::strtoull_emulation (const char *nptr,
671 char **endptr,
672 register int base)
674 register const char *s = nptr;
675 register ACE_UINT64 acc;
676 register int c;
677 register ACE_UINT64 cutoff;
678 register int neg = 0, any, cutlim;
681 * See strtol for comments as to the logic used.
684 c = *s++;
685 while (ACE_OS::ace_isspace(c));
686 if (c == '-')
688 neg = 1;
689 c = *s++;
691 else if (c == '+')
692 c = *s++;
693 if ((base == 0 || base == 16) &&
694 c == '0' && (*s == 'x' || *s == 'X'))
696 c = s[1];
697 s += 2;
698 base = 16;
700 if (base == 0)
701 base = c == '0' ? 8 : 10;
703 cutoff = (ACE_UINT64) ACE_UINT64_MAX / (ACE_UINT64) base;
704 cutlim = (ACE_UINT64) ACE_UINT64_MAX % (ACE_UINT64) base;
706 for (acc = 0, any = 0;; c = *s++)
708 if (ACE_OS::ace_isdigit(c))
709 c -= '0';
710 else if (ACE_OS::ace_isalpha(c))
711 c -= ACE_OS::ace_isupper(c) ? 'A' - 10 : 'a' - 10;
712 else
713 break;
714 if (c >= base)
715 break;
716 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
717 any = -1;
718 else
720 any = 1;
721 acc *= base;
722 acc += c;
725 if (any < 0)
727 acc = ACE_UINT64_MAX;
728 errno = ERANGE;
730 else if (neg)
731 acc = -acc;
732 if (endptr != 0)
733 *endptr = any ? (char *) s - 1 : (char *) nptr;
734 return (acc);
736 #endif /* ACE_LACKS_STRTOULL */
738 #if defined (ACE_LACKS_MKSTEMP)
739 ACE_HANDLE
740 ACE_OS::mkstemp_emulation (ACE_TCHAR * s)
742 if (s == 0)
744 errno = EINVAL;
745 return ACE_INVALID_HANDLE;
748 // The "XXXXXX" template to be filled in.
749 ACE_TCHAR * const t = ACE_OS::strstr (s, ACE_TEXT ("XXXXXX"));
751 if (t == 0)
753 errno = EINVAL;
754 return ACE_INVALID_HANDLE;
757 static unsigned int const NUM_RETRIES = 50;
758 static unsigned int const NUM_CHARS = 6; // Do not change!
760 // Use ACE_Time_Value::msec(ACE_UINT64&) as opposed to
761 // ACE_Time_Value::msec(void) to avoid truncation.
762 ACE_UINT64 msec;
764 // Use a const ACE_Time_Value to resolve ambiguity between
765 // ACE_Time_Value::msec (long) and ACE_Time_Value::msec(ACE_UINT64&) const.
766 ACE_Time_Value const now = ACE_OS::gettimeofday();
767 now.msec (msec);
769 // Add the process and thread ids to ensure uniqueness.
770 msec += ACE_OS::getpid();
771 msec += (size_t) ACE_OS::thr_self();
773 // ACE_thread_t may be a char* (returned by ACE_OS::thr_self()) so
774 // we need to use a C-style cast as a catch-all in order to use a
775 // static_cast<> to an integral type.
776 ACE_RANDR_TYPE seed = static_cast<ACE_RANDR_TYPE> (msec);
778 // We only care about UTF-8 / ASCII characters in generated
779 // filenames. A UTF-16 or UTF-32 character could potentially cause
780 // a very large space to be searched in the below do/while() loop,
781 // greatly slowing down this mkstemp() implementation. It is more
782 // practical to limit the search space to UTF-8 / ASCII characters
783 // (i.e. 127 characters).
785 // Note that we can't make this constant static since the compiler
786 // may not inline the return value of ACE_Numeric_Limits::max(),
787 // meaning multiple threads could potentially initialize this value
788 // in parallel.
789 float const MAX_VAL =
790 static_cast<float> (ACE_Numeric_Limits<char>::max ());
792 // Use high-order bits rather than low-order ones (e.g. rand() %
793 // MAX_VAL). See Numerical Recipes in C: The Art of Scientific
794 // Computing (William H. Press, Brian P. Flannery, Saul
795 // A. Teukolsky, William T. Vetterling; New York: Cambridge
796 // University Press, 1992 (2nd ed., p. 277).
798 // e.g.: MAX_VAL * rand() / (RAND_MAX + 1.0)
800 // Factor out the constant coefficient.
801 float const coefficient =
802 static_cast<float> (MAX_VAL / (RAND_MAX + 1.0f));
804 // @@ These nested loops may be ineffecient. Improvements are
805 // welcome.
806 for (unsigned int i = 0; i < NUM_RETRIES; ++i)
808 for (unsigned int n = 0; n < NUM_CHARS; ++n)
810 ACE_TCHAR r;
812 // This do/while() loop allows this alphanumeric character
813 // selection to work for EBCDIC, as well.
816 r = static_cast<ACE_TCHAR> (coefficient * ACE_OS::rand_r (seed));
818 while (!ACE_OS::ace_isalnum (r));
820 t[n] = r;
823 static int const perms =
824 #if defined (ACE_WIN32)
825 0; /* Do not share while open. */
826 #else
827 0600; /* S_IRUSR | S_IWUSR */
828 #endif /* ACE_WIN32 */
830 // Create the file with the O_EXCL bit set to ensure that we're
831 // not subject to a symbolic link attack.
833 // Note that O_EXCL is subject to a race condition over NFS
834 // filesystems.
835 ACE_HANDLE const handle = ACE_OS::open (s,
836 O_RDWR | O_CREAT | O_EXCL,
837 perms);
839 if (handle != ACE_INVALID_HANDLE)
840 return handle;
843 errno = EEXIST; // Couldn't create a unique temporary file.
844 return ACE_INVALID_HANDLE;
846 #endif /* ACE_LACKS_MKSTEMP */
848 #if !defined (ACE_HAS_GETPROGNAME) && !defined (ACE_HAS_SETPROGNAME)
849 static const char *__progname = "";
850 #endif /* !ACE_HAS_GETPROGNAME && !ACE_HAS_SETPROGNAME */
852 #if !defined (ACE_HAS_GETPROGNAME)
853 const char*
854 ACE_OS::getprogname_emulation ()
856 return __progname;
858 #endif /* !ACE_HAS_GETPROGNAME */
860 #if !defined (ACE_HAS_SETPROGNAME)
861 void
862 ACE_OS::setprogname_emulation (const char* progname)
864 const char *p = ACE_OS::strrchr (progname, '/');
865 if (p != 0)
866 __progname = p + 1;
867 else
868 __progname = progname;
870 #endif /* !ACE_HAS_SETPROGNAME */
872 ACE_END_VERSIONED_NAMESPACE_DECL