コード例 #1
0
ファイル: process.cpp プロジェクト: akostrikov/ATCD
// This is just to test the direct usage of CreateProcess.  I use this
// occasionally as a sanity check when ACE_Process breaks.
static void
win32_test_ls (void)
{
    PROCESS_INFORMATION process_info;
    ACE_TEXT_STARTUPINFO startup_info;
    ACE_OS::memset ((void *) &startup_info,
                    0,
                    sizeof startup_info);
    ACE_OS::memset ((void *) &process_info,
                    0,
                    sizeof process_info);
    startup_info.cb = sizeof startup_info;
    startup_info.dwFlags = STARTF_USESTDHANDLES;

    ACE_HANDLE std_out = ACE_STDOUT;

    if (!::DuplicateHandle (::GetCurrentProcess (),
                            std_out,
                            ::GetCurrentProcess (),
                            &startup_info.hStdOutput,
                            0,
                            TRUE,
                            DUPLICATE_SAME_ACCESS))
    {
        ACE_ERROR ((LM_ERROR,
                    ACE_TEXT ("%p duplicate failed.\n"),
                    ACE_TEXT ("test_ls")));
        return;
    }

    ACE_TCHAR cmd_line[8];
    ACE_OS::strncpy (cmd_line, ACE_TEXT ("-a"), sizeof (cmd_line));
    BOOL fork_result =
        ACE_TEXT_CreateProcess (ACE_TEXT ("c:\\Utils\\bin\\ls.exe"),
                                cmd_line,
                                0, // No process attributes.
                                0, // No thread attributes.
                                TRUE, // Allow handle inheritance.
                                0, // CREATE_NEW_CONSOLE, // Create a new console window.
                                0,
                                0, // Current directory to start in.
                                &startup_info,
                                &process_info);

    ::CloseHandle (startup_info.hStdOutput);

    if (fork_result == 0)
        ACE_ERROR ((LM_ERROR,
                    ACE_TEXT ("%p CreateProcess failed.\n"),
                    ACE_TEXT ("test_ls")));
    else
    {
        ::WaitForSingleObject (process_info.hProcess,
                               INFINITE);
        ACE_DEBUG ((LM_ERROR, ACE_TEXT ("ls succeeded.\n")));
    }
}
コード例 #2
0
ファイル: Process.cpp プロジェクト: Bootz/SkyFire_one
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.
  ACE_Handle_Set *set_p = 0;
  if (options.dup_handles (this->dup_handles_))
    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,
  // unless the command line runs out of space.
  // Note that we're using the knowledge that all the options, argvs, etc.
  // passed to the options are all sitting in the command_line_buf. Any
  // call to get the argv then splits them out. So, regardless of the
  // platform, tack them all onto the command line buf and take it
  // from there.
  if (set_p && !ACE_BIT_ENABLED (options.creation_flags (),
                                 ACE_Process_Options::NO_EXEC))
    {
      int maxlen = 0;
      ACE_TCHAR *cmd_line_buf = options.command_line_buf (&maxlen);
      size_t max_len = static_cast<size_t> (maxlen);
      size_t curr_len = ACE_OS::strlen (cmd_line_buf);
      ACE_Handle_Set_Iterator h_iter (*set_p);
      // Because the length of the to-be-formatted +H option is not
      // known, and we don't have a snprintf, guess at the space
      // needed (20 chars), and use that as a limit.
      for (ACE_HANDLE h = h_iter ();
           h != ACE_INVALID_HANDLE && curr_len + 20 < max_len;
           h = h_iter ())
        {
#if defined (ACE_WIN32)
# if defined (ACE_WIN64)
          curr_len += ACE_OS::sprintf (&cmd_line_buf[curr_len],
                                       ACE_TEXT (" +H %I64p"),
                                       h);
# else
          curr_len += ACE_OS::sprintf (&cmd_line_buf[curr_len],
                                       ACE_TEXT (" +H %p"),
                                       h);
# endif  /* ACE_WIN64 */
#else
          curr_len += ACE_OS::sprintf (&cmd_line_buf[curr_len],
                                       ACE_TEXT (" +H %d"),
                                       h);
#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(),
                            options.get_process_attributes(),  // must be NULL in CE
                            options.get_thread_attributes(),   // must be NULL in CE
                            options.handle_inheritance(),      // must be false in CE
                            options.creation_flags(),          // must be NULL in CE
                            options.env_buf(),                 // environment variables, must be NULL in CE
                            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 ();
# if defined (ACE_HAS_WCHAR) && !defined (ACE_USES_WCHAR)
  wchar_t* wenv_buf = 0;
  if (options.use_unicode_environment ())
    {
      wenv_buf = this->convert_env_buffer (options.env_buf ());
      env_buf = wenv_buf;
      flags |= CREATE_UNICODE_ENVIRONMENT;
    }
# endif

  BOOL fork_result =
    ACE_TEXT_CreateProcess (0,
                            options.command_line_buf (),
                            options.get_process_attributes (),
                            options.get_thread_attributes (),
                            options.handle_inheritance (),
                            flags,
                            env_buf, // environment variables
                            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;
  // Save STD file descriptors and redirect
  if (options.get_stdin () != ACE_INVALID_HANDLE) {
    if ((saved_stdin = ACE_OS::dup (ACE_STDIN)) == -1 && errno != EBADF)
      ACE_OS::exit (errno);
    if (ACE_OS::dup2 (options.get_stdin (), ACE_STDIN) == -1)
      ACE_OS::exit (errno);
  }
  if (options.get_stdout () != ACE_INVALID_HANDLE) {
    if ((saved_stdout = ACE_OS::dup (ACE_STDOUT)) == -1 && errno != EBADF)
      ACE_OS::exit (errno);
    if (ACE_OS::dup2 (options.get_stdout (), ACE_STDOUT) == -1)
      ACE_OS::exit (errno);
  }
  if (options.get_stderr () != ACE_INVALID_HANDLE) {
    if ((saved_stderr = ACE_OS::dup (ACE_STDERR)) == -1 && errno != EBADF)
      ACE_OS::exit (errno);
    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 (),
                options.command_line_argv ());
      // 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)
      ACE_OS::close (ACE_STDIN);
    else
      ACE_OS::dup2 (saved_stdin, ACE_STDIN);
  }
  if (options.get_stdout () != ACE_INVALID_HANDLE) {
    if (saved_stdout == -1)
      ACE_OS::close (ACE_STDOUT);
    else
      ACE_OS::dup2 (saved_stdout, ACE_STDOUT);
  }
  if (options.get_stderr () != ACE_INVALID_HANDLE) {
    if (saved_stderr == -1)
      ACE_OS::close (ACE_STDERR);
    else
      ACE_OS::dup2 (saved_stderr, ACE_STDERR);
  }

  return this->child_id_;
#elif defined (ACE_VXWORKS) && 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;
  // Save STD file descriptors and redirect
  if (options.get_stdin () != ACE_INVALID_HANDLE) {
    if ((saved_stdin = ACE_OS::dup (ACE_STDIN)) == -1 && errno != EBADF)
      ACE_OS::exit (errno);
    if (ACE_OS::dup2 (options.get_stdin (), ACE_STDIN) == -1)
      ACE_OS::exit (errno);
  }
  if (options.get_stdout () != ACE_INVALID_HANDLE) {
    if ((saved_stdout = ACE_OS::dup (ACE_STDOUT)) == -1 && errno != EBADF)
      ACE_OS::exit (errno);
    if (ACE_OS::dup2 (options.get_stdout (), ACE_STDOUT) == -1)
      ACE_OS::exit (errno);
  }
  if (options.get_stderr () != ACE_INVALID_HANDLE) {
    if ((saved_stderr = ACE_OS::dup (ACE_STDERR)) == -1 && errno != EBADF)
      ACE_OS::exit (errno);
    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)
  wchar_t * const *wargv = options.command_line_argv ();
  size_t vcount, i;
  for (vcount = 0; wargv[vcount] != 0; ++vcount)
    ;
  char **procargv = new char *[vcount + 1];  // Need 0 at the end
  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 ())
    {
      wargv = options.env_argv ();
      for (vcount = 0; wargv[vcount] != 0; ++vcount)
        ;
      procenv = new char *[vcount + 1];  // Need 0 at the end
      procenv[vcount] = 0;
      for (i = 0; i < vcount; ++i)
        procenv[i] = ACE_Wide_To_Ascii::convert (wargv[i]);
    }
# else
  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,
                                200,          // priority
                                0x10000,      // uStackSize
                                0,            // options
                                VX_FP_TASK);  // taskOptions
  int my_errno_ = errno;
  if (this->child_id_ == ERROR) {
      // 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)
      ACE_OS::close (ACE_STDIN);
    else
      ACE_OS::dup2 (saved_stdin, ACE_STDIN);
  }
  if (options.get_stdout () != ACE_INVALID_HANDLE) {
    if (saved_stdout == -1)
      ACE_OS::close (ACE_STDOUT);
    else
      ACE_OS::dup2 (saved_stdout, ACE_STDOUT);
  }
  if (options.get_stderr () != ACE_INVALID_HANDLE) {
    if (saved_stderr == -1)
      ACE_OS::close (ACE_STDERR);
    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)
      // If we're the child and the options specified a non-default
      // process group, try to set our pgid to it.  This allows the
      // <ACE_Process_Manager> to wait for processes by their
      // process-group.
      if (options.getgroup () != ACE_INVALID_PID
          && ACE_OS::setpgid (0,
                              options.getgroup ()) < 0)
        {
#if !defined (ACE_HAS_THREADS)
          // We can't emit this log message because ACE_ERROR(), etc.
          // will invoke async signal unsafe functions, which results
          // in undefined behavior in threaded programs.
          ACE_ERROR ((LM_ERROR,
                      ACE_TEXT ("%p.\n"),
                      ACE_TEXT ("ACE_Process::spawn: setpgid failed.")));
#endif
        }
# endif /* ACE_LACKS_SETPGID */

# if !defined (ACE_LACKS_SETREGID)
      if (options.getrgid () != (uid_t) -1
          || options.getegid () != (uid_t) -1)
        if (ACE_OS::setregid (options.getrgid (),
                              options.getegid ()) == -1)
          {
#if !defined (ACE_HAS_THREADS)
            // We can't emit this log message because ACE_ERROR(), etc.
            // will invoke async signal unsafe functions, which results
            // in undefined behavior in threaded programs.
            ACE_ERROR ((LM_ERROR,
                        ACE_TEXT ("%p.\n"),
                        ACE_TEXT ("ACE_Process::spawn: setregid failed.")));
#endif
          }
# endif /* ACE_LACKS_SETREGID */

# if !defined (ACE_LACKS_SETREUID)
      // Set user and group id's.
      if (options.getruid () != (uid_t) -1
          || options.geteuid () != (uid_t) -1)
        if (ACE_OS::setreuid (options.getruid (),
                              options.geteuid ()) == -1)
          {
#if !defined (ACE_HAS_THREADS)
            // We can't emit this log message because ACE_ERROR(), etc.
            // will invoke async signal unsafe functions, which results
            // in undefined behavior in threaded programs.
            ACE_ERROR ((LM_ERROR,
                        ACE_TEXT ("%p.\n"),
                        ACE_TEXT ("ACE_Process::spawn: setreuid failed.")));
#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:
      // Error.
      return ACE_INVALID_PID;
    case 0:
      // Child process...exec the
      {
        if (options.get_stdin () != ACE_INVALID_HANDLE
            && ACE_OS::dup2 (options.get_stdin (),
                             ACE_STDIN) == -1)
          ACE_OS::exit (errno);
        else if (options.get_stdout () != ACE_INVALID_HANDLE
                 && ACE_OS::dup2 (options.get_stdout (),
                                  ACE_STDOUT) == -1)
          ACE_OS::exit (errno);
        else if (options.get_stderr () != ACE_INVALID_HANDLE
                 && 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 (!options.handle_inheritance ())
          {
            // Set close-on-exec for all FDs except standard handles
            for (int i = ACE::max_handles () - 1; i >= 0; i--)
              {
                if (i == ACE_STDIN || i == ACE_STDOUT || i == ACE_STDERR)
                  continue;
                ACE_OS::fcntl (i, F_SETFD, FD_CLOEXEC);
              }
          }

        // 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
        // process will either exec() or exit() shortly.
# 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)
          ;
        char **procargv = new char *[vcount + 1];  // Need 0 at the end
        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)
          ;
        char **procenv = new char *[vcount + 1];  // Need 0 at the end
        procenv[vcount] = 0;
        for (i = 0; i < vcount; ++i)
          procenv[i] = ACE_Wide_To_Ascii::convert (wargv[i]);
# else
        const char *procname = options.process_name ();
        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
            // context of the context before doing an <execvp>.
            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);
          }
        else
          {
            result = ACE_OS::execve (procname, procargv, procenv);
          }
        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);
          }
        // ... otherwise, this is never reached.
        return 0;
      }
    default:
      // Server process.  The fork succeeded.
      return this->child_id_;
    }
#endif /* ACE_WIN32 */
}
コード例 #3
0
ファイル: process.cpp プロジェクト: akostrikov/ATCD
static void
win32_spawn_environment_process (void)
{
    PROCESS_INFORMATION process_info;
    ACE_TEXT_STARTUPINFO startup_info;
    ACE_OS::memset ((void *) &startup_info,
                    0,
                    sizeof startup_info);
    ACE_OS::memset ((void *) &process_info,
                    0,
                    sizeof process_info);
    startup_info.cb = sizeof (startup_info);
    startup_info.dwFlags = STARTF_USESTDHANDLES;

    ACE_HANDLE std_in = ACE_STDIN;
    ACE_HANDLE std_out = ACE_STDOUT;
    ACE_HANDLE std_err = ACE_STDERR;

    if (!::DuplicateHandle (::GetCurrentProcess(),
                            std_out,
                            ::GetCurrentProcess(),
                            &startup_info.hStdOutput,
                            0,
                            TRUE,
                            DUPLICATE_SAME_ACCESS))
    {
        ACE_ERROR ((LM_ERROR,
                    ACE_TEXT ("%p duplicate failed.\n"),
                    ACE_TEXT ("spawn_environment_process")));
        return;
    }

    if (!::DuplicateHandle (::GetCurrentProcess(),
                            std_err,
                            ::GetCurrentProcess(),
                            &startup_info.hStdError,
                            0,
                            TRUE,
                            DUPLICATE_SAME_ACCESS))
    {
        ACE_ERROR ((LM_ERROR,
                    ACE_TEXT ("%p duplicate failed.\n"),
                    ACE_TEXT ("spawn_environment_process")));
        return;
    }

    if (!::DuplicateHandle (::GetCurrentProcess(),
                            std_in,
                            ::GetCurrentProcess(),
                            &startup_info.hStdInput,
                            0,
                            TRUE,
                            DUPLICATE_SAME_ACCESS))
    {
        ACE_ERROR ((LM_ERROR,
                    ACE_TEXT ("%p duplicate failed.\n"),
                    ACE_TEXT ("spawn_environment_process")));
        return;
    }

    // Normally, this would be just GetEnvironmentStrings, but it
    // doesn't follow the same rules as the rest of the Win32 API
    ACE_TCHAR *existing_environment = ACE_OS::getenvstrings ();
    ACE_TCHAR environment[10240];
    ACE_OS::sprintf (environment,
                     ACE_TEXT("ACE_PROCESS_TEST=%s"),
                     environment_string);

    int size = 0;
    while (existing_environment[size] != '\0')
        size +=
            ACE_Utils::truncate_cast<int> (
                ACE_OS::strlen (existing_environment + size) + 1);

    ACE_OS::memcpy (environment + (ACE_OS::strlen (environment) + 1),
                    existing_environment,
                    size);

    ACE_TEXT_FreeEnvironmentStrings (existing_environment);

    ACE_TCHAR cmd_line[16];
    ACE_OS::strncpy (cmd_line, ACE_TEXT ("process -g"), sizeof (cmd_line));
    BOOL fork_result =
        ACE_TEXT_CreateProcess (ACE_TEXT ("d:\\harrison\\ACE_wrappers\\examples\\OS\\Process\\process.exe"),
                                cmd_line,
                                0, // No process attributes.
                                0, // No thread attributes.
                                TRUE, // Allow handle inheritance.
                                0, // CREATE_NEW_CONSOLE, // Create a new console window.
                                environment, // Environment.
                                //"d:\\harrison\\ACE_wrappers\\examples\\OS\\Process\\",
                                0,
                                &startup_info,
                                &process_info);

    ::CloseHandle (startup_info.hStdOutput);
    ::CloseHandle (startup_info.hStdError);

    if (fork_result == 0)
        ACE_ERROR ((LM_ERROR,
                    ACE_TEXT ("%p.\n"),
                    ACE_TEXT ("spawn_environment_process")));
    else
    {
        ::WaitForSingleObject (process_info.hProcess,
                               INFINITE);
        ACE_DEBUG ((LM_ERROR,
                    ACE_TEXT ("spawn_environment_process succeeded.\n")));
    }
}
コード例 #4
0
ファイル: OS_NS_unistd.cpp プロジェクト: 16898500/SkyFireEMU
pid_t
ACE_OS::fork_exec (ACE_TCHAR *argv[])
{
# if defined (ACE_WIN32)

  ACE_TCHAR *buf = 0;
  ACE_Auto_Basic_Array_Ptr<ACE_TCHAR> safe_ptr (buf);
  if (ACE_OS::argv_to_string (argv, buf) != -1)
    {
      PROCESS_INFORMATION process_info;
#   if !defined (ACE_HAS_WINCE)
      ACE_TEXT_STARTUPINFO startup_info;
      ACE_OS::memset ((void *) &startup_info,
                      0,
                      sizeof startup_info);
      startup_info.cb = sizeof startup_info;

      if (ACE_TEXT_CreateProcess (0,
                                  buf,
                                  0, // No process attributes.
                                  0,  // No thread attributes.
                                  TRUE, // Allow handle inheritance.
                                  0, // Don't create a new console window.
                                  0, // No environment.
                                  0, // No current directory.
                                  &startup_info,
                                  &process_info))
#   else
      if (ACE_TEXT_CreateProcess (0,
                                  buf,
                                  0, // No process attributes.
                                  0,  // No thread attributes.
                                  FALSE, // Can's inherit handles on CE
                                  0, // Don't create a new console window.
                                  0, // No environment.
                                  0, // No current directory.
                                  0, // Can't use startup info on CE
                                  &process_info))
#   endif /* ! ACE_HAS_WINCE */
        {
          // Free resources allocated in kernel.
          ACE_OS::close (process_info.hThread);
          ACE_OS::close (process_info.hProcess);
          // Return new process id.
          return process_info.dwProcessId;
        }
    }

  // CreateProcess failed.
  return -1;
# else
      pid_t const result = ACE_OS::fork ();

#   if defined (ACE_USES_WCHAR)
      // Wide-char builds need to convert the command-line args to
      // narrow char strings for execv ().
      char **cargv = 0;
      int arg_count;
#   endif /* ACE_HAS_WCHAR */

      switch (result)
        {
        case -1:
          // Error.
          return -1;
        case 0:
          // Child process.
#   if defined (ACE_USES_WCHAR)
          for (arg_count = 0; argv[arg_count] != 0; ++arg_count)
            ;
          ++arg_count;    // Need a 0-pointer end-of-array marker
          ACE_NEW_NORETURN (cargv, char*[arg_count]);
          if (cargv == 0)
            ACE_OS::exit (errno);
          --arg_count;    // Back to 0-indexed
          cargv[arg_count] = 0;
          while (--arg_count >= 0)
            cargv[arg_count] = ACE_Wide_To_Ascii::convert (argv[arg_count]);
          // Don't worry about freeing the cargv or the strings it points to.
          // Either the process will be replaced, or we'll exit.
          if (ACE_OS::execv (cargv[0], cargv) == -1)
            ACE_OS::exit (errno);
#   else
          if (ACE_OS::execv (argv[0], argv) == -1)
            {
              // The OS layer should not print stuff out
              // ACE_ERROR ((LM_ERROR,
              //             "%p Exec failed\n"));

              // If the execv fails, this child needs to exit.
              ACE_OS::exit (errno);
            }
#   endif /* ACE_HAS_WCHAR */

        default:
          // Server process.  The fork succeeded.
          return result;
        }
# endif /* ACE_WIN32 */
}
コード例 #5
0
pid_t
ACE_OS::fork_exec (ACE_TCHAR *argv[])
{
# if defined (ACE_WIN32)
  ACE_TCHAR *buf;

  if (ACE_OS::argv_to_string (argv, buf) != -1)
    {
      PROCESS_INFORMATION process_info;
#   if !defined (ACE_HAS_WINCE)
      ACE_TEXT_STARTUPINFO startup_info;
      ACE_OS::memset ((void *) &startup_info,
                      0,
                      sizeof startup_info);
      startup_info.cb = sizeof startup_info;

      if (ACE_TEXT_CreateProcess (0,
                                  buf,
                                  0, // No process attributes.
                                  0,  // No thread attributes.
                                  TRUE, // Allow handle inheritance.
                                  0, // Don't create a new console window.
                                  0, // No environment.
                                  0, // No current directory.
                                  &startup_info,
                                  &process_info))
#   else
      if (ACE_TEXT_CreateProcess (0,
                                  buf,
                                  0, // No process attributes.
                                  0,  // No thread attributes.
                                  FALSE, // Can's inherit handles on CE
                                  0, // Don't create a new console window.
                                  0, // No environment.
                                  0, // No current directory.
                                  0, // Can't use startup info on CE
                                  &process_info))
#   endif /* ! ACE_HAS_WINCE */
        {
          // Free resources allocated in kernel.
          ACE_OS::close (process_info.hThread);
          ACE_OS::close (process_info.hProcess);
          // Return new process id.
          delete [] buf;
          return process_info.dwProcessId;
        }
    }

  // CreateProcess failed.
  return -1;
# elif defined (CHORUS)
  return ACE_OS::execv (argv[0], argv);
# else
      pid_t result = ACE_OS::fork ();

      switch (result)
        {
        case -1:
          // Error.
          return -1;
        case 0:
          // Child process.
          if (ACE_OS::execv (argv[0], argv) == -1)
            {
              // The OS layer should not print stuff out
              // ACE_ERROR ((LM_ERROR,
              //             "%p Exec failed\n"));

              // If the execv fails, this child needs to exit.
              ACE_OS::exit (errno);
            }
        default:
          // Server process.  The fork succeeded.
          return result;
        }
# endif /* ACE_WIN32 */
}