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