00001
00002
00003 #include "ace/OS_NS_stdlib.h"
00004
00005 ACE_RCSID (ace,
00006 OS_NS_stdlib,
00007 "OS_NS_stdlib.cpp,v 1.31 2006/05/30 10:47:53 jwillemsen Exp")
00008
00009 #if !defined (ACE_HAS_INLINED_OSCALLS)
00010 # include "ace/OS_NS_stdlib.inl"
00011 #endif
00012
00013 #include "ace/OS_Memory.h"
00014
00015 #include "ace/OS_NS_unistd.h"
00016
00017 #if defined (ACE_LACKS_MKTEMP) \
00018 || defined (ACE_LACKS_MKSTEMP) \
00019 || defined (ACE_LACKS_REALPATH)
00020 # include "ace/OS_NS_stdio.h"
00021 # include "ace/OS_NS_sys_stat.h"
00022 #endif
00023
00024 #if defined (ACE_LACKS_MKSTEMP)
00025 # include "ace/OS_NS_fcntl.h"
00026 # include "ace/OS_NS_ctype.h"
00027 # include "ace/OS_NS_sys_time.h"
00028 # if !defined (ACE_HAS_WINCE) && !(defined (ACE_VXWORKS) && (ACE_VXWORKS == 0x551)) && !defined (max)
00029 # include <limits>
00030 # endif
00031 #endif
00032
00033 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00034
00035 ACE_EXIT_HOOK ACE_OS::exit_hook_ = 0;
00036
00037 void *
00038 ACE_OS::calloc (size_t elements, size_t sizeof_elements)
00039 {
00040 #if !defined (ACE_HAS_WINCE)
00041 return ACE_CALLOC_FUNC (elements, sizeof_elements);
00042 #else
00043
00044
00045 return ACE_MALLOC_FUNC (elements * sizeof_elements);
00046 #endif
00047 }
00048
00049 void
00050 ACE_OS::exit (int status)
00051 {
00052 ACE_OS_TRACE ("ACE_OS::exit");
00053
00054 #if defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER) && !defined (ACE_HAS_WINCE) && !defined (ACE_DOESNT_INSTANTIATE_NONSTATIC_OBJECT_MANAGER)
00055
00056
00057
00058 if (exit_hook_)
00059 (*exit_hook_) ();
00060 #endif
00061
00062 #if !defined (ACE_HAS_WINCE)
00063 # if defined (ACE_WIN32)
00064 ::ExitProcess ((UINT) status);
00065 # else
00066 ::exit (status);
00067 # endif
00068 #else
00069
00070
00071 ::TerminateProcess (::GetCurrentProcess (), status);
00072 #endif
00073 }
00074
00075 void
00076 ACE_OS::free (void *ptr)
00077 {
00078 ACE_FREE_FUNC (ACE_MALLOC_T (ptr));
00079 }
00080
00081
00082
00083
00084
00085
00086 #if defined (ACE_WIN32) && defined (UNICODE) && !defined (ACE_USES_TCHAR)
00087 #undef GetEnvironmentStrings
00088 #endif
00089
00090 ACE_TCHAR *
00091 ACE_OS::getenvstrings (void)
00092 {
00093 #if defined (ACE_LACKS_ENV)
00094 ACE_NOTSUP_RETURN (0);
00095 #elif defined (ACE_WIN32)
00096 # if defined (ACE_USES_WCHAR)
00097 return ::GetEnvironmentStringsW ();
00098 # else
00099 return ::GetEnvironmentStrings ();
00100 # endif
00101 #else
00102 ACE_NOTSUP_RETURN (0);
00103 #endif
00104 }
00105
00106 #if !defined (ACE_HAS_ITOA)
00107 char *
00108 ACE_OS::itoa_emulation (int value, char *string, int radix)
00109 {
00110 char *e = string;
00111 char *b = string;
00112
00113
00114
00115 if (value == 0)
00116 {
00117 string[0] = '0';
00118 string[1] = 0;
00119 return string;
00120 }
00121
00122
00123
00124
00125 if (value < 0 && radix == 10)
00126 {
00127 string[0] = '-';
00128 ++b;
00129 ++e;
00130 value = -value;
00131 }
00132
00133
00134
00135 while (value != 0)
00136 {
00137 int mod = value % radix;
00138 value = value / radix;
00139
00140 *e++ = (mod < 10) ? '0' + mod : 'a' + mod - 10;
00141 }
00142
00143 *e-- = 0;
00144
00145
00146
00147 while (e > b)
00148 {
00149 char temp = *e;
00150 *e = *b;
00151 *b = temp;
00152 ++b;
00153 --e;
00154 }
00155
00156 return string;
00157 }
00158 #endif
00159
00160 #if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_ITOW)
00161 wchar_t *
00162 ACE_OS::itow_emulation (int value, wchar_t *string, int radix)
00163 {
00164 wchar_t *e = string;
00165 wchar_t *b = string;
00166
00167
00168
00169 if (value == 0)
00170 {
00171 string[0] = '0';
00172 string[1] = 0;
00173 return string;
00174 }
00175
00176
00177
00178
00179 if (value < 0 && radix == 10)
00180 {
00181 string[0] = '-';
00182 b++;
00183 }
00184
00185
00186
00187 while (value != 0)
00188 {
00189 int mod = value % radix;
00190 value = value / radix;
00191
00192 *e++ = (mod < 10) ? '0' + mod : 'a' + mod - 10;
00193 }
00194
00195 *e-- = 0;
00196
00197
00198
00199 while (e > b)
00200 {
00201 wchar_t temp = *e;
00202 *e = *b;
00203 *b = temp;
00204 ++b;
00205 --e;
00206 }
00207
00208 return string;
00209 }
00210 #endif
00211
00212 void *
00213 ACE_OS::malloc (size_t nbytes)
00214 {
00215 return ACE_MALLOC_FUNC (nbytes);
00216 }
00217
00218 #if defined (ACE_LACKS_MKTEMP)
00219 ACE_TCHAR *
00220 ACE_OS::mktemp (ACE_TCHAR *s)
00221 {
00222 ACE_OS_TRACE ("ACE_OS::mktemp");
00223 if (s == 0)
00224
00225 return 0;
00226 else
00227 {
00228 ACE_TCHAR *xxxxxx = ACE_OS::strstr (s, ACE_LIB_TEXT ("XXXXXX"));
00229
00230 if (xxxxxx == 0)
00231
00232 return s;
00233 else
00234 {
00235 ACE_TCHAR unique_letter = ACE_LIB_TEXT ('a');
00236 ACE_stat sb;
00237
00238
00239
00240
00241
00242
00243
00244 ACE_OS::sprintf (xxxxxx,
00245 ACE_LIB_TEXT ("%05d%c"),
00246 ACE_OS::getpid (),
00247 unique_letter);
00248 while (ACE_OS::stat (s, &sb) >= 0)
00249 {
00250 if (++unique_letter <= ACE_LIB_TEXT ('z'))
00251 ACE_OS::sprintf (xxxxxx,
00252 ACE_LIB_TEXT ("%05d%c"),
00253 ACE_OS::getpid (),
00254 unique_letter);
00255 else
00256 {
00257
00258 ACE_OS::sprintf (xxxxxx, ACE_LIB_TEXT ("%s"), ACE_LIB_TEXT (""));
00259 return s;
00260 }
00261 }
00262 }
00263 return s;
00264 }
00265 }
00266 #endif
00267
00268 void *
00269 ACE_OS::realloc (void *ptr, size_t nbytes)
00270 {
00271 return ACE_REALLOC_FUNC (ACE_MALLOC_T (ptr), nbytes);
00272 }
00273
00274 #if defined (ACE_LACKS_REALPATH) && !defined (ACE_HAS_WINCE)
00275 char *
00276 ACE_OS::realpath (const char *file_name,
00277 char *resolved_name)
00278 {
00279 ACE_OS_TRACE ("ACE_OS::realpath");
00280
00281 if (file_name == 0)
00282 {
00283
00284
00285 errno = EINVAL;
00286 return 0;
00287 }
00288
00289 if (*file_name == '\0')
00290 {
00291
00292
00293
00294 errno = ENOENT;
00295 return 0;
00296 }
00297
00298 char* rpath;
00299
00300 if (resolved_name == 0)
00301 {
00302
00303
00304
00305
00306
00307
00308 rpath = static_cast<char*>(ACE_OS::malloc (PATH_MAX));
00309 if (rpath == 0)
00310 {
00311 errno = ENOMEM;
00312 return 0;
00313 }
00314 }
00315 else
00316 {
00317 rpath = resolved_name;
00318 }
00319
00320 char* dest;
00321
00322 if (*file_name != '/')
00323 {
00324
00325 if (ACE_OS::getcwd (rpath, PATH_MAX) == 0)
00326 {
00327 if (resolved_name == 0)
00328 ACE_OS::free (rpath);
00329 return 0;
00330 }
00331 dest = ACE_OS::strchr (rpath, '\0');
00332 }
00333 else
00334 {
00335 dest = rpath;
00336 }
00337
00338 #if !defined (ACE_LACKS_SYMLINKS)
00339 char expand_buf[PATH_MAX];
00340 int nlinks = 0;
00341 #endif
00342
00343 while (*file_name)
00344 {
00345 *dest++ = '/';
00346
00347
00348 while (*file_name == '/')
00349 ++file_name;
00350
00351 char* start = dest;
00352
00353
00354 while (*file_name && *file_name != '/')
00355 {
00356 *dest++ = *file_name++;
00357 if (dest - rpath > PATH_MAX)
00358 {
00359 errno = ENAMETOOLONG;
00360 if (resolved_name == 0)
00361 ACE_OS::free (rpath);
00362 return 0;
00363 }
00364 }
00365
00366 if (start == dest)
00367 {
00368 if (dest - rpath > 1)
00369 --dest;
00370 break;
00371 }
00372 else if (dest - start == 1 && *start == '.')
00373 {
00374 dest -= 2;
00375 }
00376 else if (dest - start == 2 && *start == '.' && *(start +1) == '.')
00377 {
00378 dest -= 3;
00379 if (dest > rpath)
00380 while (*--dest != '/')
00381 ;
00382 }
00383 # if !defined (ACE_LACKS_SYMLINKS)
00384 else
00385 {
00386 ACE_stat st;
00387
00388 *dest = '\0';
00389 if (ACE_OS::lstat(rpath, &st) < 0)
00390 {
00391 if (resolved_name == 0)
00392 ACE_OS::free (rpath);
00393 return 0;
00394 }
00395
00396
00397 if (S_ISLNK (st.st_mode))
00398 {
00399 if (++nlinks > MAXSYMLINKS)
00400 {
00401 errno = ELOOP;
00402 if (resolved_name == 0)
00403 ACE_OS::free (rpath);
00404 return 0;
00405 }
00406
00407 char link_buf[PATH_MAX];
00408
00409 ssize_t link_len = ACE_OS::readlink (rpath, link_buf, PATH_MAX);
00410 int tail_len = ACE_OS::strlen (file_name) + 1;
00411
00412
00413 if (link_len + tail_len > PATH_MAX)
00414 {
00415 errno = ENAMETOOLONG;
00416 if (resolved_name == 0)
00417 ACE_OS::free (rpath);
00418 return 0;
00419 }
00420
00421
00422 ACE_OS::memmove (expand_buf + link_len, file_name, tail_len);
00423 ACE_OS::memcpy (expand_buf, link_buf, link_len);
00424
00425 if (*link_buf == '/')
00426 {
00427 dest = rpath;
00428 }
00429 else
00430 {
00431 --dest;
00432 while (*--dest != '/')
00433 ;
00434 }
00435 file_name = expand_buf;
00436 }
00437 }
00438 # endif
00439 }
00440
00441 *dest = '\0';
00442
00443 return rpath;
00444 }
00445 #endif
00446
00447 #if defined (ACE_LACKS_STRTOL)
00448 long
00449 ACE_OS::strtol_emulation (const char *nptr, char **endptr, int base)
00450 {
00451 register const char *s = nptr;
00452 register unsigned long acc;
00453 register int c;
00454 register unsigned long cutoff;
00455 register int neg = 0, any, cutlim;
00456
00457
00458
00459
00460
00461
00462 do {
00463 c = *s++;
00464 } while (isspace(c));
00465 if (c == '-') {
00466 neg = 1;
00467 c = *s++;
00468 } else if (c == '+')
00469 c = *s++;
00470 if ((base == 0 || base == 16) &&
00471 c == '0' && (*s == 'x' || *s == 'X')) {
00472 c = s[1];
00473 s += 2;
00474 base = 16;
00475 }
00476 if (base == 0)
00477 base = c == '0' ? 8 : 10;
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496 cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
00497 cutlim = cutoff % (unsigned long)base;
00498 cutoff /= (unsigned long)base;
00499 for (acc = 0, any = 0;; c = *s++) {
00500 if (isdigit(c))
00501 c -= '0';
00502 else if (isalpha(c))
00503 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
00504 else
00505 break;
00506 if (c >= base)
00507 break;
00508 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
00509 any = -1;
00510 else {
00511 any = 1;
00512 acc *= base;
00513 acc += c;
00514 }
00515 }
00516 if (any < 0) {
00517 acc = neg ? LONG_MIN : LONG_MAX;
00518 errno = ERANGE;
00519 } else if (neg)
00520 acc = -acc;
00521 if (endptr != 0)
00522 *endptr = any ? (char *)s - 1 : (char *)nptr;
00523 return (acc);
00524 }
00525 #endif
00526
00527 #if defined (ACE_LACKS_STRTOUL)
00528 unsigned long
00529 ACE_OS::strtoul_emulation (const char *nptr,
00530 char **endptr,
00531 register int base)
00532 {
00533 register const char *s = nptr;
00534 register unsigned long acc;
00535 register int c;
00536 register unsigned long cutoff;
00537 register int neg = 0, any, cutlim;
00538
00539
00540
00541
00542 do
00543 c = *s++;
00544 while (isspace(c));
00545 if (c == '-')
00546 {
00547 neg = 1;
00548 c = *s++;
00549 }
00550 else if (c == '+')
00551 c = *s++;
00552 if ((base == 0 || base == 16) &&
00553 c == '0' && (*s == 'x' || *s == 'X'))
00554 {
00555 c = s[1];
00556 s += 2;
00557 base = 16;
00558 }
00559 if (base == 0)
00560 base = c == '0' ? 8 : 10;
00561 cutoff = (unsigned long) ULONG_MAX / (unsigned long) base;
00562 cutlim = (unsigned long) ULONG_MAX % (unsigned long) base;
00563
00564 for (acc = 0, any = 0;; c = *s++)
00565 {
00566 if (isdigit(c))
00567 c -= '0';
00568 else if (isalpha(c))
00569 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
00570 else
00571 break;
00572 if (c >= base)
00573 break;
00574 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
00575 any = -1;
00576 else
00577 {
00578 any = 1;
00579 acc *= base;
00580 acc += c;
00581 }
00582 }
00583 if (any < 0)
00584 {
00585 acc = ULONG_MAX;
00586 errno = ERANGE;
00587 } else if (neg)
00588 acc = -acc;
00589 if (endptr != 0)
00590 *endptr = any ? (char *) s - 1 : (char *) nptr;
00591 return (acc);
00592 }
00593 #endif
00594
00595
00596 #if defined (ACE_LACKS_MKSTEMP)
00597 ACE_HANDLE
00598 ACE_OS::mkstemp_emulation (ACE_TCHAR * s)
00599 {
00600 if (s == 0)
00601 {
00602 errno = EINVAL;
00603 return ACE_INVALID_HANDLE;
00604 }
00605
00606
00607 ACE_TCHAR * const t = ACE_OS::strstr (s, ACE_LIB_TEXT ("XXXXXX"));
00608
00609 if (t == 0)
00610 {
00611 errno = EINVAL;
00612 return ACE_INVALID_HANDLE;
00613 }
00614
00615 static unsigned int const NUM_RETRIES = 50;
00616 static unsigned int const NUM_CHARS = 6;
00617
00618 ACE_RANDR_TYPE seed =
00619 static_cast<ACE_RANDR_TYPE> (ACE_OS::gettimeofday ().msec ());
00620
00621
00622
00623
00624
00625
00626
00627 # if defined (ACE_HAS_WINCE) || (defined (ACE_VXWORKS) && (ACE_VXWORKS == 0x551)) || defined (max)
00628 static float const MAX_VAL = static_cast<float> (127);
00629 #else
00630 static float const MAX_VAL =
00631 static_cast<float> (std::numeric_limits<char>::max ());
00632 #endif
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643 static float const coefficient =
00644 static_cast<float> (MAX_VAL / (RAND_MAX + 1.0f));
00645
00646
00647
00648 for (unsigned int i = 0; i < NUM_RETRIES; ++i)
00649 {
00650 for (unsigned int n = 0; n < NUM_CHARS; ++n)
00651 {
00652 ACE_TCHAR r;
00653
00654
00655
00656 do
00657 {
00658 r =
00659 static_cast<ACE_TCHAR> (coefficient * ACE_OS::rand_r (seed));
00660 }
00661 while (!ACE_OS::ace_isalnum (r));
00662
00663 t[n] = r;
00664 }
00665
00666 static int const perms =
00667 #if defined (ACE_WIN32)
00668 0;
00669 #else
00670 0600;
00671 #endif
00672
00673
00674
00675
00676
00677
00678 ACE_HANDLE const handle = ACE_OS::open (s,
00679 O_RDWR | O_CREAT | O_EXCL,
00680 perms);
00681
00682 if (handle != ACE_INVALID_HANDLE)
00683 return handle;
00684 }
00685
00686 errno = EEXIST;
00687 return ACE_INVALID_HANDLE;
00688 }
00689 #endif
00690
00691 ACE_END_VERSIONED_NAMESPACE_DECL