00001
00002
00003 #include "ace/Process.h"
00004
00005 #if !defined (__ACE_INLINE__)
00006 #include "ace/Process.inl"
00007 #endif
00008
00009 #include "ace/ARGV.h"
00010 #include "ace/Auto_Ptr.h"
00011 #include "ace/Signal.h"
00012 #include "ace/SString.h"
00013 #include "ace/Log_Msg.h"
00014 #include "ace/OS_NS_stdio.h"
00015 #include "ace/OS_NS_stdlib.h"
00016 #include "ace/OS_NS_sys_socket.h"
00017 #include "ace/OS_NS_errno.h"
00018 #include "ace/OS_NS_string.h"
00019 #include "ace/OS_NS_unistd.h"
00020 #include "ace/OS_Memory.h"
00021 #include "ace/Countdown_Time.h"
00022 #include "ace/Truncate.h"
00023
00024 #if defined (ACE_VXWORKS) && (ACE_VXWORKS > 0x600) && defined (__RTP__)
00025 # include <rtpLib.h>
00026 # include <taskLib.h>
00027 #endif
00028
00029 ACE_RCSID (ace, Process, "$Id: Process.cpp 79134 2007-07-31 18:23:50Z johnnyw $")
00030
00031
00032
00033
00034 #if !defined (ACE_WIN32) && !defined(ACE_LACKS_UNIX_SIGNALS)
00035 static void
00036 sigchld_nop (int, siginfo_t *, ucontext_t *)
00037 {
00038 return;
00039 }
00040 #endif
00041
00042
00043 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00044
00045 ACE_Process::ACE_Process (void)
00046 :
00047 #if !defined (ACE_WIN32)
00048 child_id_ (ACE_INVALID_PID),
00049 #endif
00050 exit_code_ (0)
00051 {
00052 #if defined (ACE_WIN32)
00053 ACE_OS::memset ((void *) &this->process_info_,
00054 0,
00055 sizeof this->process_info_);
00056 #endif
00057 }
00058
00059 ACE_Process::~ACE_Process (void)
00060 {
00061 #if defined (ACE_WIN32)
00062
00063 ACE_OS::close (this->process_info_.hThread);
00064 ACE_OS::close (this->process_info_.hProcess);
00065 #endif
00066
00067
00068 this->close_dup_handles ();
00069 }
00070
00071 int
00072 ACE_Process::prepare (ACE_Process_Options &)
00073 {
00074 return 0;
00075 }
00076
00077 pid_t
00078 ACE_Process::spawn (ACE_Process_Options &options)
00079 {
00080 if (prepare (options) < 0)
00081 return ACE_INVALID_PID;
00082
00083
00084
00085
00086 ACE_Handle_Set *set_p = 0;
00087 if (options.dup_handles (this->dup_handles_))
00088 set_p = &this->dup_handles_;
00089 else if (options.passed_handles (this->handles_passed_))
00090 set_p = &this->handles_passed_;
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 if (set_p && !ACE_BIT_ENABLED (options.creation_flags (),
00102 ACE_Process_Options::NO_EXEC))
00103 {
00104 int maxlen = 0;
00105 ACE_TCHAR *cmd_line_buf = options.command_line_buf (&maxlen);
00106 size_t max_len = static_cast<size_t> (maxlen);
00107 size_t curr_len = ACE_OS::strlen (cmd_line_buf);
00108 ACE_Handle_Set_Iterator h_iter (*set_p);
00109
00110
00111
00112 for (ACE_HANDLE h = h_iter ();
00113 h != ACE_INVALID_HANDLE && curr_len + 20 < max_len;
00114 h = h_iter ())
00115 {
00116 #if defined (ACE_WIN32)
00117 # if defined (ACE_WIN64)
00118 curr_len += ACE_OS::sprintf (&cmd_line_buf[curr_len],
00119 ACE_TEXT (" +H %I64p"),
00120 h);
00121 # else
00122 curr_len += ACE_OS::sprintf (&cmd_line_buf[curr_len],
00123 ACE_TEXT (" +H %p"),
00124 h);
00125 # endif
00126 #else
00127 curr_len += ACE_OS::sprintf (&cmd_line_buf[curr_len],
00128 ACE_TEXT (" +H %d"),
00129 h);
00130 #endif
00131 }
00132 }
00133
00134 #if defined (ACE_HAS_WINCE)
00135
00136
00137
00138
00139
00140 BOOL fork_result =
00141 ACE_TEXT_CreateProcess (options.process_name(),
00142 options.command_line_buf(),
00143 options.get_process_attributes(),
00144 options.get_thread_attributes(),
00145 options.handle_inheritence(),
00146 options.creation_flags(),
00147 options.env_buf(),
00148 options.working_directory(),
00149 options.startup_info(),
00150 &this->process_info_);
00151
00152 if (fork_result)
00153 {
00154 parent (this->getpid ());
00155 return this->getpid ();
00156 }
00157 return ACE_INVALID_PID;
00158
00159 #elif defined (ACE_WIN32)
00160 BOOL fork_result =
00161 ACE_TEXT_CreateProcess (0,
00162 options.command_line_buf (),
00163 options.get_process_attributes (),
00164 options.get_thread_attributes (),
00165 options.handle_inheritence (),
00166 options.creation_flags (),
00167 options.env_buf (),
00168 options.working_directory (),
00169 options.startup_info (),
00170 &this->process_info_);
00171
00172 if (fork_result)
00173 {
00174 parent (this->getpid ());
00175 return this->getpid ();
00176 }
00177 return ACE_INVALID_PID;
00178
00179 #elif defined(ACE_OPENVMS)
00180 if (ACE_BIT_ENABLED (options.creation_flags (),
00181 ACE_Process_Options::NO_EXEC))
00182 ACE_NOTSUP_RETURN (ACE_INVALID_PID);
00183
00184 int saved_stdin = ACE_STDIN;
00185 int saved_stdout = ACE_STDOUT;
00186 int saved_stderr = ACE_STDERR;
00187
00188 if (options.get_stdin () != ACE_INVALID_HANDLE) {
00189 if ((saved_stdin = ACE_OS::dup (ACE_STDIN)) == -1 && errno != EBADF)
00190 ACE_OS::exit (errno);
00191 if (ACE_OS::dup2 (options.get_stdin (), ACE_STDIN) == -1)
00192 ACE_OS::exit (errno);
00193 }
00194 if (options.get_stdout () != ACE_INVALID_HANDLE) {
00195 if ((saved_stdout = ACE_OS::dup (ACE_STDOUT)) == -1 && errno != EBADF)
00196 ACE_OS::exit (errno);
00197 if (ACE_OS::dup2 (options.get_stdout (), ACE_STDOUT) == -1)
00198 ACE_OS::exit (errno);
00199 }
00200 if (options.get_stderr () != ACE_INVALID_HANDLE) {
00201 if ((saved_stderr = ACE_OS::dup (ACE_STDERR)) == -1 && errno != EBADF)
00202 ACE_OS::exit (errno);
00203 if (ACE_OS::dup2 (options.get_stderr (), ACE_STDERR) == -1)
00204 ACE_OS::exit (errno);
00205 }
00206
00207 if (options.working_directory () != 0)
00208 ACE_NOTSUP_RETURN (ACE_INVALID_PID);
00209
00210 this->child_id_ = vfork();
00211 if (this->child_id_ == 0) {
00212 ACE_OS::execvp (options.process_name (),
00213 options.command_line_argv ());
00214
00215 this->child_id_ = ACE_INVALID_PID;
00216 }
00217
00218
00219 if (options.get_stdin () != ACE_INVALID_HANDLE) {
00220 if (saved_stdin == -1)
00221 ACE_OS::close (ACE_STDIN);
00222 else
00223 ACE_OS::dup2 (saved_stdin, ACE_STDIN);
00224 }
00225 if (options.get_stdout () != ACE_INVALID_HANDLE) {
00226 if (saved_stdout == -1)
00227 ACE_OS::close (ACE_STDOUT);
00228 else
00229 ACE_OS::dup2 (saved_stdout, ACE_STDOUT);
00230 }
00231 if (options.get_stderr () != ACE_INVALID_HANDLE) {
00232 if (saved_stderr == -1)
00233 ACE_OS::close (ACE_STDERR);
00234 else
00235 ACE_OS::dup2 (saved_stderr, ACE_STDERR);
00236 }
00237
00238 return this->child_id_;
00239 #elif (defined (ACE_VXWORKS) && (ACE_VXWORKS > 0x600)) && defined (__RTP__)
00240 if (ACE_BIT_ENABLED (options.creation_flags (),
00241 ACE_Process_Options::NO_EXEC))
00242 ACE_NOTSUP_RETURN (ACE_INVALID_PID);
00243
00244 if (options.working_directory () != 0)
00245 ACE_NOTSUP_RETURN (ACE_INVALID_PID);
00246
00247 int saved_stdin = ACE_STDIN;
00248 int saved_stdout = ACE_STDOUT;
00249 int saved_stderr = ACE_STDERR;
00250
00251 if (options.get_stdin () != ACE_INVALID_HANDLE) {
00252 if ((saved_stdin = ACE_OS::dup (ACE_STDIN)) == -1 && errno != EBADF)
00253 ACE_OS::exit (errno);
00254 if (ACE_OS::dup2 (options.get_stdin (), ACE_STDIN) == -1)
00255 ACE_OS::exit (errno);
00256 }
00257 if (options.get_stdout () != ACE_INVALID_HANDLE) {
00258 if ((saved_stdout = ACE_OS::dup (ACE_STDOUT)) == -1 && errno != EBADF)
00259 ACE_OS::exit (errno);
00260 if (ACE_OS::dup2 (options.get_stdout (), ACE_STDOUT) == -1)
00261 ACE_OS::exit (errno);
00262 }
00263 if (options.get_stderr () != ACE_INVALID_HANDLE) {
00264 if ((saved_stderr = ACE_OS::dup (ACE_STDERR)) == -1 && errno != EBADF)
00265 ACE_OS::exit (errno);
00266 if (ACE_OS::dup2 (options.get_stderr (), ACE_STDERR) == -1)
00267 ACE_OS::exit (errno);
00268 }
00269
00270
00271
00272 # if defined (ACE_USES_WCHAR)
00273 wchar_t * const *wargv = options.command_line_argv ();
00274 size_t vcount, i;
00275 for (vcount = 0; wargv[vcount] != 0; ++vcount)
00276 ;
00277 char **procargv = new char *[vcount + 1];
00278 procargv[vcount] = 0;
00279 for (i = 0; i < vcount; ++i)
00280 procargv[i] = ACE_Wide_To_Ascii::convert (wargv[i]);
00281
00282 char **procenv = 0;
00283 if (options.inherit_environment ())
00284 {
00285 wargv = options.env_argv ();
00286 for (vcount = 0; wargv[vcount] != 0; ++vcount)
00287 ;
00288 procenv = new char *[vcount + 1];
00289 procenv[vcount] = 0;
00290 for (i = 0; i < vcount; ++i)
00291 procenv[i] = ACE_Wide_To_Ascii::convert (wargv[i]);
00292 }
00293 # else
00294 const char **procargv = const_cast<const char**> (options.command_line_argv ());
00295 const char **procenv = const_cast<const char**> (options.env_argv ());
00296 # endif
00297
00298 this->child_id_ = ::rtpSpawn (procargv[0],
00299 procargv,
00300 procenv,
00301 200,
00302 0x10000,
00303 0,
00304 VX_FP_TASK);
00305 int my_errno_ = errno;
00306 if (this->child_id_ == ERROR) {
00307
00308 this->child_id_ = ACE_INVALID_PID;
00309 }
00310
00311 # if defined (ACE_USES_WCHAR)
00312 if (procenv)
00313 delete procenv;
00314 # endif
00315
00316
00317 if (options.get_stdin () != ACE_INVALID_HANDLE) {
00318 if (saved_stdin == -1)
00319 ACE_OS::close (ACE_STDIN);
00320 else
00321 ACE_OS::dup2 (saved_stdin, ACE_STDIN);
00322 }
00323 if (options.get_stdout () != ACE_INVALID_HANDLE) {
00324 if (saved_stdout == -1)
00325 ACE_OS::close (ACE_STDOUT);
00326 else
00327 ACE_OS::dup2 (saved_stdout, ACE_STDOUT);
00328 }
00329 if (options.get_stderr () != ACE_INVALID_HANDLE) {
00330 if (saved_stderr == -1)
00331 ACE_OS::close (ACE_STDERR);
00332 else
00333 ACE_OS::dup2 (saved_stderr, ACE_STDERR);
00334 }
00335
00336 if (this->child_id_ == ACE_INVALID_PID) {
00337 errno = my_errno_;
00338 }
00339
00340 return this->child_id_;
00341 #else
00342
00343 this->child_id_ = ACE::fork (options.process_name (),
00344 options.avoid_zombies ());
00345
00346 if (this->child_id_ == 0)
00347 {
00348 # if !defined (ACE_LACKS_SETPGID)
00349
00350
00351
00352
00353 if (options.getgroup () != ACE_INVALID_PID
00354 && ACE_OS::setpgid (0,
00355 options.getgroup ()) < 0)
00356 ACE_ERROR ((LM_ERROR,
00357 ACE_TEXT ("%p.\n"),
00358 ACE_TEXT ("ACE_Process::spawn: setpgid failed.")));
00359 # endif
00360
00361 # if !defined (ACE_LACKS_SETREGID)
00362 if (options.getrgid () != (uid_t) -1
00363 || options.getegid () != (uid_t) -1)
00364 if (ACE_OS::setregid (options.getrgid (),
00365 options.getegid ()) == -1)
00366 ACE_ERROR ((LM_ERROR,
00367 ACE_TEXT ("%p.\n"),
00368 ACE_TEXT ("ACE_Process::spawn: setregid failed.")));
00369 # endif
00370
00371 # if !defined (ACE_LACKS_SETREUID)
00372
00373 if (options.getruid () != (uid_t) -1
00374 || options.geteuid () != (uid_t) -1)
00375 if (ACE_OS::setreuid (options.getruid (),
00376 options.geteuid ()) == -1)
00377 ACE_ERROR ((LM_ERROR,
00378 ACE_TEXT ("%p.\n"),
00379 ACE_TEXT ("ACE_Process::spawn: setreuid failed.")));
00380 # endif
00381
00382 this->child (ACE_OS::getppid ());
00383 }
00384 else if (this->child_id_ != -1)
00385 this->parent (this->child_id_);
00386
00387
00388 if (ACE_BIT_ENABLED (options.creation_flags (),
00389 ACE_Process_Options::NO_EXEC))
00390 return this->child_id_;
00391
00392 switch (this->child_id_)
00393 {
00394 case -1:
00395
00396 return ACE_INVALID_PID;
00397 case 0:
00398
00399 {
00400 if (options.get_stdin () != ACE_INVALID_HANDLE
00401 && ACE_OS::dup2 (options.get_stdin (),
00402 ACE_STDIN) == -1)
00403 ACE_OS::exit (errno);
00404 else if (options.get_stdout () != ACE_INVALID_HANDLE
00405 && ACE_OS::dup2 (options.get_stdout (),
00406 ACE_STDOUT) == -1)
00407 ACE_OS::exit (errno);
00408 else if (options.get_stderr () != ACE_INVALID_HANDLE
00409 && ACE_OS::dup2 (options.get_stderr (),
00410 ACE_STDERR) == -1)
00411 ACE_OS::exit (errno);
00412
00413
00414 ACE_OS::close (options.get_stdin ());
00415 ACE_OS::close (options.get_stdout ());
00416 ACE_OS::close (options.get_stderr ());
00417
00418
00419
00420 if (options.working_directory () != 0)
00421 ACE_OS::chdir (options.working_directory ());
00422
00423
00424
00425 int result = 0;
00426
00427
00428
00429
00430
00431 # if defined (ACE_USES_WCHAR)
00432 ACE_Wide_To_Ascii n_procname (options.process_name ());
00433 const char *procname = n_procname.char_rep ();
00434
00435 wchar_t * const *wargv = options.command_line_argv ();
00436 size_t vcount, i;
00437 for (vcount = 0; wargv[vcount] != 0; ++vcount)
00438 ;
00439 char **procargv = new char *[vcount + 1];
00440 procargv[vcount] = 0;
00441 for (i = 0; i < vcount; ++i)
00442 procargv[i] = ACE_Wide_To_Ascii::convert (wargv[i]);
00443
00444 wargv = options.env_argv ();
00445 for (vcount = 0; wargv[vcount] != 0; ++vcount)
00446 ;
00447 char **procenv = new char *[vcount + 1];
00448 procenv[vcount] = 0;
00449 for (i = 0; i < vcount; ++i)
00450 procenv[i] = ACE_Wide_To_Ascii::convert (wargv[i]);
00451 # else
00452 const char *procname = options.process_name ();
00453 char *const *procargv = options.command_line_argv ();
00454 char *const *procenv = options.env_argv ();
00455 # endif
00456
00457 if (options.inherit_environment ())
00458 {
00459
00460
00461 for (size_t i = 0; procenv[i] != 0; i++)
00462 if (ACE_OS::putenv (procenv[i]) != 0)
00463 return ACE_INVALID_PID;
00464
00465
00466
00467 result = ACE_OS::execvp (procname, procargv);
00468 }
00469 else
00470 {
00471 # if defined (ghs)
00472
00473
00474 ACE_NOTSUP_RETURN (ACE_INVALID_PID);
00475 # else
00476 result = ACE_OS::execve (procname, procargv, procenv);
00477 # endif
00478 }
00479 if (result == -1)
00480 {
00481
00482
00483
00484
00485 ACE_OS::_exit (errno);
00486 }
00487
00488 return 0;
00489 }
00490 default:
00491
00492 return this->child_id_;
00493 }
00494 #endif
00495 }
00496
00497 void
00498 ACE_Process::parent (pid_t)
00499 {
00500
00501 }
00502
00503 void
00504 ACE_Process::child (pid_t)
00505 {
00506
00507 }
00508
00509 void
00510 ACE_Process::unmanage (void)
00511 {
00512
00513 }
00514
00515 int
00516 ACE_Process::running (void) const
00517 {
00518 #if defined (ACE_WIN32)
00519 DWORD code;
00520
00521 BOOL result = ::GetExitCodeProcess (this->gethandle (),
00522 &code);
00523 return result && code == STILL_ACTIVE;
00524 #else
00525 if (ACE_INVALID_PID == this->getpid ())
00526 return 0;
00527 else
00528 return ACE_OS::kill (this->getpid (),
00529 0) == 0
00530 || errno != ESRCH;
00531 #endif
00532 }
00533
00534 pid_t
00535 ACE_Process::wait (const ACE_Time_Value &tv,
00536 ACE_exitcode *status)
00537 {
00538 #if defined (ACE_WIN32)
00539
00540
00541 switch (::WaitForSingleObject (process_info_.hProcess,
00542 tv.msec ()))
00543 {
00544 case WAIT_OBJECT_0:
00545
00546
00547 ::GetExitCodeProcess (process_info_.hProcess,
00548 &this->exit_code_);
00549 if (status != 0)
00550 *status = this->exit_code_;
00551 return this->getpid ();
00552 case WAIT_TIMEOUT:
00553 errno = ETIME;
00554 return 0;
00555 default:
00556 ACE_OS::set_errno_to_last_error ();
00557 return -1;
00558 }
00559 #elif defined(ACE_LACKS_UNIX_SIGNALS)
00560 if (tv == ACE_Time_Value::zero)
00561 {
00562 pid_t retv =
00563 ACE_OS::waitpid (this->child_id_,
00564 &this->exit_code_,
00565 WNOHANG);
00566 if (status != 0)
00567 *status = this->exit_code_;
00568
00569 return retv;
00570 }
00571
00572 if (tv == ACE_Time_Value::max_time)
00573 # if defined (ACE_VXWORKS)
00574 {
00575 pid_t retv;
00576 while ( (retv = this->wait (status)) == ACE_INVALID_PID && errno == EINTR ) ;
00577 return retv;
00578 }
00579 # else
00580 return this->wait (status);
00581 # endif
00582
00583 pid_t pid = 0;
00584 ACE_Time_Value sleeptm (1);
00585 if (sleeptm > tv)
00586 sleeptm = tv;
00587 ACE_Time_Value tmo (tv);
00588 for (ACE_Countdown_Time time_left (&tmo); tmo > ACE_Time_Value::zero ; time_left.update ())
00589 {
00590 pid = ACE_OS::waitpid (this->getpid (),
00591 &this->exit_code_,
00592 WNOHANG);
00593 if (status != 0)
00594 *status = this->exit_code_;
00595
00596 if (pid > 0 || pid == ACE_INVALID_PID)
00597 break;
00598
00599
00600
00601 ACE_OS::sleep (sleeptm);
00602 }
00603
00604 return pid;
00605 #else
00606 if (tv == ACE_Time_Value::zero)
00607 {
00608 pid_t retv =
00609 ACE_OS::waitpid (this->child_id_,
00610 &this->exit_code_,
00611 WNOHANG);
00612 if (status != 0)
00613 *status = this->exit_code_;
00614
00615 return retv;
00616 }
00617
00618 if (tv == ACE_Time_Value::max_time)
00619 return this->wait (status);
00620
00621
00622
00623
00624
00625
00626
00627 ACE_Sig_Action old_action;
00628 ACE_Sig_Action do_sigchld ((ACE_SignalHandler)sigchld_nop);
00629 do_sigchld.register_action (SIGCHLD, &old_action);
00630
00631 pid_t pid;
00632 ACE_Time_Value tmo (tv);
00633 for (ACE_Countdown_Time time_left (&tmo); ; time_left.update ())
00634 {
00635 pid = ACE_OS::waitpid (this->getpid (),
00636 &this->exit_code_,
00637 WNOHANG);
00638 if (status != 0)
00639 *status = this->exit_code_;
00640
00641 if (pid > 0 || pid == ACE_INVALID_PID)
00642 break;
00643
00644
00645
00646
00647
00648
00649 if (-1 == ACE_OS::sleep (tmo) && errno == EINTR)
00650 continue;
00651
00652 pid = 0;
00653 break;
00654 }
00655
00656
00657 old_action.register_action (SIGCHLD);
00658
00659 return pid;
00660 #endif
00661 }
00662
00663 void
00664 ACE_Process::close_dup_handles (void)
00665 {
00666 if (this->dup_handles_.num_set () > 0)
00667 {
00668 ACE_Handle_Set_Iterator h_iter (this->dup_handles_);
00669 for (ACE_HANDLE h = h_iter ();
00670 h != ACE_INVALID_HANDLE;
00671 h = h_iter ())
00672 ACE_OS::closesocket (h);
00673 this->dup_handles_.reset ();
00674 }
00675 return;
00676 }
00677
00678 void
00679 ACE_Process::close_passed_handles (void)
00680 {
00681 if (this->handles_passed_.num_set () > 0)
00682 {
00683 ACE_Handle_Set_Iterator h_iter (this->handles_passed_);
00684 for (ACE_HANDLE h = h_iter ();
00685 h != ACE_INVALID_HANDLE;
00686 h = h_iter ())
00687 ACE_OS::closesocket (h);
00688 this->handles_passed_.reset ();
00689 }
00690 return;
00691 }
00692
00693 ACE_Process_Options::ACE_Process_Options (int ie,
00694 int cobl,
00695 int ebl,
00696 int mea)
00697 :
00698 #if !defined (ACE_HAS_WINCE)
00699 inherit_environment_ (ie),
00700 #endif
00701 creation_flags_ (0),
00702 avoid_zombies_ (0),
00703 #if !defined (ACE_HAS_WINCE)
00704 #if defined (ACE_WIN32)
00705 environment_inherited_ (0),
00706 handle_inheritence_ (TRUE),
00707 process_attributes_ (0),
00708 thread_attributes_ (0),
00709 #else
00710 stdin_ (ACE_INVALID_HANDLE),
00711 stdout_ (ACE_INVALID_HANDLE),
00712 stderr_ (ACE_INVALID_HANDLE),
00713 ruid_ ((uid_t) -1),
00714 euid_ ((uid_t) -1),
00715 rgid_ ((uid_t) -1),
00716 egid_ ((uid_t) -1),
00717 #endif
00718 set_handles_called_ (0),
00719 environment_buf_index_ (0),
00720 environment_argv_index_ (0),
00721 environment_buf_ (0),
00722 environment_buf_len_ (ebl),
00723 max_environment_args_ (mea),
00724 max_environ_argv_index_ (mea - 1),
00725 #endif
00726 command_line_argv_calculated_ (0),
00727 command_line_buf_ (0),
00728 command_line_copy_ (0),
00729 command_line_buf_len_ (cobl),
00730 process_group_ (ACE_INVALID_PID)
00731 {
00732 ACE_NEW (command_line_buf_,
00733 ACE_TCHAR[cobl]);
00734 command_line_buf_[0] = '\0';
00735
00736 #if !defined (ACE_HAS_WINCE)
00737 working_directory_[0] = '\0';
00738 ACE_NEW (environment_buf_,
00739 ACE_TCHAR[ebl]);
00740 ACE_NEW (environment_argv_,
00741 ACE_TCHAR *[mea]);
00742 environment_buf_[0] = '\0';
00743 environment_argv_[0] = 0;
00744 process_name_[0] = '\0';
00745 #if defined (ACE_WIN32)
00746 ACE_OS::memset ((void *) &this->startup_info_,
00747 0,
00748 sizeof this->startup_info_);
00749 this->startup_info_.cb = sizeof this->startup_info_;
00750 #endif
00751 #endif
00752 }
00753
00754 #if !defined (ACE_HAS_WINCE)
00755 #if defined (ACE_WIN32)
00756 void
00757 ACE_Process_Options::inherit_environment (void)
00758 {
00759
00760 if (environment_inherited_)
00761 return;
00762 environment_inherited_ = 1;
00763
00764
00765 ACE_TCHAR *existing_environment = ACE_OS::getenvstrings ();
00766
00767 size_t slot = 0;
00768
00769 while (existing_environment[slot] != '\0')
00770 {
00771 size_t len = ACE_OS::strlen (existing_environment + slot);
00772
00773
00774 if (this->setenv_i (existing_environment + slot, len) == -1)
00775 {
00776 ACE_ERROR ((LM_ERROR,
00777 ACE_TEXT ("%p.\n"),
00778 ACE_TEXT ("ACE_Process_Options::ACE_Process_Options")));
00779 break;
00780 }
00781
00782
00783 slot += len + 1;
00784 }
00785
00786 ACE_TEXT_FreeEnvironmentStrings (existing_environment);
00787 }
00788
00789 #else
00790
00791 ACE_TCHAR * const *
00792 ACE_Process_Options::env_argv (void)
00793 {
00794 return environment_argv_;
00795 }
00796
00797 #endif
00798
00799 int
00800 ACE_Process_Options::setenv (ACE_TCHAR *envp[])
00801 {
00802 int i = 0;
00803 while (envp[i])
00804 {
00805 if (this->setenv_i (envp[i],
00806 ACE_OS::strlen (envp[i])) == -1)
00807 return -1;
00808 i++;
00809 }
00810
00811 #if defined (ACE_WIN32)
00812 if (inherit_environment_)
00813 this->inherit_environment ();
00814 #endif
00815
00816 return 0;
00817 }
00818
00819 int
00820 ACE_Process_Options::setenv (const ACE_TCHAR *format, ...)
00821 {
00822 ACE_TCHAR stack_buf[DEFAULT_COMMAND_LINE_BUF_LEN];
00823
00824
00825 va_list argp;
00826 va_start (argp, format);
00827
00828
00829 ACE_OS::vsprintf (stack_buf,
00830 format,
00831 argp);
00832
00833 va_end (argp);
00834
00835
00836 if (this->setenv_i (stack_buf,
00837 ACE_OS::strlen (stack_buf)) == -1)
00838 return -1;
00839
00840 #if defined (ACE_WIN32)
00841 if (inherit_environment_)
00842 this->inherit_environment ();
00843 #endif
00844
00845 return 0;
00846 }
00847
00848 int
00849 ACE_Process_Options::setenv (const ACE_TCHAR *variable_name,
00850 const ACE_TCHAR *format, ...)
00851 {
00852
00853
00854 size_t const buflen = ACE_OS::strlen (variable_name) + ACE_OS::strlen (format) + 2;
00855 ACE_TCHAR *newformat = 0;
00856 ACE_NEW_RETURN (newformat, ACE_TCHAR[buflen], -1);
00857 ACE_Auto_Basic_Array_Ptr<ACE_TCHAR> safe_newformat (newformat);
00858
00859
00860 ACE_OS::sprintf (safe_newformat.get (),
00861 ACE_TEXT ("%s=%s"),
00862 variable_name,
00863 format);
00864
00865
00866 va_list argp;
00867 va_start (argp, format);
00868
00869
00870 size_t tmp_buflen = DEFAULT_COMMAND_LINE_BUF_LEN > buflen
00871 ? static_cast<size_t> (DEFAULT_COMMAND_LINE_BUF_LEN) : buflen;
00872 int retval = 0;
00873
00874 ACE_TCHAR *stack_buf = 0;
00875 ACE_NEW_RETURN (stack_buf, ACE_TCHAR[tmp_buflen], -1);
00876 ACE_Auto_Basic_Array_Ptr<ACE_TCHAR> safe_stack_buf (stack_buf);
00877
00878 do
00879 {
00880 retval = ACE_OS::vsnprintf (safe_stack_buf.get (), tmp_buflen, safe_newformat.get (), argp);
00881 if (retval > ACE_Utils::truncate_cast<int> (tmp_buflen))
00882 {
00883 tmp_buflen *= 2;
00884 ACE_NEW_RETURN (stack_buf, ACE_TCHAR[tmp_buflen], -1);
00885 safe_stack_buf.reset (stack_buf);
00886 }
00887 else
00888 break;
00889 }
00890 while (1);
00891
00892 if (retval == -1)
00893 {
00894
00895
00896
00897 if (errno == ENOTSUP)
00898 {
00899
00900
00901
00902 retval = ACE_OS::vsprintf (safe_stack_buf.get (), safe_newformat.get (), argp);
00903 if (retval == -1)
00904
00905 return -1;
00906 }
00907 else
00908
00909 return -1;
00910 }
00911
00912
00913 va_end (argp);
00914
00915
00916 if (this->setenv_i (safe_stack_buf.get (),
00917 ACE_OS::strlen (safe_stack_buf.get ())) == -1)
00918 return -1;
00919
00920 #if defined (ACE_WIN32)
00921 if (inherit_environment_)
00922 this->inherit_environment ();
00923 #endif
00924
00925 return 0;
00926 }
00927
00928 int
00929 ACE_Process_Options::setenv_i (ACE_TCHAR *assignment,
00930 size_t len)
00931 {
00932
00933 ++len;
00934
00935
00936
00937 if (environment_argv_index_ == max_environ_argv_index_
00938 || (len + environment_buf_index_) >= environment_buf_len_)
00939 return -1;
00940
00941
00942 ACE_OS::memcpy (environment_buf_ + environment_buf_index_,
00943 assignment,
00944 len * sizeof (ACE_TCHAR));
00945
00946
00947 environment_argv_[environment_argv_index_++] =
00948 environment_buf_ + environment_buf_index_;
00949 environment_argv_[environment_argv_index_] = 0;
00950
00951
00952 environment_buf_index_ += len;
00953
00954
00955 environment_buf_[environment_buf_index_] = '\0';
00956 return 0;
00957 }
00958
00959 int
00960 ACE_Process_Options::set_handles (ACE_HANDLE std_in,
00961 ACE_HANDLE std_out,
00962 ACE_HANDLE std_err)
00963 {
00964 this->set_handles_called_ = 1;
00965 #if defined (ACE_WIN32)
00966
00967
00968 this->startup_info_.dwFlags = STARTF_USESTDHANDLES;
00969
00970 if (std_in == ACE_INVALID_HANDLE)
00971 std_in = ACE_STDIN;
00972 if (std_out == ACE_INVALID_HANDLE)
00973 std_out = ACE_STDOUT;
00974 if (std_err == ACE_INVALID_HANDLE)
00975 std_err = ACE_STDERR;
00976
00977 if (!::DuplicateHandle (::GetCurrentProcess (),
00978 std_in,
00979 ::GetCurrentProcess (),
00980 &this->startup_info_.hStdInput,
00981 0,
00982 TRUE,
00983 DUPLICATE_SAME_ACCESS))
00984 return -1;
00985
00986 if (!::DuplicateHandle (::GetCurrentProcess (),
00987 std_out,
00988 ::GetCurrentProcess (),
00989 &this->startup_info_.hStdOutput,
00990 0,
00991 TRUE,
00992 DUPLICATE_SAME_ACCESS))
00993 return -1;
00994
00995 if (!::DuplicateHandle (::GetCurrentProcess (),
00996 std_err,
00997 ::GetCurrentProcess (),
00998 &this->startup_info_.hStdError,
00999 0,
01000 TRUE,
01001 DUPLICATE_SAME_ACCESS))
01002 return -1;
01003 #else
01004 this->stdin_ = ACE_OS::dup (std_in);
01005 this->stdout_ = ACE_OS::dup (std_out);
01006 this->stderr_ = ACE_OS::dup (std_err);
01007 #endif
01008
01009 return 0;
01010 }
01011
01012
01013 void
01014 ACE_Process_Options::release_handles ()
01015 {
01016 if (set_handles_called_)
01017 {
01018 #if defined (ACE_WIN32)
01019 ACE_OS::close (startup_info_.hStdInput);
01020 ACE_OS::close (startup_info_.hStdOutput);
01021 ACE_OS::close (startup_info_.hStdError);
01022 #else
01023 ACE_OS::close (stdin_);
01024 ACE_OS::close (stdout_);
01025 ACE_OS::close (stderr_);
01026 #endif
01027 set_handles_called_ = 0;
01028 }
01029 }
01030 #endif
01031
01032
01033 ACE_Process_Options::~ACE_Process_Options (void)
01034 {
01035 #if !defined (ACE_HAS_WINCE)
01036 release_handles();
01037 delete [] environment_buf_;
01038 delete [] environment_argv_;
01039 #endif
01040 delete [] command_line_buf_;
01041 ACE::strdelete (command_line_copy_);
01042 }
01043
01044 int
01045 ACE_Process_Options::command_line (const ACE_TCHAR *const argv[])
01046 {
01047
01048 int i = 0;
01049
01050 if (argv[i])
01051 {
01052 ACE_OS::strcat (command_line_buf_, argv[i]);
01053 while (argv[++i])
01054 {
01055 ACE_OS::strcat (command_line_buf_,
01056 ACE_TEXT (" "));
01057 ACE_OS::strcat (command_line_buf_,
01058 argv[i]);
01059 }
01060 }
01061
01062 command_line_argv_calculated_ = 0;
01063 return 0;
01064 }
01065
01066 int
01067 ACE_Process_Options::command_line (const ACE_TCHAR *format, ...)
01068 {
01069
01070 va_list argp;
01071 va_start (argp, format);
01072
01073 if (command_line_buf_len_ < 1)
01074 return -1;
01075
01076 #if !defined (ACE_LACKS_VSNPRINTF) || defined (ACE_HAS_TRIO)
01077
01078 ACE_OS::vsnprintf (command_line_buf_,
01079 command_line_buf_len_,
01080 format,
01081 argp);
01082 #else
01083
01084 ACE_OS::vsprintf (command_line_buf_,
01085 format,
01086 argp);
01087 #endif
01088
01089
01090 va_end (argp);
01091
01092 command_line_argv_calculated_ = 0;
01093 return 0;
01094 }
01095
01096 #if defined (ACE_HAS_WCHAR) && !defined (ACE_HAS_WINCE)
01097
01098
01099
01100
01101 int
01102 ACE_Process_Options::command_line (const ACE_ANTI_TCHAR *format, ...)
01103 {
01104 ACE_ANTI_TCHAR *anti_clb;
01105 ACE_NEW_RETURN (anti_clb,
01106 ACE_ANTI_TCHAR[this->command_line_buf_len_],
01107 -1);
01108
01109
01110 va_list argp;
01111 va_start (argp, format);
01112
01113
01114 ACE_OS::vsprintf (anti_clb,
01115 format,
01116 argp);
01117
01118
01119 va_end (argp);
01120
01121 ACE_OS::strcpy (this->command_line_buf_,
01122 ACE_TEXT_ANTI_TO_TCHAR (anti_clb));
01123
01124 delete [] anti_clb;
01125
01126 command_line_argv_calculated_ = 0;
01127 return 0;
01128 }
01129 #endif
01130
01131 ACE_TCHAR *
01132 ACE_Process_Options::env_buf (void)
01133 {
01134 #if !defined (ACE_HAS_WINCE)
01135 if (environment_buf_[0] == '\0')
01136 return 0;
01137 else
01138 return environment_buf_;
01139 #else
01140 return 0;
01141 #endif
01142 }
01143
01144 ACE_TCHAR * const *
01145 ACE_Process_Options::command_line_argv (void)
01146 {
01147 if (command_line_argv_calculated_ == 0)
01148 {
01149 command_line_argv_calculated_ = 1;
01150
01151
01152 ACE::strdelete (command_line_copy_);
01153
01154
01155
01156 command_line_copy_ = ACE::strnew (command_line_buf_);
01157
01158
01159 ACE_Tokenizer parser (command_line_copy_);
01160 parser.delimiter_replace (' ', '\0');
01161 parser.preserve_designators ('\"', '\"');
01162 parser.preserve_designators ('\'', '\'');
01163
01164 int x = 0;
01165 do
01166 command_line_argv_[x] = parser.next ();
01167 while (command_line_argv_[x] != 0
01168
01169 && ++x < MAX_COMMAND_LINE_OPTIONS - 1);
01170
01171 command_line_argv_[x] = 0;
01172 }
01173
01174 return command_line_argv_;
01175 }
01176
01177
01178
01179 int
01180 ACE_Process_Options::pass_handle (ACE_HANDLE h)
01181 {
01182 # if defined (ACE_WIN32)
01183 # if defined (ACE_HAS_WINCE)
01184 ACE_NOTSUP_RETURN (-1);
01185 # else
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195 ACE_TEXT_OSVERSIONINFO osvi;
01196 ZeroMemory (&osvi, sizeof (osvi));
01197 osvi.dwOSVersionInfoSize = sizeof (ACE_TEXT_OSVERSIONINFO);
01198
01199 if (!ACE_TEXT_GetVersionEx (&osvi) || osvi.dwPlatformId != VER_PLATFORM_WIN32_NT)
01200 {
01201 HANDLE dup_handle;
01202 if (!DuplicateHandle (GetCurrentProcess (),
01203 static_cast<HANDLE> (h),
01204 GetCurrentProcess (),
01205 &dup_handle,
01206 0,
01207 TRUE,
01208 DUPLICATE_SAME_ACCESS))
01209 return -1;
01210 dup_handles_.set_bit (static_cast<ACE_HANDLE> (dup_handle));
01211 }
01212 # endif
01213 #endif
01214
01215 this->handles_passed_.set_bit (h);
01216
01217 return 0;
01218 }
01219
01220
01221
01222 int
01223 ACE_Process_Options::dup_handles (ACE_Handle_Set &set) const
01224 {
01225 if (this->dup_handles_.num_set () == 0)
01226 return 0;
01227 set.reset ();
01228 set = this->dup_handles_;
01229 return 1;
01230 }
01231
01232
01233
01234 int
01235 ACE_Process_Options::passed_handles (ACE_Handle_Set &set) const
01236 {
01237 if (this->handles_passed_.num_set () == 0)
01238 return 0;
01239 set.reset ();
01240 set = this->handles_passed_;
01241 return 1;
01242 }
01243
01244 ACE_Managed_Process::~ACE_Managed_Process (void)
01245 {
01246 }
01247
01248 void
01249 ACE_Managed_Process::unmanage (void)
01250 {
01251 delete this;
01252 }
01253
01254 ACE_END_VERSIONED_NAMESPACE_DECL