#include <Process.h>
Inheritance diagram for ACE_Process:


Public Methods | |
| ACE_Process (void) | |
| Default construction. Must use <ACE_Process::spawn> to start. More... | |
| virtual | ~ACE_Process (void) |
| Destructor. More... | |
| virtual int | prepare (ACE_Process_Options &options) |
| virtual pid_t | spawn (ACE_Process_Options &options) |
| virtual void | parent (pid_t child) |
| Called just after <ACE_OS::fork> in the parent's context, if the <fork> succeeds. The default is to do nothing. More... | |
| virtual void | child (pid_t parent) |
| virtual void | unmanage (void) |
| Called by a <Process_Manager> that is removing this Process from its table of managed Processes. Default is to do nothing. More... | |
| pid_t | wait (ACE_exitcode *status=0, int wait_options=0) |
| pid_t | wait (const ACE_Time_Value &tv, ACE_exitcode *status=0) |
| int | kill (int signum=SIGINT) |
| Send the process a signal. This is only portable to operating systems that support signals, such as UNIX/POSIX. More... | |
| int | terminate (void) |
| pid_t | getpid (void) const |
| Return the process id of the new child process. More... | |
| ACE_HANDLE | gethandle (void) const |
| Return the handle of the process, if it has one. More... | |
| int | running (void) const |
| Return 1 if running; 0 otherwise. More... | |
| ACE_exitcode | exit_code (void) const |
| Return the Process' exit code. This method returns the raw exit status returned from system APIs (such as <wait> or <waitpid>). This value is system dependent. More... | |
| int | return_value (void) const |
| Return the Process' return value. This method returns the actual return value that a child process returns or <exit>s. More... | |
| void | close_dup_handles (void) |
Close all the handles in the set obtained from the
| |
| void | close_passed_handles (void) |
Close all the handles in the set obtained from the
| |
| PROCESS_INFORMATION | process_info (void) |
Protected Methods | |
| void | exit_code (ACE_exitcode code) |
| Set this process' <exit_code_>. ACE_Process_Manager uses this method to set the <exit_code_> after successfully waiting for this proecess to exit. More... | |
Protected Attributes | |
| PROCESS_INFORMATION | process_info_ |
| ACE_exitcode | exit_code_ |
| ACE_Handle_Set | handles_passed_ |
| Set of handles that were passed to the child process. More... | |
| ACE_Handle_Set | dup_handles_ |
| Handle duplicates made for the child process. More... | |
Friends | |
| class | ACE_Process_Manager |
A Portable encapsulation for creating new processes. Notice that on UNIX platforms, if the <setenv> is used, the <spawn> is using the <execve> system call. It means that the <command_line> should include a full path to the program file (<execve> does not search the PATH). If <setenv> is not used then, the <spawn> is using the <execvp> which searches for the program file in the PATH variable.
Definition at line 430 of file Process.h.
|
|
Default construction. Must use <ACE_Process::spawn> to start.
Definition at line 31 of file Process.cpp. References ACE_INVALID_PID, and ACE_OS_String::memset.
00032 : 00033 #if !defined (ACE_WIN32) 00034 child_id_ (ACE_INVALID_PID), 00035 #endif /* !defined (ACE_WIN32) */ 00036 exit_code_ (0) 00037 { 00038 #if defined (ACE_WIN32) 00039 ACE_OS::memset ((void *) &this->process_info_, 00040 0, 00041 sizeof this->process_info_); 00042 #endif /* ACE_WIN32 */ 00043 } |
|
|
Destructor.
Definition at line 45 of file Process.cpp. References ACE_OS::close, and close_dup_handles.
00046 {
00047 #if defined (ACE_WIN32)
00048 // Free resources allocated in kernel.
00049 ACE_OS::close (this->process_info_.hThread);
00050 ACE_OS::close (this->process_info_.hProcess);
00051 #endif /* ACE_WIN32 */
00052 // If any handles were duplicated for the child process and
00053 // still not closed, get them now.
00054 this->close_dup_handles ();
00055 }
|
|
|
Called just after <ACE_OS::fork> in the child's context. The default does nothing. This function is *not* called on Win32 because the process-creation scheme does not allow it. Definition at line 329 of file Process.cpp. References pid_t. Referenced by spawn.
00330 {
00331 // nothing to do
00332 }
|
|
|
Close all the handles in the set obtained from the
Definition at line 440 of file Process.cpp. References ACE_OS::closesocket, dup_handles_, ACE_Handle_Set::num_set, and ACE_Handle_Set::reset. Referenced by ~ACE_Process.
00441 {
00442 if (this->dup_handles_.num_set () > 0)
00443 {
00444 ACE_Handle_Set_Iterator h_iter (this->dup_handles_);
00445 for (ACE_HANDLE h = h_iter ();
00446 h != ACE_INVALID_HANDLE;
00447 h = h_iter ())
00448 ACE_OS::closesocket (h);
00449 this->dup_handles_.reset ();
00450 }
00451 return;
00452 }
|
|
|
Close all the handles in the set obtained from the
Definition at line 455 of file Process.cpp. References ACE_OS::closesocket, handles_passed_, ACE_Handle_Set::num_set, and ACE_Handle_Set::reset.
00456 {
00457 if (this->handles_passed_.num_set () > 0)
00458 {
00459 ACE_Handle_Set_Iterator h_iter (this->handles_passed_);
00460 for (ACE_HANDLE h = h_iter ();
00461 h != ACE_INVALID_HANDLE;
00462 h = h_iter ())
00463 ACE_OS::closesocket (h);
00464 this->handles_passed_.reset ();
00465 }
00466 return;
00467 }
|
|
|
Set this process' <exit_code_>. ACE_Process_Manager uses this method to set the <exit_code_> after successfully waiting for this proecess to exit.
Definition at line 87 of file Process.i. References ACE_exitcode, and exit_code_.
00088 {
00089 this->exit_code_ = code;
00090 }
|
|
|
Return the Process' exit code. This method returns the raw exit status returned from system APIs (such as <wait> or <waitpid>). This value is system dependent.
Definition at line 81 of file Process.i. References exit_code_. Referenced by ACE_Process_Manager::notify_proc_handler.
00082 {
00083 return this->exit_code_;
00084 }
|
|
|
Return the handle of the process, if it has one.
Definition at line 14 of file Process.i. References process_info_. Referenced by ACE_Process_Manager::append_proc, ACE_Process_Manager::find_proc, ACE_Process_Manager::remove_proc, running, and ACE_Process_Manager::wait.
00015 {
00016 #if defined (ACE_WIN32)
00017 return process_info_.hProcess;
00018 #else
00019 return ACE_HANDLE (child_id_);
00020 #endif /* ACE_WIN32 */
00021 }
|
|
|
Return the process id of the new child process.
Definition at line 24 of file Process.i. Referenced by ACE_Process_Manager::find_proc, ACE_Process_Manager::handle_signal, ACE_Process_Manager::insert_proc, kill, spawn, terminate, ACE_Process_Manager::wait, and wait.
00026 {
00027 #if defined (ACE_WIN32)
00028 return process_info_.dwProcessId;
00029 #else /* ACE_WIN32 */
00030 return child_id_;
00031 #endif /* ACE_WIN32 */
00032 }
|
|
|
Send the process a signal. This is only portable to operating systems that support signals, such as UNIX/POSIX.
Definition at line 53 of file Process.i. References getpid, and ACE_OS::kill.
00054 {
00055 if (this->getpid () != -1)
00056 return ACE_OS::kill (this->getpid (), signum);
00057 else
00058 return -1;
00059 }
|
|
|
Called just after <ACE_OS::fork> in the parent's context, if the <fork> succeeds. The default is to do nothing.
Definition at line 323 of file Process.cpp. References pid_t. Referenced by spawn.
00324 {
00325 // nothing to do
00326 }
|
|
|
Called just before <ACE_OS::fork> in the <spawn>. If this returns non-zero, the <spawn> is aborted (and returns ACE_INVALID_PID). The default simply returns zero. Definition at line 58 of file Process.cpp. Referenced by spawn.
00059 {
00060 return 0;
00061 }
|
|
|
|
|
|
Return the Process' return value. This method returns the actual return value that a child process returns or <exit>s.
Definition at line 71 of file Process.i. References exit_code_, and WEXITSTATUS.
00072 {
00073 #if defined (ACE_WIN32)
00074 return this->exit_code_;
00075 #else
00076 return WEXITSTATUS (this->exit_code_);
00077 #endif /* ACE_WIN32 */
00078 }
|
|
|
Return 1 if running; 0 otherwise.
Definition at line 341 of file Process.cpp. References gethandle, and ACE_OS::kill.
00342 {
00343 #if defined (ACE_WIN32)
00344 DWORD code;
00345
00346 BOOL result = ::GetExitCodeProcess (this->gethandle (),
00347 &code);
00348 return result && code == STILL_ACTIVE;
00349 #else
00350 return ACE_OS::kill (this->getpid (),
00351 0) == 0
00352 || errno != ESRCH;
00353 #endif /* ACE_WIN32 */
00354 }
|
|
|
Launch a new process as described by <options>. Returns the process id of the newly spawned child on success or -1 on failure. Definition at line 64 of file Process.cpp. References ACE_OS::_exit, ACE_BIT_ENABLED, ACE_ERROR, ACE_INVALID_PID, ACE_LIB_TEXT, ACE_STDERR, ACE_STDIN, ACE_STDOUT, ACE_TCHAR, ACE_Process_Options::avoid_zombies, ACE_OS::chdir, child, ACE_OS::close, ACE_Process_Options::command_line_argv, ACE_Process_Options::command_line_buf, ACE_Process_Options::creation_flags, ACE_OS::dup2, ACE_Process_Options::dup_handles, dup_handles_, ACE_Process_Options::env_buf, ACE_OS::execve, ACE_OS::execvp, ACE_OS::exit, ACE::fork, ACE_Process_Options::get_process_attributes, ACE_Process_Options::get_thread_attributes, ACE_Process_Options::getgroup, getpid, ACE_OS::getppid, ACE_Process_Options::handle_inheritence, handles_passed_, ACE_Process_Options::inherit_environment, LM_ERROR, ACE_Process_Options::NO_EXEC, parent, ACE_Process_Options::passed_handles, prepare, process_info_, ACE_Process_Options::process_name, ACE_OS::putenv, ACE_OS::setpgid, ACE_OS::setregid, ACE_OS::setreuid, ACE_OS::sprintf, ACE_Process_Options::startup_info, ACE_OS_String::strlen, and ACE_Process_Options::working_directory. Referenced by ACE_Process_Manager::spawn.
00065 {
00066 if (prepare (options) < 0)
00067 return ACE_INVALID_PID;
00068
00069 // Stash the passed/duped handle sets away in this object for later
00070 // closing if needed or requested. At the same time, figure out which
00071 // ones to include in command line options if that's needed below.
00072 ACE_Handle_Set *set_p = 0;
00073 if (options.dup_handles (this->dup_handles_))
00074 set_p = &this->dup_handles_;
00075 else if (options.passed_handles (this->handles_passed_))
00076 set_p = &this->handles_passed_;
00077
00078 // If we are going to end up running a new program (i.e. Win32, or
00079 // NO_EXEC option is set) then get any handles passed in the options,
00080 // and tack them onto the command line with +H <handle> options,
00081 // unless the command line runs out of space.
00082 // Note that we're using the knowledge that all the options, argvs, etc.
00083 // passed to the options are all sitting in the command_line_buf. Any
00084 // call to get the argv then splits them out. So, regardless of the
00085 // platform, tack them all onto the command line buf and take it
00086 // from there.
00087 if (set_p && !ACE_BIT_ENABLED (options.creation_flags (),
00088 ACE_Process_Options::NO_EXEC))
00089 {
00090 int maxlen = 0;
00091 ACE_TCHAR *cmd_line_buf = options.command_line_buf (&maxlen);
00092 size_t max_len = ACE_static_cast (size_t, maxlen);
00093 size_t curr_len = ACE_OS::strlen (cmd_line_buf);
00094 ACE_Handle_Set_Iterator h_iter (*set_p);
00095 // Because the length of the to-be-formatted +H option is not
00096 // known, and we don't have a snprintf, guess at the space
00097 // needed (20 chars), and use that as a limit.
00098 for (ACE_HANDLE h = h_iter ();
00099 h != ACE_INVALID_HANDLE && curr_len + 20 < max_len;
00100 h = h_iter ())
00101 {
00102 curr_len += ACE_OS::sprintf (&cmd_line_buf[curr_len],
00103 ACE_LIB_TEXT (" +H %d"),
00104 h);
00105 }
00106 }
00107
00108 #if defined (ACE_HAS_WINCE)
00109 // Note that WinCE does not have process name included in the command line as argv[0]
00110 // like other OS environment. Therefore, it is user's whole responsibility to call
00111 // 'ACE_Process_Options::process_name(const ACE_TCHAR *name)' to set the proper
00112 // process name (the execution file name with path if needed).
00113
00114 BOOL fork_result =
00115 ACE_TEXT_CreateProcess (options.process_name(),
00116 options.command_line_buf(),
00117 options.get_process_attributes(), // must be NULL in CE
00118 options.get_thread_attributes(), // must be NULL in CE
00119 options.handle_inheritence(), // must be false in CE
00120 options.creation_flags(), // must be NULL in CE
00121 options.env_buf(), // environment variables, must be NULL in CE
00122 options.working_directory(), // must be NULL in CE
00123 options.startup_info(), // must be NULL in CE
00124 &this->process_info_);
00125
00126 if (fork_result)
00127 {
00128 parent (this->getpid ());
00129 return this->getpid ();
00130 }
00131 return ACE_INVALID_PID;
00132
00133 #elif defined (ACE_WIN32)
00134 BOOL fork_result =
00135 ACE_TEXT_CreateProcess (0,
00136 options.command_line_buf (),
00137 options.get_process_attributes (),
00138 options.get_thread_attributes (),
00139 options.handle_inheritence (),
00140 options.creation_flags (),
00141 options.env_buf (), // environment variables
00142 options.working_directory (),
00143 options.startup_info (),
00144 &this->process_info_);
00145
00146 if (fork_result)
00147 {
00148 parent (this->getpid ());
00149 return this->getpid ();
00150 }
00151 return ACE_INVALID_PID;
00152
00153 #elif defined (CHORUS)
00154 // This only works if we exec. Chorus does not really support
00155 // forking.
00156 if (ACE_BIT_ENABLED (options.creation_flags (),
00157 ACE_Process_Options::NO_EXEC))
00158 ACE_NOTSUP_RETURN (ACE_INVALID_PID);
00159
00160 // These are all currently unsupported.
00161 if (options.get_stdin () != ACE_INVALID_HANDLE)
00162 ACE_NOTSUP_RETURN (ACE_INVALID_PID);
00163 if (options.get_stdout () != ACE_INVALID_HANDLE)
00164 ACE_NOTSUP_RETURN (ACE_INVALID_PID);
00165 if (options.get_stderr () != ACE_INVALID_HANDLE)
00166 ACE_NOTSUP_RETURN (ACE_INVALID_PID);
00167 if (options.working_directory () != 0)
00168 ACE_NOTSUP_RETURN (ACE_INVALID_PID);
00169
00170 if (options.env_argv ()[0] == 0)
00171 // command-line args
00172 this->child_id_ = ACE_OS::execvp (options.process_name (),
00173 options.command_line_argv ());
00174 else
00175 {
00176 // Add the new environment variables to the environment context
00177 // of the context before doing an <execvp>.
00178 for (char *const *user_env = options.env_argv ();
00179 *user_env != 0;
00180 user_env++)
00181 if (ACE_OS::putenv (*user_env) != 0)
00182 return ACE_INVALID_PID;
00183
00184 // Now the forked process has both inherited variables and the
00185 // user's supplied variables.
00186 this->child_id_ = ACE_OS::execvp (options.process_name (),
00187 options.command_line_argv ());
00188 }
00189
00190 return this->child_id_;
00191 #else /* ACE_WIN32 */
00192 // Fork the new process.
00193 this->child_id_ = ACE::fork (options.process_name (),
00194 options.avoid_zombies ());
00195
00196 if (this->child_id_ == 0)
00197 {
00198 # if !defined (ACE_LACKS_SETPGID)
00199 // If we're the child and the options specified a non-default
00200 // process group, try to set our pgid to it. This allows the
00201 // <ACE_Process_Manager> to wait for processes by their
00202 // process-group.
00203 if (options.getgroup () != ACE_INVALID_PID
00204 && ACE_OS::setpgid (0,
00205 options.getgroup ()) < 0)
00206 ACE_ERROR ((LM_ERROR,
00207 ACE_LIB_TEXT ("%p.\n"),
00208 ACE_LIB_TEXT ("ACE_Process::spawn: setpgid failed.")));
00209 # endif /* ACE_LACKS_SETPGID */
00210
00211 # if !defined (ACE_LACKS_SETREGID)
00212 if (options.getrgid () != (uid_t) -1
00213 || options.getegid () != (uid_t) -1)
00214 if (ACE_OS::setregid (options.getrgid (),
00215 options.getegid ()) == -1)
00216 ACE_ERROR ((LM_ERROR,
00217 ACE_LIB_TEXT ("%p.\n"),
00218 ACE_LIB_TEXT ("ACE_Process::spawn: setregid failed.")));
00219 # endif /* ACE_LACKS_SETREGID */
00220
00221 # if !defined (ACE_LACKS_SETREUID)
00222 // Set user and group id's.
00223 if (options.getruid () != (uid_t) -1
00224 || options.geteuid () != (uid_t) -1)
00225 if (ACE_OS::setreuid (options.getruid (),
00226 options.geteuid ()) == -1)
00227 ACE_ERROR ((LM_ERROR,
00228 ACE_LIB_TEXT ("%p.\n"),
00229 ACE_LIB_TEXT ("ACE_Process::spawn: setreuid failed.")));
00230 # endif /* ACE_LACKS_SETREUID */
00231
00232 this->child (ACE_OS::getppid ());
00233 }
00234 else if (this->child_id_ != -1)
00235 this->parent (this->child_id_);
00236
00237 // If we're not supposed to exec, return the process id.
00238 if (ACE_BIT_ENABLED (options.creation_flags (),
00239 ACE_Process_Options::NO_EXEC))
00240 return this->child_id_;
00241
00242 switch (this->child_id_)
00243 {
00244 case -1:
00245 // Error.
00246 return ACE_INVALID_PID;
00247 case 0:
00248 // Child process...exec the
00249 {
00250 if (options.get_stdin () != ACE_INVALID_HANDLE
00251 && ACE_OS::dup2 (options.get_stdin (),
00252 ACE_STDIN) == -1)
00253 ACE_OS::exit (errno);
00254 else if (options.get_stdout () != ACE_INVALID_HANDLE
00255 && ACE_OS::dup2 (options.get_stdout (),
00256 ACE_STDOUT) == -1)
00257 ACE_OS::exit (errno);
00258 else if (options.get_stderr () != ACE_INVALID_HANDLE
00259 && ACE_OS::dup2 (options.get_stderr (),
00260 ACE_STDERR) == -1)
00261 ACE_OS::exit (errno);
00262
00263 // close down unneeded descriptors
00264 ACE_OS::close (options.get_stdin ());
00265 ACE_OS::close (options.get_stdout ());
00266 ACE_OS::close (options.get_stderr ());
00267
00268 // If we must, set the working directory for the child
00269 // process.
00270 if (options.working_directory () != 0)
00271 ACE_OS::chdir (options.working_directory ());
00272 // Should check for error here!
00273
00274 // Child process executes the command.
00275 int result = 0;
00276
00277 if (options.inherit_environment ())
00278 {
00279 // Add the new environment variables to the environment
00280 // context of the context before doing an <execvp>.
00281 for (char *const *user_env = options.env_argv ();
00282 *user_env != 0;
00283 user_env++)
00284 if (ACE_OS::putenv (*user_env) != 0)
00285 return ACE_INVALID_PID;
00286
00287 // Now the forked process has both inherited variables and
00288 // the user's supplied variables.
00289 result = ACE_OS::execvp (options.process_name (),
00290 options.command_line_argv ());
00291 }
00292 else
00293 {
00294 #if defined (ghs)
00295 // GreenHills 1.8.8 (for VxWorks 5.3.x) can't compile this
00296 // code. Processes aren't supported on VxWorks anyways.
00297 ACE_NOTSUP_RETURN (ACE_INVALID_PID);
00298 #else
00299 result = ACE_OS::execve (options.process_name (),
00300 options.command_line_argv (),
00301 options.env_argv ());
00302 # endif /* ghs */
00303 }
00304 if (result == -1)
00305 {
00306 // If the execv fails, this child needs to exit.
00307
00308 // Exit with the errno so that the calling process can
00309 // catch this and figure out what went wrong.
00310 ACE_OS::_exit (errno);
00311 }
00312 // ... otherwise, this is never reached.
00313 return 0;
00314 }
00315 default:
00316 // Server process. The fork succeeded.
00317 return this->child_id_;
00318 }
00319 #endif /* ACE_WIN32 */
00320 }
|
|
|
Terminate the process abruptly using <ACE::terminate_process>. This call doesn't give the process a chance to cleanup, so use it with caution... Definition at line 62 of file Process.i. References getpid, and ACE::terminate_process.
00063 {
00064 if (this->getpid () != -1)
00065 return ACE::terminate_process (this->getpid ());
00066 else
00067 return -1;
00068 }
|
|
|
Called by a <Process_Manager> that is removing this Process from its table of managed Processes. Default is to do nothing.
Reimplemented in ACE_Managed_Process. Definition at line 335 of file Process.cpp. Referenced by ACE_Process_Manager::remove_proc.
00336 {
00337 // nothing to do
00338 }
|
|
||||||||||||
|
Timed wait for the process we've created to exit. A return value of -1 indicates that the something failed; 0 indicates that a timeout occurred. Otherwise, the child's process id is returned. If <status> != 0, it points to an integer where the function stores the child's exit status. NOTE: on UNIX platforms this function uses <ualarm>, i.e., it overwrites any existing alarm. In addition, it steals all <SIGCHLD>s during the timeout period, which will break another <ACE_Process_Manager> in the same process that's expecting <SIGCHLD> to kick off process reaping. Definition at line 357 of file Process.cpp. References ACE_exitcode, ACE_INVALID_PID, ACE_SignalHandler, ETIME, exit_code_, getpid, ACE_Time_Value::max_time, ACE_Time_Value::msec, pid_t, process_info_, ACE_Sig_Action::register_action, ACE_OS::set_errno_to_last_error, SIGCHLD, ACE_OS::sleep, ACE_Countdown_Time::update, wait, ACE_OS::waitpid, WNOHANG, and ACE_Time_Value::zero.
00359 {
00360 #if defined (ACE_WIN32)
00361 // Don't try to get the process exit status if wait failed so we can
00362 // keep the original error code intact.
00363 switch (::WaitForSingleObject (process_info_.hProcess,
00364 tv.msec ()))
00365 {
00366 case WAIT_OBJECT_0:
00367 // The error status of <GetExitCodeProcess> is nonetheless not
00368 // tested because we don't know how to return the value.
00369 ::GetExitCodeProcess (process_info_.hProcess,
00370 &this->exit_code_);
00371 if (status != 0)
00372 *status = this->exit_code_;
00373 return this->getpid ();
00374 case WAIT_TIMEOUT:
00375 errno = ETIME;
00376 return 0;
00377 default:
00378 ACE_OS::set_errno_to_last_error ();
00379 return -1;
00380 }
00381 #else /* ACE_WIN32 */
00382 if (tv == ACE_Time_Value::zero)
00383 {
00384 pid_t retv =
00385 ACE_OS::waitpid (this->child_id_,
00386 &this->exit_code_,
00387 WNOHANG);
00388 if (status != 0)
00389 *status = this->exit_code_;
00390
00391 return retv;
00392 }
00393
00394 if (tv == ACE_Time_Value::max_time)
00395 return this->wait (status);
00396
00397 // Need to wait but limited to specified time.
00398 // Force generation of SIGCHLD, even though we don't want to
00399 // catch it - just need it to interrupt the sleep below.
00400 // If this object has a reactor set, assume it was given at
00401 // open(), and there's already a SIGCHLD action set, so no
00402 // action is needed here.
00403 ACE_Sig_Action old_action;
00404 ACE_Sig_Action do_sigchld ((ACE_SignalHandler)sigchld_nop);
00405 do_sigchld.register_action (SIGCHLD, &old_action);
00406
00407 pid_t pid;
00408 ACE_Time_Value tmo (tv); // Need one we can change
00409 for (ACE_Countdown_Time time_left (&tmo); ; time_left.update ())
00410 {
00411 pid = ACE_OS::waitpid (this->getpid (),
00412 &this->exit_code_,
00413 WNOHANG);
00414 if (status != 0)
00415 *status = this->exit_code_;
00416
00417 if (pid > 0 || pid == ACE_INVALID_PID)
00418 break; // Got a child or an error - all done
00419
00420 // pid 0, nothing is ready yet, so wait.
00421 // Do a sleep (only this thread sleeps) til something
00422 // happens. This relies on SIGCHLD interrupting the sleep.
00423 // If SIGCHLD isn't delivered, we'll need to do something
00424 // with sigaction to force it.
00425 if (-1 == ACE_OS::sleep (tmo) && errno == EINTR)
00426 continue;
00427 // Timed out
00428 pid = 0;
00429 break;
00430 }
00431
00432 // Restore the previous SIGCHLD action if it was changed.
00433 old_action.register_action (SIGCHLD);
00434
00435 return pid;
00436 #endif /* ACE_WIN32 */
00437 }
|
|
||||||||||||
|
Wait for the process we've created to exit. If <status> != 0, it points to an integer where the function store the exit status of child process to. If <wait_options> == <WNOHANG> then return 0 and don't block if the child process hasn't exited yet. A return value of -1 represents the <wait> operation failed, otherwise, the child process id is returned. Definition at line 35 of file Process.i. References ACE_exitcode, exit_code_, pid_t, process_info_, and ACE_OS::wait. Referenced by ACE_Process_Manager::wait, and wait.
00037 {
00038 pid_t retv =
00039 ACE_OS::wait (this->getpid (),
00040 &this->exit_code_,
00041 wait_options
00042 #if defined (ACE_WIN32)
00043 , process_info_.hProcess
00044 #endif /* ACE_WIN32 */
00045 );
00046 if (status != 0)
00047 *status = this->exit_code_;
00048
00049 return retv;
00050 }
|
|
|
|
|
|
Handle duplicates made for the child process.
Definition at line 557 of file Process.h. Referenced by close_dup_handles, and spawn. |
|
|
Definition at line 552 of file Process.h. Referenced by exit_code, return_value, and wait. |
|
|
Set of handles that were passed to the child process.
Definition at line 555 of file Process.h. Referenced by close_passed_handles, and spawn. |
|
|
|
1.2.14 written by Dimitri van Heesch,
© 1997-2002