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