OS_NS_unistd.cpp

Go to the documentation of this file.
00001 // OS_NS_unistd.cpp,v 1.18 2006/06/19 11:35:26 jwillemsen Exp
00002 
00003 #include "ace/OS_NS_unistd.h"
00004 
00005 ACE_RCSID(ace, OS_NS_unistd, "OS_NS_unistd.cpp,v 1.18 2006/06/19 11:35:26 jwillemsen Exp")
00006 
00007 #if !defined (ACE_HAS_INLINED_OSCALLS)
00008 # include "ace/OS_NS_unistd.inl"
00009 #endif /* ACE_HAS_INLINED_OS_CALLS */
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/os_include/sys/os_pstat.h"
00019 #include "ace/os_include/sys/os_sysctl.h"
00020 
00021 #if defined (ACE_NEEDS_FTRUNCATE)
00022 extern "C" int
00023 ftruncate (ACE_HANDLE handle, long len)
00024 {
00025   struct flock fl;
00026   fl.l_whence = 0;
00027   fl.l_len = 0;
00028   fl.l_start = len;
00029   fl.l_type = F_WRLCK;
00030 
00031   return ACE_OS::fcntl (handle, F_FREESP, reinterpret_cast <long> (&fl));
00032 }
00033 #endif /* ACE_NEEDS_FTRUNCATE */
00034 
00035 /*****************************************************************************/
00036 
00037 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00038 
00039 int
00040 ACE_OS::argv_to_string (ACE_TCHAR **argv,
00041                         ACE_TCHAR *&buf,
00042                         bool substitute_env_args)
00043 {
00044   if (argv == 0 || argv[0] == 0)
00045     return 0;
00046 
00047   size_t buf_len = 0;
00048 
00049   // Determine the length of the buffer.
00050 
00051   for (int i = 0; argv[i] != 0; i++)
00052     {
00053 #if !defined (ACE_LACKS_ENV)
00054       // Account for environment variables.
00055       if (substitute_env_args && argv[i][0] == ACE_LIB_TEXT ('$'))
00056         {
00057 #  if defined (ACE_WIN32) || !defined (ACE_HAS_WCHAR)
00058           ACE_TCHAR *temp = 0;
00059           // Win32 is the only platform with a wide-char ACE_OS::getenv().
00060           if ((temp = ACE_OS::getenv (&argv[i][1])) != 0)
00061             buf_len += ACE_OS::strlen (temp);
00062           else
00063             buf_len += ACE_OS::strlen (argv[i]);
00064 #  else
00065           // This is an ACE_HAS_WCHAR platform and not ACE_WIN32.
00066           // Convert the env variable name for getenv(), then add
00067           // the length of the returned char *string. Later, when we
00068           // actually use the returned env variable value, convert it
00069           // as well.
00070           char *ctemp = ACE_OS::getenv (ACE_TEXT_ALWAYS_CHAR (&argv[i][1]));
00071           if (ctemp == 0)
00072             buf_len += ACE_OS::strlen (argv[i]);
00073           else
00074             buf_len += ACE_OS::strlen (ctemp);
00075 #  endif /* ACE_WIN32 || !ACE_HAS_WCHAR */
00076         }
00077       else
00078 #endif /* ACE_LACKS_ENV */
00079         buf_len += ACE_OS::strlen (argv[i]);
00080 
00081       // Add one for the extra space between each string.
00082       buf_len++;
00083     }
00084 
00085   // Step through all argv params and copy each one into buf; separate
00086   // each param with white space.
00087 
00088   ACE_NEW_RETURN (buf,
00089                   ACE_TCHAR[buf_len + 1],
00090                   0);
00091 
00092   // Initial null charater to make it a null string.
00093   buf[0] = '\0';
00094   ACE_TCHAR *end = buf;
00095   int j;
00096 
00097   for (j = 0; argv[j] != 0; j++)
00098     {
00099 
00100 #if !defined (ACE_LACKS_ENV)
00101       // Account for environment variables.
00102       if (substitute_env_args && argv[j][0] == ACE_LIB_TEXT ('$'))
00103         {
00104 #  if defined (ACE_WIN32) || !defined (ACE_HAS_WCHAR)
00105           // Win32 is the only platform with a wide-char ACE_OS::getenv().
00106           ACE_TCHAR *temp = ACE_OS::getenv (&argv[j][1]);
00107           if (temp != 0)
00108             end = ACE_OS::strecpy (end, temp);
00109           else
00110             end = ACE_OS::strecpy (end, argv[j]);
00111 #  else
00112           // This is an ACE_HAS_WCHAR platform and not ACE_WIN32.
00113           // Convert the env variable name for getenv(), then convert
00114           // the returned char *string back to wchar_t.
00115           char *ctemp = ACE_OS::getenv (ACE_TEXT_ALWAYS_CHAR (&argv[j][1]));
00116           if (ctemp == 0)
00117             end = ACE_OS::strecpy (end, argv[j]);
00118           else
00119             end = ACE_OS::strecpy (end, ACE_TEXT_CHAR_TO_TCHAR (ctemp));
00120 #  endif /* ACE_WIN32 || !ACE_HAS_WCHAR */
00121         }
00122       else
00123 #endif /* ACE_LACKS_ENV */
00124         end = ACE_OS::strecpy (end, argv[j]);
00125 
00126       // Replace the null char that strecpy put there with white
00127       // space.
00128       end[-1] = ' ';
00129     }
00130 
00131   // Null terminate the string.
00132   *end = '\0';
00133   // The number of arguments.
00134   return j;
00135 }
00136 
00137 int
00138 ACE_OS::execl (const char * /* path */, const char * /* arg0 */, ...)
00139 {
00140   ACE_OS_TRACE ("ACE_OS::execl");
00141   ACE_NOTSUP_RETURN (-1);
00142   // Need to write this code.
00143   // ACE_OSCALL_RETURN (::execv (path, argv), int, -1);
00144 }
00145 
00146 int
00147 ACE_OS::execle (const char * /* path */, const char * /* arg0 */, ...)
00148 {
00149   ACE_OS_TRACE ("ACE_OS::execle");
00150   ACE_NOTSUP_RETURN (-1);
00151   // Need to write this code.
00152   //  ACE_OSCALL_RETURN (::execve (path, argv, envp), int, -1);
00153 }
00154 
00155 int
00156 ACE_OS::execlp (const char * /* file */, const char * /* arg0 */, ...)
00157 {
00158   ACE_OS_TRACE ("ACE_OS::execlp");
00159   ACE_NOTSUP_RETURN (-1);
00160   // Need to write this code.
00161   //  ACE_OSCALL_RETURN (::execvp (file, argv), int, -1);
00162 }
00163 
00164 pid_t
00165 ACE_OS::fork (const ACE_TCHAR *program_name)
00166 {
00167   ACE_OS_TRACE ("ACE_OS::fork");
00168 # if defined (ACE_LACKS_FORK)
00169   ACE_UNUSED_ARG (program_name);
00170   ACE_NOTSUP_RETURN (pid_t (-1));
00171 # else
00172   pid_t pid =
00173 # if defined (ACE_HAS_STHREADS)
00174     ::fork1 ();
00175 #else
00176     ::fork ();
00177 #endif /* ACE_HAS_STHREADS */
00178 
00179 #if !defined (ACE_HAS_MINIMAL_ACE_OS)
00180   if (pid == 0)
00181     ACE_Base_Thread_Adapter::sync_log_msg (program_name);
00182 #endif /* ! ACE_HAS_MINIMAL_ACE_OS */
00183 
00184   return pid;
00185 # endif /* ACE_WIN32 */
00186 }
00187 
00188 // Create a contiguous command-line argument buffer with each arg
00189 // separated by spaces.
00190 
00191 pid_t
00192 ACE_OS::fork_exec (ACE_TCHAR *argv[])
00193 {
00194 # if defined (ACE_WIN32)
00195   ACE_TCHAR *buf;
00196 
00197   if (ACE_OS::argv_to_string (argv, buf) != -1)
00198     {
00199       PROCESS_INFORMATION process_info;
00200 #   if !defined (ACE_HAS_WINCE)
00201       ACE_TEXT_STARTUPINFO startup_info;
00202       ACE_OS::memset ((void *) &startup_info,
00203                       0,
00204                       sizeof startup_info);
00205       startup_info.cb = sizeof startup_info;
00206 
00207       if (ACE_TEXT_CreateProcess (0,
00208                                   buf,
00209                                   0, // No process attributes.
00210                                   0,  // No thread attributes.
00211                                   TRUE, // Allow handle inheritance.
00212                                   0, // Don't create a new console window.
00213                                   0, // No environment.
00214                                   0, // No current directory.
00215                                   &startup_info,
00216                                   &process_info))
00217 #   else
00218       if (ACE_TEXT_CreateProcess (0,
00219                                   buf,
00220                                   0, // No process attributes.
00221                                   0,  // No thread attributes.
00222                                   FALSE, // Can's inherit handles on CE
00223                                   0, // Don't create a new console window.
00224                                   0, // No environment.
00225                                   0, // No current directory.
00226                                   0, // Can't use startup info on CE
00227                                   &process_info))
00228 #   endif /* ! ACE_HAS_WINCE */
00229         {
00230           // Free resources allocated in kernel.
00231           ACE_OS::close (process_info.hThread);
00232           ACE_OS::close (process_info.hProcess);
00233           // Return new process id.
00234           delete [] buf;
00235           return process_info.dwProcessId;
00236         }
00237     }
00238 
00239   // CreateProcess failed.
00240   return -1;
00241 # else
00242       pid_t result = ACE_OS::fork ();
00243 
00244 #   if defined (ACE_USES_WCHAR)
00245       // Wide-char builds need to convert the command-line args to
00246       // narrow char strings for execv().
00247       char **cargv;
00248       int arg_count;
00249 #   endif /* ACE_HAS_WCHAR */
00250 
00251       switch (result)
00252         {
00253         case -1:
00254           // Error.
00255           return -1;
00256         case 0:
00257           // Child process.
00258 #   if defined (ACE_USES_WCHAR)
00259           for (arg_count = 0; argv[arg_count] != 0; ++arg_count)
00260             ;
00261           ++arg_count;    // Need a 0-pointer end-of-array marker
00262           ACE_NEW_NORETURN (cargv, char*[arg_count]);
00263           if (cargv == 0)
00264             ACE_OS::exit (errno);
00265           --arg_count;    // Back to 0-indexed
00266           cargv[arg_count] = 0;
00267           while (--arg_count >= 0)
00268             cargv[arg_count] = ACE_Wide_To_Ascii::convert (argv[arg_count]);
00269           // Don't worry about freeing the cargv or the strings it points to.
00270           // Either the process will be replaced, or we'll exit.
00271           if (ACE_OS::execv (cargv[0], cargv) == -1)
00272             ACE_OS::exit (errno);
00273 #   else
00274           if (ACE_OS::execv (argv[0], argv) == -1)
00275             {
00276               // The OS layer should not print stuff out
00277               // ACE_ERROR ((LM_ERROR,
00278               //             "%p Exec failed\n"));
00279 
00280               // If the execv fails, this child needs to exit.
00281               ACE_OS::exit (errno);
00282             }
00283 #   endif /* ACE_HAS_WCHAR */
00284 
00285         default:
00286           // Server process.  The fork succeeded.
00287           return result;
00288         }
00289 # endif /* ACE_WIN32 */
00290 }
00291 
00292 long
00293 ACE_OS::num_processors (void)
00294 {
00295   ACE_OS_TRACE ("ACE_OS::num_processors");
00296 
00297 #if defined (ACE_HAS_PHARLAP)
00298   return 1;
00299 #elif defined (ACE_WIN32)
00300   SYSTEM_INFO sys_info;
00301   ::GetSystemInfo (&sys_info);
00302   return sys_info.dwNumberOfProcessors;
00303 #elif defined (_SC_NPROCESSORS_CONF)
00304   return ::sysconf (_SC_NPROCESSORS_CONF);
00305 #elif defined (ACE_HAS_SYSCTL)
00306   int num_processors;
00307   int mib[2] = { CTL_HW, HW_NCPU };
00308   size_t len = sizeof (num_processors);
00309 
00310   sysctl(mib, 2, &num_processors, &len, NULL, 0);
00311   return num_processors;
00312 #else
00313   ACE_NOTSUP_RETURN (-1);
00314 #endif
00315 }
00316 
00317 long
00318 ACE_OS::num_processors_online (void)
00319 {
00320   ACE_OS_TRACE ("ACE_OS::num_processors_online");
00321 
00322 #if defined (ACE_HAS_PHARLAP)
00323   return 1;
00324 #elif defined (ACE_WIN32)
00325   SYSTEM_INFO sys_info;
00326   ::GetSystemInfo (&sys_info);
00327   return sys_info.dwNumberOfProcessors;
00328 #elif defined (_SC_NPROCESSORS_ONLN)
00329   return ::sysconf (_SC_NPROCESSORS_ONLN);
00330 #elif defined (ACE_HAS_SYSCTL)
00331   int num_processors;
00332   int mib[2] = { CTL_HW, HW_NCPU };
00333   size_t len = sizeof (num_processors);
00334 
00335   sysctl(mib, 2, &num_processors, &len, NULL, 0);
00336   return num_processors;
00337 #elif defined (__hpux)
00338   struct pst_dynamic psd;
00339   if (::pstat_getdynamic (&psd, sizeof (psd), (size_t) 1, 0) != -1)
00340     return psd.psd_proc_cnt;
00341   else
00342     return -1;
00343 #else
00344   ACE_NOTSUP_RETURN (-1);
00345 #endif
00346 }
00347 
00348 ssize_t
00349 ACE_OS::read_n (ACE_HANDLE handle,
00350                 void *buf,
00351                 size_t len,
00352                 size_t *bt)
00353 {
00354   size_t temp;
00355   size_t &bytes_transferred = bt == 0 ? temp : *bt;
00356   ssize_t n;
00357 
00358   for (bytes_transferred = 0;
00359        bytes_transferred < len;
00360        bytes_transferred += n)
00361     {
00362       n = ACE_OS::read (handle,
00363                         (char *) buf + bytes_transferred,
00364                         len - bytes_transferred);
00365 
00366       if (n == -1 || n == 0)
00367         return n;
00368     }
00369 
00370   return bytes_transferred;
00371 }
00372 
00373 ssize_t
00374 ACE_OS::pread (ACE_HANDLE handle,
00375                void *buf,
00376                size_t nbytes,
00377                off_t offset)
00378 {
00379 # if defined (ACE_HAS_P_READ_WRITE)
00380 #   if defined (ACE_WIN32)
00381 
00382   ACE_OS_GUARD
00383 
00384   // Remember the original file pointer position
00385   DWORD original_position = ::SetFilePointer (handle,
00386                                               0,
00387                                               0,
00388                                               FILE_CURRENT);
00389 
00390   if (original_position == 0xFFFFFFFF)
00391     return -1;
00392 
00393   // Go to the correct position
00394   DWORD altered_position = ::SetFilePointer (handle,
00395                                              offset,
00396                                              0,
00397                                              FILE_BEGIN);
00398   if (altered_position == 0xFFFFFFFF)
00399     return -1;
00400 
00401   DWORD bytes_read;
00402 
00403 #     if defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)
00404 
00405   OVERLAPPED overlapped;
00406   overlapped.Internal = 0;
00407   overlapped.InternalHigh = 0;
00408   overlapped.Offset = offset;
00409   overlapped.OffsetHigh = 0;
00410   overlapped.hEvent = 0;
00411 
00412   BOOL result = ::ReadFile (handle,
00413                             buf,
00414                             static_cast <DWORD> (nbytes),
00415                             &bytes_read,
00416                             &overlapped);
00417 
00418   if (result == FALSE)
00419     {
00420       if (::GetLastError () != ERROR_IO_PENDING)
00421         return -1;
00422 
00423       else
00424         {
00425           result = ::GetOverlappedResult (handle,
00426                                           &overlapped,
00427                                           &bytes_read,
00428                                           TRUE);
00429           if (result == FALSE)
00430             return -1;
00431         }
00432     }
00433 
00434 #     else /* ACE_HAS_WINNT4 && (ACE_HAS_WINNT4 != 0) */
00435 
00436   BOOL result = ::ReadFile (handle,
00437                             buf,
00438                             nbytes,
00439                             &bytes_read,
00440                             0);
00441   if (result == FALSE)
00442     return -1;
00443 
00444 #     endif /* ACE_HAS_WINNT4 && (ACE_HAS_WINNT4 != 0) */
00445 
00446   // Reset the original file pointer position
00447   if (::SetFilePointer (handle,
00448                         original_position,
00449                         0,
00450                         FILE_BEGIN) == 0xFFFFFFFF)
00451     return -1;
00452 
00453   return (ssize_t) bytes_read;
00454 
00455 #   else /* ACE_WIN32 */
00456 
00457   return ::pread (handle, buf, nbytes, offset);
00458 
00459 #   endif /* ACE_WIN32 */
00460 
00461 # else /* ACE_HAS_P_READ_WRITE */
00462 
00463   ACE_OS_GUARD
00464 
00465   // Remember the original file pointer position
00466   off_t original_position = ACE_OS::lseek (handle,
00467                                            0,
00468                                            SEEK_CUR);
00469 
00470   if (original_position == -1)
00471     return -1;
00472 
00473   // Go to the correct position
00474   off_t altered_position = ACE_OS::lseek (handle,
00475                                           offset,
00476                                           SEEK_SET);
00477 
00478   if (altered_position == -1)
00479     return -1;
00480 
00481   ssize_t bytes_read = ACE_OS::read (handle,
00482                                      buf,
00483                                      nbytes);
00484 
00485   if (bytes_read == -1)
00486     return -1;
00487 
00488   if (ACE_OS::lseek (handle,
00489                      original_position,
00490                      SEEK_SET) == -1)
00491     return -1;
00492 
00493   return bytes_read;
00494 
00495 # endif /* ACE_HAD_P_READ_WRITE */
00496 }
00497 
00498 ssize_t
00499 ACE_OS::pwrite (ACE_HANDLE handle,
00500                 const void *buf,
00501                 size_t nbytes,
00502                 ACE_LOFF_T offset)
00503 {
00504 # if defined (ACE_HAS_P_READ_WRITE)
00505 #   if defined (ACE_WIN32)
00506 
00507   ACE_OS_GUARD
00508 
00509   // Remember the original file pointer position
00510   DWORD original_position = ::SetFilePointer (handle,
00511                                               0,
00512                                               0,
00513                                               FILE_CURRENT);
00514 
00515   if (original_position == 0xFFFFFFFF)
00516     return -1;
00517 
00518   // Go to the correct position
00519   LARGE_INTEGER loffset;
00520   loffset.QuadPart = offset;
00521   DWORD altered_position = ::SetFilePointerEx (handle,
00522                                                loffset,
00523                                                0,
00524                                                FILE_BEGIN);
00525   if (altered_position == 0xFFFFFFFF)
00526     return -1;
00527 
00528   DWORD bytes_written;
00529 
00530 #     if defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)
00531 
00532   OVERLAPPED overlapped;
00533   overlapped.Internal = 0;
00534   overlapped.InternalHigh = 0;
00535   overlapped.Offset = offset;
00536   overlapped.OffsetHigh = 0;
00537   overlapped.hEvent = 0;
00538 
00539   BOOL result = ::WriteFile (handle,
00540                              buf,
00541                              static_cast <DWORD> (nbytes),
00542                              &bytes_written,
00543                              &overlapped);
00544 
00545   if (result == FALSE)
00546     {
00547       if (::GetLastError () != ERROR_IO_PENDING)
00548         return -1;
00549 
00550       else
00551         {
00552           result = ::GetOverlappedResult (handle,
00553                                           &overlapped,
00554                                           &bytes_written,
00555                                           TRUE);
00556           if (result == FALSE)
00557             return -1;
00558         }
00559     }
00560 
00561 #     else /* ACE_HAS_WINNT4 && (ACE_HAS_WINNT4 != 0) */
00562 
00563   BOOL result = ::WriteFile (handle,
00564                              buf,
00565                              nbytes,
00566                              &bytes_written,
00567                              0);
00568   if (result == FALSE)
00569     return -1;
00570 
00571 #     endif /* ACE_HAS_WINNT4 && (ACE_HAS_WINNT4 != 0) */
00572 
00573   // Reset the original file pointer position
00574   if (::SetFilePointer (handle,
00575                         original_position,
00576                         0,
00577                         FILE_BEGIN) == 0xFFFFFFFF)
00578     return -1;
00579 
00580   return (ssize_t) bytes_written;
00581 
00582 #   else /* ACE_WIN32 */
00583 
00584   return ::pwrite (handle, buf, nbytes, offset);
00585 #   endif /* ACE_WIN32 */
00586 # else /* ACE_HAS_P_READ_WRITE */
00587 
00588   ACE_OS_GUARD
00589 
00590   // Remember the original file pointer position
00591   off_t original_position = ACE_OS::lseek (handle,
00592                                            0,
00593                                            SEEK_CUR);
00594   if (original_position == -1)
00595     return -1;
00596 
00597   // Go to the correct position
00598   off_t altered_position = ACE_OS::lseek (handle,
00599                                           offset,
00600                                           SEEK_SET);
00601   if (altered_position == -1)
00602     return -1;
00603 
00604   ssize_t bytes_written = ACE_OS::write (handle,
00605                                          buf,
00606                                          nbytes);
00607   if (bytes_written == -1)
00608     return -1;
00609 
00610   if (ACE_OS::lseek (handle,
00611                      original_position,
00612                      SEEK_SET) == -1)
00613     return -1;
00614 
00615   return bytes_written;
00616 # endif /* ACE_HAD_P_READ_WRITE */
00617 }
00618 
00619 int
00620 ACE_OS::string_to_argv (ACE_TCHAR *buf,
00621                         int &argc,
00622                         ACE_TCHAR **&argv,
00623                         bool substitute_env_args)
00624 {
00625   // Reset the number of arguments
00626   argc = 0;
00627 
00628   if (buf == 0)
00629     return -1;
00630 
00631   ACE_TCHAR *cp = buf;
00632 
00633   // First pass: count arguments.
00634 
00635   // '#' is the start-comment token..
00636   while (*cp != ACE_LIB_TEXT ('\0') && *cp != ACE_LIB_TEXT ('#'))
00637     {
00638       // Skip whitespace..
00639       while (ACE_OS::ace_isspace (*cp))
00640         cp++;
00641 
00642       // Increment count and move to next whitespace..
00643       if (*cp != ACE_LIB_TEXT ('\0'))
00644         argc++;
00645 
00646       while (*cp != ACE_LIB_TEXT ('\0') && !ACE_OS::ace_isspace (*cp))
00647         {
00648           // Grok quotes....
00649           if (*cp == ACE_LIB_TEXT ('\'') || *cp == ACE_LIB_TEXT ('"'))
00650             {
00651               ACE_TCHAR quote = *cp;
00652 
00653               // Scan past the string..
00654               for (cp++; *cp != ACE_LIB_TEXT ('\0') && *cp != quote; cp++)
00655                 continue;
00656 
00657               // '\0' implies unmatched quote..
00658               if (*cp == ACE_LIB_TEXT ('\0'))
00659                 {
00660                   argc--;
00661                   break;
00662                 }
00663               else
00664                 cp++;
00665             }
00666           else
00667             cp++;
00668         }
00669     }
00670 
00671   // Second pass: copy arguments.
00672   ACE_TCHAR arg[ACE_DEFAULT_ARGV_BUFSIZ];
00673   ACE_TCHAR *argp = arg;
00674 
00675   // Make sure that the buffer we're copying into is always large
00676   // enough.
00677   if (cp - buf >= ACE_DEFAULT_ARGV_BUFSIZ)
00678     ACE_NEW_RETURN (argp,
00679                     ACE_TCHAR[cp - buf + 1],
00680                     -1);
00681 
00682   // Make a new argv vector of argc + 1 elements.
00683   ACE_NEW_RETURN (argv,
00684                   ACE_TCHAR *[argc + 1],
00685                   -1);
00686 
00687   ACE_TCHAR *ptr = buf;
00688 
00689   for (int i = 0; i < argc; i++)
00690     {
00691       // Skip whitespace..
00692       while (ACE_OS::ace_isspace (*ptr))
00693         ptr++;
00694 
00695       // Copy next argument and move to next whitespace..
00696       cp = argp;
00697       while (*ptr != ACE_LIB_TEXT ('\0') && !ACE_OS::ace_isspace (*ptr))
00698         if (*ptr == ACE_LIB_TEXT ('\'') || *ptr == ACE_LIB_TEXT ('"'))
00699           {
00700             ACE_TCHAR quote = *ptr++;
00701 
00702             while (*ptr != ACE_LIB_TEXT ('\0') && *ptr != quote)
00703               *cp++ = *ptr++;
00704 
00705             if (*ptr == quote)
00706               ptr++;
00707           }
00708         else
00709           *cp++ = *ptr++;
00710 
00711       *cp = ACE_LIB_TEXT ('\0');
00712 
00713 #if !defined (ACE_LACKS_ENV)
00714       // Check for environment variable substitution here.
00715       if (substitute_env_args) {
00716           argv[i] = ACE_OS::strenvdup(argp);
00717 
00718           if (argv[i] == 0)
00719             {
00720               if (argp != arg)
00721                 delete [] argp;
00722               errno = ENOMEM;
00723               return -1;
00724             }
00725       }
00726       else
00727 #endif /* ACE_LACKS_ENV */
00728         {
00729           argv[i] = ACE_OS::strdup(argp);
00730 
00731           if (argv[i] == 0)
00732             {
00733               if (argp != arg)
00734                 delete [] argp;
00735               errno = ENOMEM;
00736               return -1;
00737             }
00738         }
00739     }
00740 
00741   if (argp != arg)
00742     delete [] argp;
00743 
00744   argv[argc] = 0;
00745   return 0;
00746 }
00747 
00748 // Write <len> bytes from <buf> to <handle> (uses the <write>
00749 // system call on UNIX and the <WriteFile> call on Win32).
00750 
00751 ssize_t
00752 ACE_OS::write_n (ACE_HANDLE handle,
00753                  const void *buf,
00754                  size_t len,
00755                  size_t *bt)
00756 {
00757   size_t temp;
00758   size_t &bytes_transferred = bt == 0 ? temp : *bt;
00759   ssize_t n;
00760 
00761   for (bytes_transferred = 0;
00762        bytes_transferred < len;
00763        bytes_transferred += n)
00764     {
00765       n = ACE_OS::write (handle,
00766                          (char *) buf + bytes_transferred,
00767                          len - bytes_transferred);
00768 
00769       if (n == -1 || n == 0)
00770         return n;
00771     }
00772 
00773   return bytes_transferred;
00774 }
00775 
00776 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 09:41:58 2006 for ACE by doxygen 1.3.6