00001
00002
00003 #include "ace/OS_NS_unistd.h"
00004
00005 ACE_RCSID (ace, OS_NS_unistd, "$Id: OS_NS_unistd.cpp 81284 2008-04-09 03:08:22Z iliyan $")
00006
00007 #if !defined (ACE_HAS_INLINED_OSCALLS)
00008 # include "ace/OS_NS_unistd.inl"
00009 #endif
00010
00011 #include "ace/Base_Thread_Adapter.h"
00012 #include "ace/OS_NS_stdlib.h"
00013 #include "ace/OS_NS_ctype.h"
00014 #include "ace/Default_Constants.h"
00015 #include "ace/OS_Memory.h"
00016 #include "ace/OS_NS_Thread.h"
00017 #include "ace/Object_Manager_Base.h"
00018 #include "ace/Auto_Ptr.h"
00019 #include "ace/os_include/sys/os_pstat.h"
00020 #include "ace/os_include/sys/os_sysctl.h"
00021
00022 #if defined (ACE_NEEDS_FTRUNCATE)
00023 extern "C" int
00024 ftruncate (ACE_HANDLE handle, long len)
00025 {
00026 struct flock fl;
00027 fl.l_whence = 0;
00028 fl.l_len = 0;
00029 fl.l_start = len;
00030 fl.l_type = F_WRLCK;
00031
00032 return ACE_OS::fcntl (handle, F_FREESP, reinterpret_cast <long> (&fl));
00033 }
00034 #endif
00035
00036
00037
00038 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00039
00040 int
00041 ACE_OS::argv_to_string (ACE_TCHAR **argv,
00042 ACE_TCHAR *&buf,
00043 bool substitute_env_args,
00044 bool quote_args)
00045 {
00046 if (argv == 0 || argv[0] == 0)
00047 return 0;
00048
00049 int argc;
00050 for (argc = 0; argv[argc] != 0; ++argc)
00051 continue;
00052
00053 return argv_to_string (argc,
00054 argv,
00055 buf,
00056 substitute_env_args,
00057 quote_args);
00058 }
00059
00060 int
00061 ACE_OS::argv_to_string (int argc,
00062 ACE_TCHAR **argv,
00063 ACE_TCHAR *&buf,
00064 bool substitute_env_args,
00065 bool quote_args)
00066 {
00067 if (argc <= 0 || argv == 0 || argv[0] == 0)
00068 return 0;
00069
00070 size_t buf_len = 0;
00071
00072
00073
00074 ACE_TCHAR **argv_p = argv;
00075
00076 for (int i = 0; i < argc; ++i)
00077 {
00078 #if !defined (ACE_LACKS_ENV)
00079
00080 if (substitute_env_args
00081 && ACE_OS::strchr (argv[i], ACE_TEXT ('$')) != 0)
00082 {
00083 if (argv_p == argv)
00084 {
00085 argv_p = (ACE_TCHAR **) ACE_OS::malloc (argc * sizeof (ACE_TCHAR *));
00086 if (argv_p == 0)
00087 {
00088 errno = ENOMEM;
00089 return 0;
00090 }
00091 ACE_OS::memcpy (argv_p, argv, argc * sizeof (ACE_TCHAR *));
00092 }
00093 argv_p[i] = ACE_OS::strenvdup (argv[i]);
00094 if (argv_p[i] == 0)
00095 {
00096 ACE_OS::free (argv_p);
00097 errno = ENOMEM;
00098 return 0;
00099 }
00100 }
00101 #endif
00102
00103
00104
00105 if (quote_args
00106 && (ACE_OS::strchr (argv_p[i], ACE_TEXT (' ')) != 0
00107 || ACE_OS::strchr (argv_p[i], ACE_TEXT ('\t')) != 0
00108 || ACE_OS::strchr (argv_p[i], ACE_TEXT ('\n')) != 0
00109 || *argv_p[i] == 0))
00110 {
00111 if (argv_p == argv)
00112 {
00113 argv_p = (ACE_TCHAR **) ACE_OS::malloc (argc * sizeof (ACE_TCHAR *));
00114 if (argv_p == 0)
00115 {
00116 errno = ENOMEM;
00117 return 0;
00118 }
00119 ACE_OS::memcpy (argv_p, argv, argc * sizeof (ACE_TCHAR *));
00120 }
00121 int quotes = 0;
00122 ACE_TCHAR *temp = argv_p[i];
00123 if (ACE_OS::strchr (temp, ACE_TEXT ('"')) != 0)
00124 {
00125 for (int j = 0; temp[j] != 0; ++j)
00126 if (temp[j] == ACE_TEXT ('"'))
00127 ++quotes;
00128 }
00129 argv_p[i] =
00130 (ACE_TCHAR *) ACE_OS::malloc (ACE_OS::strlen (temp) * sizeof (ACE_TCHAR) + quotes + 3);
00131 if (argv_p[i] == 0)
00132 {
00133 ACE_OS::free (argv_p);
00134 errno = ENOMEM;
00135 return 0;
00136 }
00137 ACE_TCHAR *end = argv_p[i];
00138
00139 *end++ = ACE_TEXT ('"');
00140
00141 if (quotes > 0)
00142 {
00143 for (ACE_TCHAR *p = temp;
00144 *p != 0;
00145 *end++ = *p++)
00146 if (*p == ACE_TEXT ('"'))
00147 *end++ = ACE_TEXT ('\\');
00148
00149 *end++ = ACE_TEXT ('\0');
00150 }
00151 else
00152 end = ACE_OS::strecpy (end, temp);
00153
00154 end[-1] = ACE_TEXT ('"');
00155
00156 *end = ACE_TEXT ('\0');
00157 if (temp != argv[i])
00158 ACE_OS::free (temp);
00159 }
00160 buf_len += ACE_OS::strlen (argv_p[i]);
00161
00162
00163 buf_len++;
00164 }
00165
00166
00167
00168
00169 ACE_NEW_RETURN (buf,
00170 ACE_TCHAR[buf_len + 1],
00171 0);
00172
00173
00174 buf[0] = ACE_TEXT ('\0');
00175 ACE_TCHAR *end = buf;
00176
00177 for (int i = 0; i < argc; ++i)
00178 {
00179 end = ACE_OS::strecpy (end, argv_p[i]);
00180 if (argv_p[i] != argv[i])
00181 ACE_OS::free (argv_p[i]);
00182
00183
00184
00185 end[-1] = ACE_TEXT (' ');
00186 }
00187
00188 *end = ACE_TEXT ('\0');
00189
00190 if (argv_p != argv)
00191 ACE_OS::free (argv_p);
00192
00193
00194 return argc;
00195 }
00196
00197 int
00198 ACE_OS::execl (const char * , const char * , ...)
00199 {
00200 ACE_OS_TRACE ("ACE_OS::execl");
00201 ACE_NOTSUP_RETURN (-1);
00202
00203
00204 }
00205
00206 int
00207 ACE_OS::execle (const char * , const char * , ...)
00208 {
00209 ACE_OS_TRACE ("ACE_OS::execle");
00210 ACE_NOTSUP_RETURN (-1);
00211
00212
00213 }
00214
00215 int
00216 ACE_OS::execlp (const char * , const char * , ...)
00217 {
00218 ACE_OS_TRACE ("ACE_OS::execlp");
00219 ACE_NOTSUP_RETURN (-1);
00220
00221
00222 }
00223
00224 pid_t
00225 ACE_OS::fork (const ACE_TCHAR *program_name)
00226 {
00227 ACE_OS_TRACE ("ACE_OS::fork");
00228 # if defined (ACE_LACKS_FORK)
00229 ACE_UNUSED_ARG (program_name);
00230 ACE_NOTSUP_RETURN (pid_t (-1));
00231 # else
00232 pid_t const pid =
00233 # if defined (ACE_HAS_STHREADS)
00234 ::fork1 ();
00235 #else
00236 ::fork ();
00237 #endif
00238
00239 #if !defined (ACE_HAS_MINIMAL_ACE_OS) && !defined (ACE_HAS_THREADS)
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 if (pid == 0)
00254 ACE_Base_Thread_Adapter::sync_log_msg (program_name);
00255
00256 #else
00257
00258 ACE_UNUSED_ARG (program_name);
00259
00260 #endif
00261
00262 return pid;
00263 # endif
00264 }
00265
00266
00267
00268
00269 pid_t
00270 ACE_OS::fork_exec (ACE_TCHAR *argv[])
00271 {
00272 # if defined (ACE_WIN32)
00273
00274 ACE_TCHAR *buf = 0;
00275 ACE_Auto_Basic_Array_Ptr<ACE_TCHAR> safe_ptr (buf);
00276 if (ACE_OS::argv_to_string (argv, buf) != -1)
00277 {
00278 PROCESS_INFORMATION process_info;
00279 # if !defined (ACE_HAS_WINCE)
00280 ACE_TEXT_STARTUPINFO startup_info;
00281 ACE_OS::memset ((void *) &startup_info,
00282 0,
00283 sizeof startup_info);
00284 startup_info.cb = sizeof startup_info;
00285
00286 if (ACE_TEXT_CreateProcess (0,
00287 buf,
00288 0,
00289 0,
00290 TRUE,
00291 0,
00292 0,
00293 0,
00294 &startup_info,
00295 &process_info))
00296 # else
00297 if (ACE_TEXT_CreateProcess (0,
00298 buf,
00299 0,
00300 0,
00301 FALSE,
00302 0,
00303 0,
00304 0,
00305 0,
00306 &process_info))
00307 # endif
00308 {
00309
00310 ACE_OS::close (process_info.hThread);
00311 ACE_OS::close (process_info.hProcess);
00312
00313 return process_info.dwProcessId;
00314 }
00315 }
00316
00317
00318 return -1;
00319 # else
00320 pid_t const result = ACE_OS::fork ();
00321
00322 # if defined (ACE_USES_WCHAR)
00323
00324
00325 char **cargv = 0;
00326 int arg_count;
00327 # endif
00328
00329 switch (result)
00330 {
00331 case -1:
00332
00333 return -1;
00334 case 0:
00335
00336 # if defined (ACE_USES_WCHAR)
00337 for (arg_count = 0; argv[arg_count] != 0; ++arg_count)
00338 ;
00339 ++arg_count;
00340 ACE_NEW_NORETURN (cargv, char*[arg_count]);
00341 if (cargv == 0)
00342 ACE_OS::exit (errno);
00343 --arg_count;
00344 cargv[arg_count] = 0;
00345 while (--arg_count >= 0)
00346 cargv[arg_count] = ACE_Wide_To_Ascii::convert (argv[arg_count]);
00347
00348
00349 if (ACE_OS::execv (cargv[0], cargv) == -1)
00350 ACE_OS::exit (errno);
00351 # else
00352 if (ACE_OS::execv (argv[0], argv) == -1)
00353 {
00354
00355
00356
00357
00358
00359 ACE_OS::exit (errno);
00360 }
00361 # endif
00362
00363 default:
00364
00365 return result;
00366 }
00367 # endif
00368 }
00369
00370 long
00371 ACE_OS::num_processors (void)
00372 {
00373 ACE_OS_TRACE ("ACE_OS::num_processors");
00374
00375 #if defined (ACE_HAS_PHARLAP)
00376 return 1;
00377 #elif defined (ACE_WIN32)
00378 SYSTEM_INFO sys_info;
00379 ::GetSystemInfo (&sys_info);
00380 return sys_info.dwNumberOfProcessors;
00381 #elif defined (_SC_NPROCESSORS_CONF)
00382 return ::sysconf (_SC_NPROCESSORS_CONF);
00383 #elif defined (ACE_HAS_SYSCTL)
00384 int num_processors;
00385 int mib[2] = { CTL_HW, HW_NCPU };
00386 size_t len = sizeof (num_processors);
00387 if (::sysctl (mib, 2, &num_processors, &len, 0, 0) != -1)
00388 return num_processors;
00389 else
00390 return -1;
00391 #elif defined (__hpux)
00392 struct pst_dynamic psd;
00393 if (::pstat_getdynamic (&psd, sizeof (psd), (size_t) 1, 0) != -1)
00394 return psd.psd_max_proc_cnt;
00395 else
00396 return -1;
00397 #else
00398 ACE_NOTSUP_RETURN (-1);
00399 #endif
00400 }
00401
00402 long
00403 ACE_OS::num_processors_online (void)
00404 {
00405 ACE_OS_TRACE ("ACE_OS::num_processors_online");
00406
00407 #if defined (ACE_HAS_PHARLAP)
00408 return 1;
00409 #elif defined (ACE_WIN32)
00410 SYSTEM_INFO sys_info;
00411 ::GetSystemInfo (&sys_info);
00412 long active_processors = 0;
00413 DWORD_PTR mask = sys_info.dwActiveProcessorMask;
00414 while (mask != 0)
00415 {
00416 if (mask & 1)
00417 ++active_processors;
00418 mask >>= 1;
00419 }
00420 return active_processors;
00421 #elif defined (_SC_NPROCESSORS_ONLN)
00422 return ::sysconf (_SC_NPROCESSORS_ONLN);
00423 #elif defined (ACE_HAS_SYSCTL)
00424 int num_processors;
00425 int mib[2] = { CTL_HW, HW_NCPU };
00426 size_t len = sizeof (num_processors);
00427 if (::sysctl (mib, 2, &num_processors, &len, 0, 0) != -1)
00428 return num_processors;
00429 else
00430 return -1;
00431 #elif defined (__hpux)
00432 struct pst_dynamic psd;
00433 if (::pstat_getdynamic (&psd, sizeof (psd), (size_t) 1, 0) != -1)
00434 return psd.psd_proc_cnt;
00435 else
00436 return -1;
00437 #else
00438 ACE_NOTSUP_RETURN (-1);
00439 #endif
00440 }
00441
00442 ssize_t
00443 ACE_OS::read_n (ACE_HANDLE handle,
00444 void *buf,
00445 size_t len,
00446 size_t *bt)
00447 {
00448 size_t temp;
00449 size_t &bytes_transferred = bt == 0 ? temp : *bt;
00450 ssize_t n = 0;
00451
00452 for (bytes_transferred = 0;
00453 bytes_transferred < len;
00454 bytes_transferred += n)
00455 {
00456 n = ACE_OS::read (handle,
00457 (char *) buf + bytes_transferred,
00458 len - bytes_transferred);
00459
00460 if (n == -1 || n == 0)
00461 return n;
00462 }
00463
00464 return bytes_transferred;
00465 }
00466
00467 ssize_t
00468 ACE_OS::pread (ACE_HANDLE handle,
00469 void *buf,
00470 size_t nbytes,
00471 ACE_OFF_T offset)
00472 {
00473 # if defined (ACE_HAS_P_READ_WRITE)
00474 # if defined (ACE_WIN32)
00475
00476 ACE_OS_GUARD
00477
00478
00479 LONG original_high_position = 0;
00480 DWORD original_low_position = ::SetFilePointer (handle,
00481 0,
00482 &original_high_position,
00483 FILE_CURRENT);
00484
00485 if (original_low_position == INVALID_SET_FILE_POINTER
00486 && GetLastError () != NO_ERROR)
00487 return -1;
00488
00489
00490 LONG low_offset = ACE_LOW_PART (offset);
00491 LONG high_offset = ACE_HIGH_PART (offset);
00492 DWORD altered_position = ::SetFilePointer (handle,
00493 low_offset,
00494 &high_offset,
00495 FILE_BEGIN);
00496 if (altered_position == INVALID_SET_FILE_POINTER
00497 && GetLastError () != NO_ERROR)
00498 return -1;
00499
00500 DWORD bytes_read;
00501
00502 # if defined (ACE_HAS_WIN32_OVERLAPPED_IO)
00503
00504 OVERLAPPED overlapped;
00505 overlapped.Internal = 0;
00506 overlapped.InternalHigh = 0;
00507 overlapped.Offset = low_offset;
00508 overlapped.OffsetHigh = high_offset;
00509 overlapped.hEvent = 0;
00510
00511 BOOL result = ::ReadFile (handle,
00512 buf,
00513 static_cast <DWORD> (nbytes),
00514 &bytes_read,
00515 &overlapped);
00516
00517 if (result == FALSE)
00518 {
00519 if (::GetLastError () != ERROR_IO_PENDING)
00520 return -1;
00521
00522 else
00523 {
00524 result = ::GetOverlappedResult (handle,
00525 &overlapped,
00526 &bytes_read,
00527 TRUE);
00528 if (result == FALSE)
00529 return -1;
00530 }
00531 }
00532
00533 # else
00534
00535 BOOL result = ::ReadFile (handle,
00536 buf,
00537 nbytes,
00538 &bytes_read,
00539 0);
00540 if (result == FALSE)
00541 return -1;
00542
00543 # endif
00544
00545
00546 if (::SetFilePointer (handle,
00547 original_low_position,
00548 &original_high_position,
00549 FILE_BEGIN) == INVALID_SET_FILE_POINTER
00550 && GetLastError () != NO_ERROR)
00551 return -1;
00552
00553 return (ssize_t) bytes_read;
00554
00555 # else
00556
00557 return ::pread (handle, buf, nbytes, offset);
00558
00559 # endif
00560
00561 # else
00562
00563 ACE_OS_GUARD
00564
00565
00566 ACE_OFF_T original_position = ACE_OS::lseek (handle,
00567 0,
00568 SEEK_CUR);
00569
00570 if (original_position == -1)
00571 return -1;
00572
00573
00574 ACE_OFF_T altered_position = ACE_OS::lseek (handle, offset, SEEK_SET);
00575
00576 if (altered_position == -1)
00577 return -1;
00578
00579 ssize_t const bytes_read = ACE_OS::read (handle, buf, nbytes);
00580
00581 if (bytes_read == -1)
00582 return -1;
00583
00584 if (ACE_OS::lseek (handle,
00585 original_position,
00586 SEEK_SET) == -1)
00587 return -1;
00588
00589 return bytes_read;
00590
00591 # endif
00592 }
00593
00594 ssize_t
00595 ACE_OS::pwrite (ACE_HANDLE handle,
00596 const void *buf,
00597 size_t nbytes,
00598 ACE_OFF_T offset)
00599 {
00600 # if defined (ACE_HAS_P_READ_WRITE)
00601 # if defined (ACE_WIN32)
00602
00603 ACE_OS_GUARD
00604
00605
00606 LARGE_INTEGER orig_position;
00607 orig_position.QuadPart = 0;
00608 orig_position.LowPart = ::SetFilePointer (handle,
00609 0,
00610 &orig_position.HighPart,
00611 FILE_CURRENT);
00612 if (orig_position.LowPart == INVALID_SET_FILE_POINTER
00613 && GetLastError () != NO_ERROR)
00614 return -1;
00615
00616 DWORD bytes_written;
00617 LARGE_INTEGER loffset;
00618 loffset.QuadPart = offset;
00619
00620 # if defined (ACE_HAS_WIN32_OVERLAPPED_IO)
00621
00622 OVERLAPPED overlapped;
00623 overlapped.Internal = 0;
00624 overlapped.InternalHigh = 0;
00625 overlapped.Offset = loffset.LowPart;
00626 overlapped.OffsetHigh = loffset.HighPart;
00627 overlapped.hEvent = 0;
00628
00629 BOOL result = ::WriteFile (handle,
00630 buf,
00631 static_cast <DWORD> (nbytes),
00632 &bytes_written,
00633 &overlapped);
00634
00635 if (result == FALSE)
00636 {
00637 if (::GetLastError () != ERROR_IO_PENDING)
00638 return -1;
00639
00640 result = ::GetOverlappedResult (handle,
00641 &overlapped,
00642 &bytes_written,
00643 TRUE);
00644 if (result == FALSE)
00645 return -1;
00646 }
00647
00648 # else
00649
00650
00651
00652
00653
00654 DWORD newpos;
00655 # if defined (_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64
00656 newpos = ::SetFilePointer (handle,
00657 loffset.LowPart,
00658 &loffset.HighPart,
00659 FILE_BEGIN);
00660 # else
00661 newpos = ::SetFilePointer (handle,
00662 loffset.LowPart,
00663 0,
00664 FILE_BEGIN);
00665 # endif
00666 if (newpos == 0xFFFFFFFF && ::GetLastError () != NO_ERROR)
00667 {
00668 ACE_OS::set_errno_to_last_error ();
00669 return -1;
00670 }
00671
00672 BOOL result = ::WriteFile (handle,
00673 buf,
00674 nbytes,
00675 &bytes_written,
00676 0);
00677 if (result == FALSE)
00678 return -1;
00679
00680 # endif
00681
00682
00683 if (::SetFilePointer (handle,
00684 orig_position.LowPart,
00685 &orig_position.HighPart,
00686 FILE_BEGIN) == INVALID_SET_FILE_POINTER
00687 && GetLastError () != NO_ERROR)
00688 return -1;
00689
00690 return (ssize_t) bytes_written;
00691
00692 # else
00693
00694 return ::pwrite (handle, buf, nbytes, offset);
00695 # endif
00696 # else
00697
00698 ACE_OS_GUARD
00699
00700
00701 ACE_OFF_T original_position = ACE_OS::lseek (handle,
00702 0,
00703 SEEK_CUR);
00704 if (original_position == -1)
00705 return -1;
00706
00707
00708 ACE_OFF_T altered_position = ACE_OS::lseek (handle,
00709 offset,
00710 SEEK_SET);
00711 if (altered_position == -1)
00712 return -1;
00713
00714 ssize_t const bytes_written = ACE_OS::write (handle,
00715 buf,
00716 nbytes);
00717 if (bytes_written == -1)
00718 return -1;
00719
00720 if (ACE_OS::lseek (handle,
00721 original_position,
00722 SEEK_SET) == -1)
00723 return -1;
00724
00725 return bytes_written;
00726 # endif
00727 }
00728
00729 int
00730 ACE_OS::string_to_argv (ACE_TCHAR *buf,
00731 int &argc,
00732 ACE_TCHAR **&argv,
00733 bool substitute_env_args)
00734 {
00735
00736 argc = 0;
00737
00738 if (buf == 0)
00739 return -1;
00740
00741 ACE_TCHAR *cp = buf;
00742
00743
00744
00745
00746 while (*cp != ACE_TEXT ('\0') && *cp != ACE_TEXT ('#'))
00747 {
00748
00749 while (ACE_OS::ace_isspace (*cp))
00750 ++cp;
00751
00752
00753 if (*cp != ACE_TEXT ('\0'))
00754 ++argc;
00755
00756 while (*cp != ACE_TEXT ('\0') && !ACE_OS::ace_isspace (*cp))
00757 {
00758
00759 if (*cp == ACE_TEXT ('\'') || *cp == ACE_TEXT ('"'))
00760 {
00761 ACE_TCHAR quote = *cp;
00762
00763
00764 for (++cp; *cp != ACE_TEXT ('\0')
00765 && (*cp != quote || cp[-1] == ACE_TEXT ('\\')); ++cp)
00766 continue;
00767
00768
00769 if (*cp == ACE_TEXT ('\0'))
00770 {
00771 --argc;
00772 break;
00773 }
00774 else
00775 ++cp;
00776 }
00777 else
00778 ++cp;
00779 }
00780 }
00781
00782
00783 ACE_TCHAR arg[ACE_DEFAULT_ARGV_BUFSIZ];
00784 ACE_TCHAR *argp = arg;
00785
00786
00787
00788 if (cp - buf >= ACE_DEFAULT_ARGV_BUFSIZ)
00789 ACE_NEW_RETURN (argp,
00790 ACE_TCHAR[cp - buf + 1],
00791 -1);
00792
00793
00794 ACE_NEW_RETURN (argv,
00795 ACE_TCHAR *[argc + 1],
00796 -1);
00797
00798 ACE_TCHAR *ptr = buf;
00799
00800 for (int i = 0; i < argc; ++i)
00801 {
00802
00803 while (ACE_OS::ace_isspace (*ptr))
00804 ++ptr;
00805
00806
00807 cp = argp;
00808 while (*ptr != ACE_TEXT ('\0') && !ACE_OS::ace_isspace (*ptr))
00809 if (*ptr == ACE_TEXT ('\'') || *ptr == ACE_TEXT ('"'))
00810 {
00811 ACE_TCHAR quote = *ptr++;
00812
00813 while (*ptr != ACE_TEXT ('\0')
00814 && (*ptr != quote || ptr[-1] == ACE_TEXT ('\\')))
00815 {
00816 if (*ptr == quote && ptr[-1] == ACE_TEXT ('\\')) --cp;
00817 *cp++ = *ptr++;
00818 }
00819
00820 if (*ptr == quote)
00821 ++ptr;
00822 }
00823 else
00824 *cp++ = *ptr++;
00825
00826 *cp = ACE_TEXT ('\0');
00827
00828 #if !defined (ACE_LACKS_ENV)
00829
00830 if (substitute_env_args) {
00831 argv[i] = ACE_OS::strenvdup (argp);
00832
00833 if (argv[i] == 0)
00834 {
00835 if (argp != arg)
00836 delete [] argp;
00837 errno = ENOMEM;
00838 return -1;
00839 }
00840 }
00841 else
00842 #endif
00843 {
00844 argv[i] = ACE_OS::strdup (argp);
00845
00846 if (argv[i] == 0)
00847 {
00848 if (argp != arg)
00849 delete [] argp;
00850 errno = ENOMEM;
00851 return -1;
00852 }
00853 }
00854 }
00855
00856 if (argp != arg)
00857 delete [] argp;
00858
00859 argv[argc] = 0;
00860 return 0;
00861 }
00862
00863
00864
00865
00866 ssize_t
00867 ACE_OS::write_n (ACE_HANDLE handle,
00868 const void *buf,
00869 size_t len,
00870 size_t *bt)
00871 {
00872 size_t temp;
00873 size_t &bytes_transferred = bt == 0 ? temp : *bt;
00874 ssize_t n;
00875
00876 for (bytes_transferred = 0;
00877 bytes_transferred < len;
00878 bytes_transferred += n)
00879 {
00880 n = ACE_OS::write (handle,
00881 (char *) buf + bytes_transferred,
00882 len - bytes_transferred);
00883
00884 if (n == -1 || n == 0)
00885 return n;
00886 }
00887
00888 return bytes_transferred;
00889 }
00890
00891 ACE_END_VERSIONED_NAMESPACE_DECL