aboutsummaryrefslogtreecommitdiff
path: root/dep/ACE_wrappers/ace/Process.cpp
diff options
context:
space:
mode:
authormaximius <none@none>2009-10-17 15:51:44 -0700
committermaximius <none@none>2009-10-17 15:51:44 -0700
commite585187b248f48b3c6e9247b49fa07c6565d65e5 (patch)
tree637c5b7ddacf41040bef4ea4f75a97da64c6a9bc /dep/ACE_wrappers/ace/Process.cpp
parent26b5e033ffde3d161382fc9addbfa99738379641 (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.cpp158
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