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