diff options
author | maximius <none@none> | 2009-10-17 15:51:44 -0700 |
---|---|---|
committer | maximius <none@none> | 2009-10-17 15:51:44 -0700 |
commit | e585187b248f48b3c6e9247b49fa07c6565d65e5 (patch) | |
tree | 637c5b7ddacf41040bef4ea4f75a97da64c6a9bc /dep/ACE_wrappers/ace/Process.cpp | |
parent | 26b5e033ffde3d161382fc9addbfa99738379641 (diff) |
*Backed out changeset 3be01fb200a5
--HG--
branch : trunk
Diffstat (limited to 'dep/ACE_wrappers/ace/Process.cpp')
-rw-r--r-- | dep/ACE_wrappers/ace/Process.cpp | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/dep/ACE_wrappers/ace/Process.cpp b/dep/ACE_wrappers/ace/Process.cpp index a8e29b02b69..a39a02beb52 100644 --- a/dep/ACE_wrappers/ace/Process.cpp +++ b/dep/ACE_wrappers/ace/Process.cpp @@ -1,8 +1,11 @@ // $Id: Process.cpp 82499 2008-08-04 20:01:17Z shuston $ + #include "ace/Process.h" + #if !defined (__ACE_INLINE__) #include "ace/Process.inl" #endif /* __ACE_INLINE__ */ + #include "ace/ARGV.h" #include "ace/Auto_Ptr.h" #include "ace/Signal.h" @@ -18,11 +21,14 @@ #include "ace/Countdown_Time.h" #include "ace/Truncate.h" #include "ace/Vector_T.h" + #if defined (ACE_VXWORKS) && (ACE_VXWORKS > 0x600) && defined (__RTP__) # include <rtpLib.h> # include <taskLib.h> #endif + ACE_RCSID (ace, Process, "$Id: Process.cpp 82499 2008-08-04 20:01:17Z shuston $") + // This function acts as a signal handler for SIGCHLD. We don't really want // to do anything with the signal - it's just needed to interrupt a sleep. // See wait() for more info. @@ -34,7 +40,9 @@ sigchld_nop (int, siginfo_t *, ucontext_t *) } #endif /* ACE_WIN32 */ + ACE_BEGIN_VERSIONED_NAMESPACE_DECL + ACE_Process::ACE_Process (void) : #if !defined (ACE_WIN32) @@ -48,6 +56,7 @@ ACE_Process::ACE_Process (void) sizeof this->process_info_); #endif /* ACE_WIN32 */ } + ACE_Process::~ACE_Process (void) { #if defined (ACE_WIN32) @@ -59,16 +68,19 @@ ACE_Process::~ACE_Process (void) // still not closed, get them now. this->close_dup_handles (); } + int ACE_Process::prepare (ACE_Process_Options &) { return 0; } + pid_t ACE_Process::spawn (ACE_Process_Options &options) { if (this->prepare (options) < 0) return ACE_INVALID_PID; + // Stash the passed/duped handle sets away in this object for later // closing if needed or requested. At the same time, figure out which // ones to include in command line options if that's needed below. @@ -77,6 +89,7 @@ ACE_Process::spawn (ACE_Process_Options &options) set_p = &this->dup_handles_; else if (options.passed_handles (this->handles_passed_)) set_p = &this->handles_passed_; + // If we are going to end up running a new program (i.e. Win32, or // NO_EXEC option is set) then get any handles passed in the options, // and tack them onto the command line with +H <handle> options, @@ -118,11 +131,13 @@ ACE_Process::spawn (ACE_Process_Options &options) #endif /* ACE_WIN32 */ } } + #if defined (ACE_HAS_WINCE) // Note that WinCE does not have process name included in the command line as argv[0] // like other OS environment. Therefore, it is user's whole responsibility to call // 'ACE_Process_Options::process_name(const ACE_TCHAR *name)' to set the proper // process name (the execution file name with path if needed). + BOOL fork_result = ACE_TEXT_CreateProcess (options.process_name(), options.command_line_buf(), @@ -134,12 +149,14 @@ ACE_Process::spawn (ACE_Process_Options &options) options.working_directory(), // must be NULL in CE options.startup_info(), // must be NULL in CE &this->process_info_); + if (fork_result) { parent (this->getpid ()); return this->getpid (); } return ACE_INVALID_PID; + #elif defined (ACE_WIN32) void* env_buf = options.env_buf (); DWORD flags = options.creation_flags (); @@ -152,6 +169,7 @@ ACE_Process::spawn (ACE_Process_Options &options) flags |= CREATE_UNICODE_ENVIRONMENT; } # endif + BOOL fork_result = ACE_TEXT_CreateProcess (0, options.command_line_buf (), @@ -163,20 +181,24 @@ ACE_Process::spawn (ACE_Process_Options &options) options.working_directory (), options.startup_info (), &this->process_info_); + # if defined (ACE_HAS_WCHAR) && !defined (ACE_USES_WCHAR) if (options.use_unicode_environment ()) delete wenv_buf; # endif + if (fork_result) { parent (this->getpid ()); return this->getpid (); } return ACE_INVALID_PID; + #elif defined(ACE_OPENVMS) if (ACE_BIT_ENABLED (options.creation_flags (), ACE_Process_Options::NO_EXEC)) ACE_NOTSUP_RETURN (ACE_INVALID_PID); + int saved_stdin = ACE_STDIN; int saved_stdout = ACE_STDOUT; int saved_stderr = ACE_STDERR; @@ -199,8 +221,10 @@ ACE_Process::spawn (ACE_Process_Options &options) if (ACE_OS::dup2 (options.get_stderr (), ACE_STDERR) == -1) ACE_OS::exit (errno); } + if (options.working_directory () != 0) ACE_NOTSUP_RETURN (ACE_INVALID_PID); + this->child_id_ = vfork(); if (this->child_id_ == 0) { ACE_OS::execvp (options.process_name (), @@ -208,6 +232,7 @@ ACE_Process::spawn (ACE_Process_Options &options) // something went wrong this->child_id_ = ACE_INVALID_PID; } + // restore STD file descriptors (if necessary) if (options.get_stdin () != ACE_INVALID_HANDLE) { if (saved_stdin == -1) @@ -227,13 +252,16 @@ ACE_Process::spawn (ACE_Process_Options &options) else ACE_OS::dup2 (saved_stderr, ACE_STDERR); } + return this->child_id_; #elif (defined (ACE_VXWORKS) && (ACE_VXWORKS > 0x600)) && defined (__RTP__) if (ACE_BIT_ENABLED (options.creation_flags (), ACE_Process_Options::NO_EXEC)) ACE_NOTSUP_RETURN (ACE_INVALID_PID); + if (options.working_directory () != 0) ACE_NOTSUP_RETURN (ACE_INVALID_PID); + int saved_stdin = ACE_STDIN; int saved_stdout = ACE_STDOUT; int saved_stderr = ACE_STDERR; @@ -256,6 +284,7 @@ ACE_Process::spawn (ACE_Process_Options &options) if (ACE_OS::dup2 (options.get_stderr (), ACE_STDERR) == -1) ACE_OS::exit (errno); } + // Wide-char builds need narrow-char strings for commandline and // environment variables. # if defined (ACE_USES_WCHAR) @@ -267,6 +296,7 @@ ACE_Process::spawn (ACE_Process_Options &options) procargv[vcount] = 0; for (i = 0; i < vcount; ++i) procargv[i] = ACE_Wide_To_Ascii::convert (wargv[i]); + char **procenv = 0; if (options.inherit_environment ()) { @@ -282,6 +312,7 @@ ACE_Process::spawn (ACE_Process_Options &options) const char **procargv = const_cast<const char**> (options.command_line_argv ()); const char **procenv = const_cast<const char**> (options.env_argv ()); # endif /* ACE_USES_WCHAR */ + this->child_id_ = ::rtpSpawn (procargv[0], procargv, procenv, @@ -294,10 +325,12 @@ ACE_Process::spawn (ACE_Process_Options &options) // something went wrong this->child_id_ = ACE_INVALID_PID; } + # if defined (ACE_USES_WCHAR) if (procenv) delete procenv; # endif /* ACE_USES_WCHAR */ + // restore STD file descriptors (if necessary) if (options.get_stdin () != ACE_INVALID_HANDLE) { if (saved_stdin == -1) @@ -317,15 +350,18 @@ ACE_Process::spawn (ACE_Process_Options &options) else ACE_OS::dup2 (saved_stderr, ACE_STDERR); } + if (this->child_id_ == ACE_INVALID_PID) { errno = my_errno_; } + return this->child_id_; #else /* ACE_WIN32 */ // Fork the new process. this->child_id_ = ACE::fork (options.process_name (), options.avoid_zombies ()); + if (this->child_id_ == 0) { # if !defined (ACE_LACKS_SETPGID) @@ -347,6 +383,7 @@ ACE_Process::spawn (ACE_Process_Options &options) #endif } # endif /* ACE_LACKS_SETPGID */ + # if !defined (ACE_LACKS_SETREGID) if (options.getrgid () != (uid_t) -1 || options.getegid () != (uid_t) -1) @@ -363,6 +400,7 @@ ACE_Process::spawn (ACE_Process_Options &options) #endif } # endif /* ACE_LACKS_SETREGID */ + # if !defined (ACE_LACKS_SETREUID) // Set user and group id's. if (options.getruid () != (uid_t) -1 @@ -380,14 +418,17 @@ ACE_Process::spawn (ACE_Process_Options &options) #endif } # endif /* ACE_LACKS_SETREUID */ + this->child (ACE_OS::getppid ()); } else if (this->child_id_ != -1) this->parent (this->child_id_); + // If we're not supposed to exec, return the process id. if (ACE_BIT_ENABLED (options.creation_flags (), ACE_Process_Options::NO_EXEC)) return this->child_id_; + switch (this->child_id_) { case -1: @@ -408,17 +449,21 @@ ACE_Process::spawn (ACE_Process_Options &options) && ACE_OS::dup2 (options.get_stderr (), ACE_STDERR) == -1) ACE_OS::exit (errno); + // close down unneeded descriptors ACE_OS::close (options.get_stdin ()); ACE_OS::close (options.get_stdout ()); ACE_OS::close (options.get_stderr ()); + // If we must, set the working directory for the child // process. if (options.working_directory () != 0) ACE_OS::chdir (options.working_directory ()); // Should check for error here! + // Child process executes the command. int result = 0; + // Wide-char builds not on Windows need narrow-char strings for // exec() and environment variables. Don't need to worry about // releasing any of the converted string memory since this @@ -426,6 +471,7 @@ ACE_Process::spawn (ACE_Process_Options &options) # if defined (ACE_USES_WCHAR) ACE_Wide_To_Ascii n_procname (options.process_name ()); const char *procname = n_procname.char_rep (); + wchar_t * const *wargv = options.command_line_argv (); size_t vcount, i; for (vcount = 0; wargv[vcount] != 0; ++vcount) @@ -434,6 +480,7 @@ ACE_Process::spawn (ACE_Process_Options &options) procargv[vcount] = 0; for (i = 0; i < vcount; ++i) procargv[i] = ACE_Wide_To_Ascii::convert (wargv[i]); + wargv = options.env_argv (); for (vcount = 0; wargv[vcount] != 0; ++vcount) ; @@ -446,6 +493,7 @@ ACE_Process::spawn (ACE_Process_Options &options) char *const *procargv = options.command_line_argv (); char *const *procenv = options.env_argv (); # endif /* ACE_USES_WCHAR */ + if (options.inherit_environment ()) { // Add the new environment variables to the environment @@ -453,6 +501,7 @@ ACE_Process::spawn (ACE_Process_Options &options) for (size_t i = 0; procenv[i] != 0; i++) if (ACE_OS::putenv (procenv[i]) != 0) return ACE_INVALID_PID; + // Now the forked process has both inherited variables and // the user's supplied variables. result = ACE_OS::execvp (procname, procargv); @@ -470,6 +519,7 @@ ACE_Process::spawn (ACE_Process_Options &options) if (result == -1) { // If the execv fails, this child needs to exit. + // Exit with the errno so that the calling process can // catch this and figure out what went wrong. ACE_OS::_exit (errno); @@ -483,26 +533,31 @@ ACE_Process::spawn (ACE_Process_Options &options) } #endif /* ACE_WIN32 */ } + void ACE_Process::parent (pid_t) { // nothing to do } + void ACE_Process::child (pid_t) { // nothing to do } + void ACE_Process::unmanage (void) { // nothing to do } + int ACE_Process::running (void) const { #if defined (ACE_WIN32) DWORD code; + BOOL result = ::GetExitCodeProcess (this->gethandle (), &code); return result && code == STILL_ACTIVE; @@ -515,6 +570,7 @@ ACE_Process::running (void) const || errno != ESRCH; #endif /* ACE_WIN32 */ } + pid_t ACE_Process::wait (const ACE_Time_Value &tv, ACE_exitcode *status) @@ -549,8 +605,10 @@ ACE_Process::wait (const ACE_Time_Value &tv, WNOHANG); if (status != 0) *status = this->exit_code_; + return retv; } + if (tv == ACE_Time_Value::max_time) # if defined (ACE_VXWORKS) { @@ -561,6 +619,7 @@ ACE_Process::wait (const ACE_Time_Value &tv, # else return this->wait (status); # endif + pid_t pid = 0; ACE_Time_Value sleeptm (1); // 1 msec if (sleeptm > tv) // if sleeptime > waittime @@ -573,12 +632,15 @@ ACE_Process::wait (const ACE_Time_Value &tv, WNOHANG); if (status != 0) *status = this->exit_code_; + if (pid > 0 || pid == ACE_INVALID_PID) break; // Got a child or an error - all done + // pid 0, nothing is ready yet, so wait. // Do a (very) short sleep (only this thread sleeps). ACE_OS::sleep (sleeptm); } + return pid; #else /* !ACE_WIN32 && !ACE_LACKS_UNIX_SIGNALS */ if (tv == ACE_Time_Value::zero) @@ -589,10 +651,13 @@ ACE_Process::wait (const ACE_Time_Value &tv, WNOHANG); if (status != 0) *status = this->exit_code_; + return retv; } + if (tv == ACE_Time_Value::max_time) return this->wait (status); + // Need to wait but limited to specified time. // Force generation of SIGCHLD, even though we don't want to // catch it - just need it to interrupt the sleep below. @@ -602,6 +667,7 @@ ACE_Process::wait (const ACE_Time_Value &tv, ACE_Sig_Action old_action; ACE_Sig_Action do_sigchld ((ACE_SignalHandler)sigchld_nop); do_sigchld.register_action (SIGCHLD, &old_action); + pid_t pid; ACE_Time_Value tmo (tv); // Need one we can change for (ACE_Countdown_Time time_left (&tmo); ; time_left.update ()) @@ -611,8 +677,10 @@ ACE_Process::wait (const ACE_Time_Value &tv, WNOHANG); if (status != 0) *status = this->exit_code_; + if (pid > 0 || pid == ACE_INVALID_PID) break; // Got a child or an error - all done + // pid 0, nothing is ready yet, so wait. // Do a sleep (only this thread sleeps) til something // happens. This relies on SIGCHLD interrupting the sleep. @@ -624,11 +692,14 @@ ACE_Process::wait (const ACE_Time_Value &tv, pid = 0; break; } + // Restore the previous SIGCHLD action if it was changed. old_action.register_action (SIGCHLD); + return pid; #endif /* ACE_WIN32 */ } + void ACE_Process::close_dup_handles (void) { @@ -643,6 +714,7 @@ ACE_Process::close_dup_handles (void) } return; } + void ACE_Process::close_passed_handles (void) { @@ -657,6 +729,7 @@ ACE_Process::close_passed_handles (void) } return; } + #if defined (ACE_WIN32) && \ defined (ACE_HAS_WCHAR) && !defined (ACE_USES_WCHAR) && \ !defined (ACE_HAS_WINCE) @@ -665,6 +738,7 @@ ACE_Process::convert_env_buffer (const char* env) const { // Total starts out at 1 due to the final block nul terminator size_t total = 1; + // Convert each individual character string to the equivalent wide // character string. ACE_Vector<wchar_t*> buffer; @@ -676,8 +750,10 @@ ACE_Process::convert_env_buffer (const char* env) const { // Convert the char string to wchar_t wchar_t* str = ACE_Ascii_To_Wide::convert (env + start); + // Add the length of the string plus the nul terminator total += ACE_OS::strlen (str) + 1; + // Save it and set up for the next string buffer.push_back (str); start = ++i; @@ -689,6 +765,7 @@ ACE_Process::convert_env_buffer (const char* env) const i += ACE_OS::strlen (env + i); } } + // Copy each string into the buffer leaving a nul terminator between // each string and adding a second nul terminator at the end start = 0; @@ -704,6 +781,7 @@ ACE_Process::convert_env_buffer (const char* env) const return wenv; } #endif + ACE_Process_Options::ACE_Process_Options (bool inherit_environment, int command_line_buf_len, int env_buf_len, @@ -747,6 +825,7 @@ ACE_Process_Options::ACE_Process_Options (bool inherit_environment, ACE_NEW (command_line_buf_, ACE_TCHAR[command_line_buf_len]); command_line_buf_[0] = '\0'; + #if !defined (ACE_HAS_WINCE) working_directory_[0] = '\0'; ACE_NEW (environment_buf_, @@ -764,6 +843,7 @@ ACE_Process_Options::ACE_Process_Options (bool inherit_environment, #endif /* ACE_WIN32 */ #endif /* !ACE_HAS_WINCE */ } + #if !defined (ACE_HAS_WINCE) #if defined (ACE_WIN32) void @@ -773,6 +853,7 @@ ACE_Process_Options::inherit_environment (void) if (environment_inherited_) return; environment_inherited_ = 1; + // Get the existing environment. ACE_TCHAR *existing_environment = 0; #if defined (ACE_HAS_WCHAR) && !defined (ACE_USES_WCHAR) @@ -796,10 +877,13 @@ ACE_Process_Options::inherit_environment (void) else #endif existing_environment = ACE_OS::getenvstrings (); + size_t slot = 0; + while (existing_environment[slot] != '\0') { size_t len = ACE_OS::strlen (existing_environment + slot); + // Add the string to our env buffer. if (this->setenv_i (existing_environment + slot, len) == -1) { @@ -808,9 +892,11 @@ ACE_Process_Options::inherit_environment (void) ACE_TEXT ("ACE_Process_Options::ACE_Process_Options"))); break; } + // Skip to the next word. slot += len + 1; } + #if defined (ACE_HAS_WCHAR) && !defined (ACE_USES_WCHAR) if (this->use_unicode_environment_) ::FreeEnvironmentStringsW (existing_wide_env); @@ -818,28 +904,35 @@ ACE_Process_Options::inherit_environment (void) #endif ACE_TEXT_FreeEnvironmentStrings (existing_environment); } + #else /* defined ACE_WIN32 */ + ACE_TCHAR * const * ACE_Process_Options::env_argv (void) { return environment_argv_; } + #endif /* ACE_WIN32 */ + void ACE_Process_Options::enable_unicode_environment (void) { this->use_unicode_environment_ = true; } + void ACE_Process_Options::disable_unicode_environment (void) { this->use_unicode_environment_ = false; } + bool ACE_Process_Options::use_unicode_environment (void) const { return this->use_unicode_environment_; } + int ACE_Process_Options::setenv (ACE_TCHAR *envp[]) { @@ -851,35 +944,44 @@ ACE_Process_Options::setenv (ACE_TCHAR *envp[]) return -1; i++; } + #if defined (ACE_WIN32) if (inherit_environment_) this->inherit_environment (); #endif /* ACE_WIN32 */ + return 0; } + int ACE_Process_Options::setenv (const ACE_TCHAR *format, ...) { ACE_TCHAR stack_buf[DEFAULT_COMMAND_LINE_BUF_LEN]; + // Start varargs. va_list argp; va_start (argp, format); + // Add the rest of the varargs. ACE_OS::vsprintf (stack_buf, format, argp); // End varargs. va_end (argp); + // Append the string to are environment buffer. if (this->setenv_i (stack_buf, ACE_OS::strlen (stack_buf)) == -1) return -1; + #if defined (ACE_WIN32) if (inherit_environment_) this->inherit_environment (); #endif /* ACE_WIN32 */ + return 0; } + int ACE_Process_Options::setenv (const ACE_TCHAR *variable_name, const ACE_TCHAR *format, ...) @@ -890,21 +992,26 @@ ACE_Process_Options::setenv (const ACE_TCHAR *variable_name, ACE_TCHAR *newformat = 0; ACE_NEW_RETURN (newformat, ACE_TCHAR[buflen], -1); ACE_Auto_Basic_Array_Ptr<ACE_TCHAR> safe_newformat (newformat); + // Add in the variable name. ACE_OS::sprintf (safe_newformat.get (), ACE_TEXT ("%s=%s"), variable_name, format); + // Start varargs. va_list argp; va_start (argp, format); + // Add the rest of the varargs. size_t tmp_buflen = DEFAULT_COMMAND_LINE_BUF_LEN > buflen ? static_cast<size_t> (DEFAULT_COMMAND_LINE_BUF_LEN) : buflen; int retval = 0; + ACE_TCHAR *stack_buf = 0; ACE_NEW_RETURN (stack_buf, ACE_TCHAR[tmp_buflen], -1); ACE_Auto_Basic_Array_Ptr<ACE_TCHAR> safe_stack_buf (stack_buf); + do { retval = ACE_OS::vsnprintf (safe_stack_buf.get (), tmp_buflen, safe_newformat.get (), argp); @@ -918,6 +1025,7 @@ ACE_Process_Options::setenv (const ACE_TCHAR *variable_name, break; } while (1); + if (retval == -1) { // In case that vsnprintf is not supported, @@ -937,43 +1045,54 @@ ACE_Process_Options::setenv (const ACE_TCHAR *variable_name, // vsnprintf is failed. return -1; } + // End varargs. va_end (argp); + // Append the string to our environment buffer. if (this->setenv_i (safe_stack_buf.get (), ACE_OS::strlen (safe_stack_buf.get ())) == -1) return -1; + #if defined (ACE_WIN32) if (inherit_environment_) this->inherit_environment (); #endif /* ACE_WIN32 */ + return 0; } + int ACE_Process_Options::setenv_i (ACE_TCHAR *assignment, size_t len) { // Add one for the null char. ++len; + // If environment larger than allocated buffer return. Also check to // make sure we have enough room. if (environment_argv_index_ == max_environ_argv_index_ || (len + environment_buf_index_) >= environment_buf_len_) return -1; + // Copy the new environment string. ACE_OS::memcpy (environment_buf_ + environment_buf_index_, assignment, len * sizeof (ACE_TCHAR)); + // Update the argv array. environment_argv_[environment_argv_index_++] = environment_buf_ + environment_buf_index_; environment_argv_[environment_argv_index_] = 0; + // Update our index. environment_buf_index_ += len; + // Make sure the buffer is null-terminated. environment_buf_[environment_buf_index_] = '\0'; return 0; } + int ACE_Process_Options::set_handles (ACE_HANDLE std_in, ACE_HANDLE std_out, @@ -981,14 +1100,17 @@ ACE_Process_Options::set_handles (ACE_HANDLE std_in, { this->set_handles_called_ = 1; #if defined (ACE_WIN32) + // Tell the new process to use our std handles. this->startup_info_.dwFlags = STARTF_USESTDHANDLES; + if (std_in == ACE_INVALID_HANDLE) std_in = ACE_STDIN; if (std_out == ACE_INVALID_HANDLE) std_out = ACE_STDOUT; if (std_err == ACE_INVALID_HANDLE) std_err = ACE_STDERR; + if (!::DuplicateHandle (::GetCurrentProcess (), std_in, ::GetCurrentProcess (), @@ -997,6 +1119,7 @@ ACE_Process_Options::set_handles (ACE_HANDLE std_in, TRUE, DUPLICATE_SAME_ACCESS)) return -1; + if (!::DuplicateHandle (::GetCurrentProcess (), std_out, ::GetCurrentProcess (), @@ -1005,6 +1128,7 @@ ACE_Process_Options::set_handles (ACE_HANDLE std_in, TRUE, DUPLICATE_SAME_ACCESS)) return -1; + if (!::DuplicateHandle (::GetCurrentProcess (), std_err, ::GetCurrentProcess (), @@ -1018,9 +1142,11 @@ ACE_Process_Options::set_handles (ACE_HANDLE std_in, this->stdout_ = ACE_OS::dup (std_out); this->stderr_ = ACE_OS::dup (std_err); #endif /* ACE_WIN32 */ + return 0; // Success. } + void ACE_Process_Options::release_handles () { @@ -1040,6 +1166,7 @@ ACE_Process_Options::release_handles () } #endif /* !ACE_HAS_WINCE */ + ACE_Process_Options::~ACE_Process_Options (void) { #if !defined (ACE_HAS_WINCE) @@ -1050,11 +1177,13 @@ ACE_Process_Options::~ACE_Process_Options (void) delete [] command_line_buf_; ACE::strdelete (command_line_copy_); } + int ACE_Process_Options::command_line (const ACE_TCHAR *const argv[]) { // @@ Factor out the code between this int i = 0; + if (argv[i]) { ACE_OS::strcat (command_line_buf_, argv[i]); @@ -1066,17 +1195,21 @@ ACE_Process_Options::command_line (const ACE_TCHAR *const argv[]) argv[i]); } } + command_line_argv_calculated_ = 0; return 0; // Success. } + int ACE_Process_Options::command_line (const ACE_TCHAR *format, ...) { // Store all ... args in argp. va_list argp; va_start (argp, format); + if (command_line_buf_len_ < 1) return -1; + #if !defined (ACE_LACKS_VSNPRINTF) || defined (ACE_HAS_TRIO) // vsnprintf the format and args into command_line_buf__. ACE_OS::vsnprintf (command_line_buf_, @@ -1089,11 +1222,14 @@ ACE_Process_Options::command_line (const ACE_TCHAR *format, ...) format, argp); #endif + // Useless macro. va_end (argp); + command_line_argv_calculated_ = 0; return 0; } + #if defined (ACE_HAS_WCHAR) && !defined (ACE_HAS_WINCE) /** * @note Not available on Windows CE because it doesn't have a char version of @@ -1106,22 +1242,29 @@ ACE_Process_Options::command_line (const ACE_ANTI_TCHAR *format, ...) ACE_NEW_RETURN (anti_clb, ACE_ANTI_TCHAR[this->command_line_buf_len_], -1); + // Store all ... args in argp. va_list argp; va_start (argp, format); + // sprintf the format and args into command_line_buf_. ACE_OS::vsprintf (anti_clb, format, argp); + // Useless macro. va_end (argp); + ACE_OS::strcpy (this->command_line_buf_, ACE_TEXT_ANTI_TO_TCHAR (anti_clb)); + delete [] anti_clb; + command_line_argv_calculated_ = 0; return 0; } #endif /* ACE_HAS_WCHAR && !ACE_HAS_WINCE */ + ACE_TCHAR * ACE_Process_Options::env_buf (void) { @@ -1134,14 +1277,17 @@ ACE_Process_Options::env_buf (void) return 0; #endif /* !ACE_HAS_WINCE */ } + ACE_TCHAR * const * ACE_Process_Options::command_line_argv (void) { if (command_line_argv_calculated_ == 0) { command_line_argv_calculated_ = 1; + // We need to free up any previous allocated memory first. ACE::strdelete (command_line_copy_); + // We need to make a dynamically allocated copy here since // ACE_Tokenizer modifies its arguments. command_line_copy_ = ACE::strnew (command_line_buf_); @@ -1151,16 +1297,20 @@ ACE_Process_Options::command_line_argv (void) parser.delimiter_replace (' ', '\0'); parser.preserve_designators ('\"', '\"'); // " parser.preserve_designators ('\'', '\''); + int x = 0; do command_line_argv_[x] = parser.next (); while (command_line_argv_[x] != 0 // substract one for the ending zero. && ++x < MAX_COMMAND_LINE_OPTIONS - 1); + command_line_argv_[x] = 0; } + return command_line_argv_; } + // Cause the specified handle to be passed to a child process // when it's spawned. int @@ -1170,6 +1320,7 @@ ACE_Process_Options::pass_handle (ACE_HANDLE h) # if defined (ACE_HAS_WINCE) ACE_NOTSUP_RETURN (-1); # else + // This is oriented towards socket handles... may need some adjustment // for non-sockets. // This is all based on an MSDN article: @@ -1197,9 +1348,12 @@ ACE_Process_Options::pass_handle (ACE_HANDLE h) } # endif /* ACE_HAS_WINCE */ #endif /* ACE_WIN32 */ + this->handles_passed_.set_bit (h); + return 0; } + // Get a copy of the handles the ACE_Process_Options duplicated // for the spawned process. int @@ -1211,6 +1365,7 @@ ACE_Process_Options::dup_handles (ACE_Handle_Set &set) const set = this->dup_handles_; return 1; } + // Get a copy of the handles passed to the spawned process. This // will be the set of handles previously passed to @arg pass_handle(). int @@ -1222,13 +1377,16 @@ ACE_Process_Options::passed_handles (ACE_Handle_Set &set) const set = this->handles_passed_; return 1; } + ACE_Managed_Process::~ACE_Managed_Process (void) { } + void ACE_Managed_Process::unmanage (void) { delete this; } + ACE_END_VERSIONED_NAMESPACE_DECL |