예제 #1
0
/* \brief Just runs automatic tests

Function sends a number of datagrams, spawns child thread or process and
tries to receive at least one datagram.
\retval 0 datagram was received
\retval -1 datagram was not received
*/
int run_auto_test (const ACE_TCHAR *prog_name)
{
#if defined (ACE_HAS_PROCESS_SPAWN)
  ACE_DEBUG ((LM_INFO, ACE_TEXT ("Running auto_tests in process mode\n")));

  ACE_Process_Options opts;
  pid_t child_pid;
  opts.command_line (ACE_TEXT ("%s -p %d -t %d -a -r"),
                     prog_name, dgram_port, dgram_recv_timeout.msec ());
  if ((child_pid = ACE_Process_Manager::instance ()->spawn (opts)) == -1)
    ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("spawn_n()")), -1);

#elif defined (ACE_HAS_THREADS)
  ACE_UNUSED_ARG (prog_name);
  ACE_DEBUG ((LM_INFO, ACE_TEXT ("Running auto_tests in thread mode\n")));
  if (ACE_Thread_Manager::instance ()->spawn (run_thread_receiver) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       ACE_TEXT ("%p\n"),
                       ACE_TEXT ("spawn_n ()")), -1);
#else
  ACE_ERROR_RETURN ((LM_ERROR,
                     ACE_TEXT ("Cannot run in auto_test mode without fork or threads.\n")),
                      -1);
#endif /* defined (ACE_HAS_PROCESS_SPAWN) */

  ACE_DEBUG ((LM_INFO,
              ACE_TEXT ("Sending datagrams on port %d in auto_test mode\n"),
              dgram_port));

  ACE_SOCK_Dgram_Bcast socket;

  if (socket.open (ACE_Addr::sap_any) != -1)
    {
      // send datagrams until child finishes
      while (1)
        {
          send_datagram (socket, dgrams_no--);
          ACE_Time_Value child_timeout (1);
#if defined (ACE_HAS_PROCESS_SPAWN)

          if (ACE_Process_Manager::instance ()->wait (child_pid,
                                                      child_timeout,
                                                      &receiver_exit_code) == child_pid)
            break;
#else /* ACE_HAS_THREADS */
          // sleep 1 second or wait for child thread
          child_timeout += ACE_OS::gettimeofday () ;
          if (ACE_Thread_Manager::instance ()->wait (&child_timeout) == 0)
            break;
#endif
        }
      socket.close ();
      ACE_DEBUG ((LM_INFO, ACE_TEXT ("Child finished with %d exit code\n"),
                  receiver_exit_code));
    }
  else
    ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"),
                       ACE_TEXT ("Cannot open broadcast socket")), -1);
  return (receiver_exit_code);
}
예제 #2
0
파일: Process_Test.cpp 프로젝트: annp/ACE
void
run_parent (bool inherit_files)
{
  ACE_TCHAR t[] = ACE_TEXT ("ace_testXXXXXX");

  // Create tempfile. This will be tested for inheritance.
  ACE_TCHAR tempfile[MAXPATHLEN + 1];

  if (ACE::get_temp_dir (tempfile, MAXPATHLEN - sizeof (t)) == -1)
    ACE_ERROR ((LM_ERROR, ACE_TEXT ("Could not get temp dir\n")));

  ACE_OS::strcat (tempfile, t);

  ACE_HANDLE file_handle = ACE_OS::mkstemp (tempfile);
  if (file_handle == ACE_INVALID_HANDLE)
    ACE_ERROR ((LM_ERROR, ACE_TEXT ("Could not get temp filename\n")));

  // Build child options
  ACE_TString exe_sub_dir;
  const char *subdir_env = ACE_OS::getenv ("ACE_EXE_SUB_DIR");
  if (subdir_env)
    {
      exe_sub_dir = ACE_TEXT_CHAR_TO_TCHAR (subdir_env);
      exe_sub_dir += ACE_DIRECTORY_SEPARATOR_STR;
    }

  ACE_Process_Options options;
  options.command_line (ACE_TEXT (".") ACE_DIRECTORY_SEPARATOR_STR
                        ACE_TEXT ("%sProcess_Test")
                        ACE_PLATFORM_EXE_SUFFIX
                        ACE_TEXT (" -c -h %d -f %s"),
                        exe_sub_dir.c_str(),
                        (int)inherit_files,
                        tempfile);
  options.handle_inheritance (inherit_files); /* ! */

  // Spawn child
  ACE_Process child;

  pid_t result = child.spawn (options);
  if (result == -1)
    ACE_ERROR ((LM_ERROR, ACE_TEXT ("Parent could NOT spawn child process\n")));
  else
    ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("Parent spawned child process with pid = %d.\n"),
              child.getpid ()));

  ACE_exitcode child_status;
  result = child.wait (&child_status);
  if (result == -1)
    ACE_ERROR ((LM_ERROR, ACE_TEXT ("Could NOT wait on child process\n")));
  else if (child_status == 0)
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("Child %d finished ok\n"),
                child.getpid ()));
  else
    ACE_ERROR ((LM_ERROR,
                ACE_TEXT ("Child %d finished with status %d\n"),
                child.getpid (), child_status));
}
예제 #3
0
파일: process.cpp 프로젝트: akostrikov/ATCD
static void
test_date (void)
{
    ACE_Process_Options options;
    options.command_line (DATE_PATH);

    // Try to create a new process running date.
    ACE_Process new_process;
    if (new_process.spawn (options) == -1)
    {
        int const error_number = ACE_OS::last_error ();
        ACE_ERROR ((LM_ERROR,
                    ACE_TEXT ("%p errno = %d.\n"),
                    ACE_TEXT ("test_date"),
                    error_number));
        return;
    }

    ACE_exitcode status;
    new_process.wait (&status);
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("Process exit with status %d\n"),
                status));
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("date succeeded.\n")));
}
예제 #4
0
파일: process.cpp 프로젝트: akostrikov/ATCD
// This shows how to set handles.
static void
test_more (void)
{
    ACE_HANDLE infile = ACE_OS::open (print_file, O_RDONLY);

    if (infile == ACE_INVALID_HANDLE)
    {
        ACE_ERROR ((LM_DEBUG, ACE_TEXT ("%p\n"), print_file));
        return;
    }

    ACE_Process new_process;
    ACE_Process_Options options;
    options.command_line (executable);
    options.set_handles (infile);

    if (new_process.spawn (options) == -1)
    {
        int const error_number = ACE_OS::last_error ();
        ACE_ERROR ((LM_ERROR,
                    ACE_TEXT ("%p errno = %d.\n"),
                    ACE_TEXT ("test_more"),
                    error_number));
    }

    ACE_exitcode status;
    new_process.wait (&status);
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("Process exit with status %d\n"),
                status));
    ACE_OS::close (infile);

    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("More succeeded.\n")));
}
예제 #5
0
static int
command_line_test (void)
{
  ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT ("Testing for last character of command line\n")));
  int result = 0;
  const ACE_TCHAR *command = ACE_TEXT ("test Hello");
  size_t command_len = ACE_OS::strlen (command);
  ACE_Process_Options options (1, command_len + 1);

#ifndef ACE_LACKS_VA_FUNCTIONS
  options.command_line (command);
#endif

  ACE_TCHAR * const *procargv = options.command_line_argv ();
  if (ACE_OS::strcmp (procargv [1], ACE_TEXT ("Hello")) != 0)
    {
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("command_line_test failed: expected \"%s\"; got \"%s\"\n"),
                  ACE_TEXT ("Hello"),
                  procargv [1]));
      result = 1;
    }
  return result;
}
예제 #6
0
int
test_setenv (void)
{
  int status = 0;
  ACE_Process_Options opts;
  ACE_TCHAR bigval[5010] = ACE_TEXT ("");
  for (int i = 0; i < 100; ++i)
    ACE_OS::strcat (bigval,
                    ACE_TEXT ("01234567890123456789012345678901234567890123456789"));
#ifndef ACE_LACKS_VA_FUNCTIONS
# if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
  const ACE_TCHAR *fmt = ACE_TEXT ("%ls");
# else
  const ACE_TCHAR *fmt = ACE_TEXT ("%s");
# endif

  if (0 != opts.setenv (ACE_TEXT ("A"), fmt, bigval))
    {
      status = errno;
      ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("setenv")));
    }
  else
    {
      size_t env_len = ACE_OS::strlen (opts.env_buf ());
      if (env_len != 5002)
        {
          status = 1;
          ACE_ERROR ((LM_ERROR,
                      ACE_TEXT ("setenv result should be 5002 chars, not %B\n"),
                      env_len));
        }
    }
#endif
  return status;
}
예제 #7
0
파일: process.cpp 프로젝트: akostrikov/ATCD
static void
test_setenv (const ACE_TCHAR *argv0)
{
    ACE_Process_Options options;
    //  options.setenv ("ACE_PROCESS_TEST", "here's a really large number: %u", 0 - 1);
    options.setenv (ACE_TEXT ("ACE_PROCESS_TEST= here's a large number %u"),
                    0 - 1);
    options.setenv (ACE_TEXT ("ACE_PROCESS_TEST2"), ACE_TEXT ("ophilli"));
#if defined (ACE_WIN32) || !defined (ACE_USES_WCHAR)
    options.command_line ("%s -g", argv0);
#else
    options.command_line ("%ls -g", argv0);
#endif
    ACE_Process process;
    if (process.spawn (options) == -1)
    {
        ACE_ERROR ((LM_ERROR,
                    ACE_TEXT ("%p.\n"),
                    ACE_TEXT ("test_setenv")));
        return;
    }

    ACE_exitcode status;
    process.wait (&status);
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("Process exit with status %d\n"),
                status));
}
예제 #8
0
파일: process.cpp 프로젝트: akostrikov/ATCD
static void
test_ls (void)
{
    ACE_Process_Options options;
#if defined (ACE_WIN32) || !defined (ACE_USES_WCHAR)
    options.command_line (ACE_TEXT ("%s -al"), LS_PATH);
#else
    options.command_line (ACE_TEXT ("%ls -al"), LS_PATH);
#endif
    ACE_Process new_process;
    if (new_process.spawn (options) == -1)
    {
        int error_number = ACE_OS::last_error ();
        ACE_ERROR ((LM_ERROR,
                    ACE_TEXT ("%p errno = %d.\n"),
                    ACE_TEXT ("test_ls"),
                    error_number));
    }

    ACE_exitcode status;
    new_process.wait (&status);
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("Process exit with status %d\n"),
                status));
}
예제 #9
0
int CC_Start_Cmd::execute(void)
{
    if (excep_)
    {
        ACE_OS::printf ("Exception: %s\n", excep_->_rep_id ());
        delete excep_;
        excep_ = 0;
        return 0; // CC_FAIL
    }

    ACE_OS::printf ("Executing start command (script file: %s)\n", cfg_name_);

    char cmd_line[1024];
    int success = ACE_OS::sprintf(&cmd_line[0], "%s -c %s",
                                  "./CC_client", cfg_name_);
    if(success>=1024 || success==-1)
        ACE_ERROR_RETURN((LM_ERROR, "Creation of process failed: %s\n",
                          cmd_line), 0);

    ACE_Process new_process;
    ACE_Process_Options options;
    options.command_line(ACE_TEXT_CHAR_TO_TCHAR(cmd_line));

    if(new_process.spawn(options) == -1)
    {
        ACE_ERROR_RETURN((LM_ERROR, "Creation of process failed: %C\n",
                          cmd_line), 0);
    }
    return 1; // CC_SUCCESS
}
예제 #10
0
파일: Dgram.cpp 프로젝트: DOCGroup/ACE_TAO
int
ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
  // Estabish call backs and socket names.

  port1 = argc > 1 ? ACE_OS::atoi (argv[1]) : ACE_DEFAULT_SERVER_PORT;
  const ACE_TCHAR *remotehost = argc > 2 ? argv[2] : ACE_DEFAULT_SERVER_HOST;
  const u_short port2 = argc > 3 ? ACE_OS::atoi (argv[3]) : port1 + 1;

  // Providing the fourth command line argument indicate we don't want
  // to spawn a new process.  On Win32, we use this to exec the new
  // program.
  if (argc > 4)
    run_test (port1, remotehost, port2, argv[4]);
  else
    {
      ACE_DEBUG ((LM_DEBUG,
                  "(%P|%t) local port = %d, remote host = %s, remote port = %d\n",
                  port1,
                  remotehost,
                  port2));

      ACE_Process_Options options;
      options.command_line (ACE_TEXT ("%s %d %s %d %c"),
                            argv[0],
                            port1,
                            remotehost,
                            port2,
                            'c');

      // This has no effect on NT and will spawn a process that exec
      // the above run_test function.
      options.creation_flags (ACE_Process_Options::NO_EXEC);

      ACE_Process new_process;
      switch (new_process.spawn (options))
        {
        case -1:
          return -1;

        case 0:
          run_test (port1,
                    remotehost,
                    port2,
                    ACE_TEXT("peer1"));
          break;

        default:
          run_test (port2,
                    remotehost,
                    port1,
                    ACE_TEXT("peer2"));
          new_process.wait ();
          break;
        }
    }
  return 0;
}
예제 #11
0
static pid_t
respawn_self (const ACE_TCHAR *myname,
              int iter,
              int exit_code)
{
  ACE_Process_Options options;
  options.command_line ("%s -c -i %d -e %d",
                        myname,
                        iter,
                        exit_code);
  return ACE_Process_Manager::instance ()->spawn (options);
}
예제 #12
0
int ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
  if (argc > 1)     // Running as a child.
    {
      ACE_OS::sleep (10);
    }
  else             // Running as a parent.
    {
      // Get the processwide process manager.
      ACE_Process_Manager* pm = ACE_Process_Manager::instance ();

      // Specify the options for the new processes
      // to be spawned.
      ACE_Process_Options options;
      options.command_line (ACE_TEXT ("%s a"), argv[0]);

      // Spawn two child processes.
      pid_t pids[NCHILDREN];
      pm->spawn_n (NCHILDREN, options, pids);

      // Destroy the first child.
      pm->terminate (pids[0]);

      // Wait for the child we just terminated.
      ACE_exitcode status;
      pm->wait (pids[0], &status);

      // Get the results of the termination.

#if !defined(ACE_WIN32)
      if (WIFSIGNALED (status) != 0)
        ACE_DEBUG ((LM_DEBUG,
                    ACE_TEXT ("%d died because of a signal ")
                    ACE_TEXT ("of type %d\n"),
                    pids[0], WTERMSIG (status)));
#else
      ACE_DEBUG
        ((LM_DEBUG,
          ACE_TEXT ("The process terminated with exit code %d\n"),
          status));
#endif /*ACE_WIN32*/

      // Wait for all (only one left) of the
      // children to exit.
      pm->wait (0);
    }

  return 0;
}
예제 #13
0
파일: imore.cpp 프로젝트: annp/ACE
static int
setup_unnamed_pipe (ACE_Process_Options &opt)
{
  // Create an unnamed pipe instance.
  ACE_Pipe pipe;

  // Check if the pipe is created successfully.
  if (pipe.open () == -1)
    ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "pipe.open"), -1);

  // Setting up pipe between parent and child process.  Use the pipe
  // as child process'es ACE_STDIN.  ACE_Process_Options will keep
  // copies (by dup) of fd's that we pass in.  Notice that we have to
  // specify child process to use ACE_STDOUT for output explicitly
  // because we'll close it down in the line after.  Child process
  // will use whatever we use to dup2 ACE_STDOUT as its stdout.
  opt.set_handles (pipe.read_handle (), ACE_STDOUT);

  // The previous keep a copy of original ACE_STDOUT fd, now we
  // can replace ACE_STDOUT of parent process to the pipe.
  ACE_OS::dup2 (pipe.write_handle (), ACE_STDOUT);

  // Don't forget to close the unused fd.
  pipe.close ();
  return 0;
}
예제 #14
0
int
launcher_rvgl::_launch(const std::string &host_id) {
    if (_running) return err_already_running;

    std::string dir = pref()->get<std::string>("advanced/rvgl_path", "");
    std::string params = pref()->get<std::string>("advanced/rvgl_cmdline", "");

    if (dir.empty()) {
        win_registry r(win_registry::id_dplay, "", "Re-Volt");
        dir = r.get<std::string>("Path", "");
        pref()->set("advanced/rvgl_path", dir.c_str());
    }

    std::string cmd(dir);
#ifdef WIN32
    cmd += "/rvgl.exe";
#else
    cmd += "/rvgl";
#endif
    cmd = "\"" + cmd + "\"";
    if (!params.empty()) cmd += " " + params;
    cmd += (host_id.empty() ? " -lobby" : " -lobby " + host_id);

    //printf("%s\n", cmd.c_str());
    ACE_DEBUG((LM_DEBUG, "launcher_rvgl: command line: %s\n",
              cmd.c_str()));

    // Launch options
    ACE_Process_Manager *pm = ACE_Process_Manager::instance();
    ACE_Process_Options opts;
    opts.working_directory(dir.c_str());
    opts.command_line(cmd.c_str());
    _rvgl_pid = pm->spawn(opts, this);
    ACE_DEBUG((LM_INFO, "launcher_rvgl: pid %d from thread %t, cmd: %s\n",
               _rvgl_pid, cmd.c_str()));
    if (_rvgl_pid == ACE_INVALID_PID) {
        ACE_ERROR((LM_ERROR, "launcher_rvgl: failed to launch: %s\n",
                  cmd.c_str()));
        return err_could_not_launch;
    }
    
    _running = true;
    
    return 0;
}
예제 #15
0
bool Service_Manager::run_realmd()
{
    ACE_ARGV realmd_args;
    realmd_args.add(this->args.argv()[0]);
    realmd_args.add("runrealmd");

    ACE_Process_Manager* pmgr = ACE_Process_Manager::instance();
    ACE_Process_Options pop;
    pop.command_line(realmd_args.argv());
    pid_t realmpid = pmgr->spawn(pop);
    if (realmpid == ACE_INVALID_PID)
        return false;

    ServiceInfo *si = new ServiceInfo(realmpid);
    this->svcs.insert(std::pair<MorpheusServices, ServiceInfo*>(LOGINSERVER, si));
    ACE_DEBUG((LM_DEBUG,"Realmd runs at pid %u\n", realmpid));
    return true;
}
예제 #16
0
bool Service_Manager::run_proxyd()
{
    ACE_ARGV proxyd_args;
    proxyd_args.add(this->args.argv()[0]);
    proxyd_args.add("rungamed");

    ACE_Process_Manager* pmgr = ACE_Process_Manager::instance();
    ACE_Process_Options pop;
    pop.command_line(proxyd_args.argv());
    pid_t proxyd_pid = pmgr->spawn(pop);
    if (proxyd_pid == ACE_INVALID_PID)
        return false;

    ServiceInfo* si = new ServiceInfo(proxyd_pid);
    this->svcs.insert(std::pair<MorpheusServices, ServiceInfo*>(GAMESERVER, si));
    ACE_DEBUG((LM_DEBUG,"Proxyd runs at pid %u\n", proxyd_pid));
    return true;
}
예제 #17
0
파일: Spawn.cpp 프로젝트: azraelly/knetwork
 // Listing 10 code/ch10
  int setUserID (ACE_Process_Options &options)
  {
    ACE_TRACE ("Manager::setUserID");
    passwd* pw = ACE_OS::getpwnam ("nobody");
    if (pw == 0)
      return -1;
    options.seteuid (pw->pw_uid);
    return 0;
  }
예제 #18
0
파일: Spawn.cpp 프로젝트: azraelly/knetwork
  int setStdHandles (ACE_Process_Options &options)
  {
    ACE_TRACE ("Manager::setStdHandles");

    ACE_OS::unlink ("output.dat");
    this->outputfd_ =
      ACE_OS::open ("output.dat", O_RDWR | O_CREAT);
    return options.set_handles
      (ACE_STDIN, ACE_STDOUT, this->outputfd_);
  }
예제 #19
0
int
Handle_Events::serve (char *buf)
{
  ACE_ARGV arguments (buf);

  if (ACE_OS::strcmp (arguments[0], TESTER) == 0)
    {
      ACE_Process_Options po;
      ACE_Process p;

      po.set_handles (ACE_INVALID_HANDLE, OUTPUT_FILE, OUTPUT_FILE);
      po.command_line (arguments.argv ());

      p.spawn (po);
      return 0;
    }
  else
    return -1;
}
예제 #20
0
static double
prof_ace_process (size_t iteration)
{
    if (iteration != 0)
    {
        ACE_Process_Options popt;
        ACE_Process aProcess;

        popt.command_line (SUBPROGRAM);

        iteration *= MULTIPLY_FACTOR;

        if (do_exec_after_fork == 0)
            popt.creation_flags (ACE_Process_Options::NO_EXEC);

        ACE_Profile_Timer ptimer;
        ACE_Profile_Timer::ACE_Elapsed_Time et;
        double time = 0;
        pid_t result;

        for (size_t c = 0; c < iteration; c++)
        {
            ACE_STOP_SIGN;
            ptimer.start ();
            result = aProcess.spawn (popt);
            ptimer.stop ();

            if (result == -1)
                ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "process.spawn"), -1);
            else if (do_exec_after_fork == 0 && result == 0)
                ACE_OS::exit (0) ;
            else
            {
                ptimer.elapsed_time (et);
                time += et.real_time;
            }
        }

        return time / iteration;
    }
    else
        return -1.0;
}
예제 #21
0
int
Iterator_Handler::spawn_viewer (void)
{
  char viewer[BUFSIZ];

  if (this->get_viewer (viewer,
                        sizeof viewer) != 0)
    ACE_ERROR_RETURN ((LM_ERROR,
                       ACE_TEXT ("Problem determining which external ")
                       ACE_TEXT ("viewer to use.\n")),
                      -1);

  // Set up the command line that will be used when spawning the
  // external viewer.
  ACE_Process_Options opts;
  opts.command_line (ACE_TEXT ("%s %s"),
                     viewer,
                     this->file_.get_path_name ());

  pid_t result = ACE_Process_Manager::instance ()->spawn (opts);

  switch (result)
    {
    case 0:
      // Child
      return 0;
    case ACE_INVALID_PID:
      ACE_ERROR_RETURN ((LM_ERROR,
                         ACE_TEXT ("Error during viewer spawn of %p\n"),
                         opts.command_line_buf ()),
                        -1);
    default:
      // Parent
      ACE_DEBUG ((LM_INFO,
                  ACE_TEXT ("Spawned viewer <%s> with PID <%d>.\n"),
                  viewer,
                  result));
      break;
    }

  return 0;
}
예제 #22
0
int main(int argc, char *argv[])
{
    ACE_Process_Options options;
    FILE *fp = 0;
    char *n_env = 0;
    int n;

    if (argc == 1) {
        n_env = ACE_OS::getenv("FACTORIAL");
        n = n_env == 0 ? 10 : atoi(n_env);
        options.command_line("%s %d", argv[0], n - 1);
        const char *working_dir = ACE_OS::getenv("WORKING_DIR");
        if (working_dir) options.working_directory(working_dir);
        fp = fopen("factorial.log", "a");
        cout << "before setenv" << endl;
        options.setenv("PROGRAM=%s", ACE::basename(argv[0]));
        cout << "after setenv" << endl;
    } else {
        fp = fopen("factorial.log", "a");
        if (atoi(argv[1]) == 1) {
            fprintf(fp, "[%s|%d]: base case\n",
                    ACE_OS::getenv("PROGRAM"), ACE_OS::getpid());
            fclose(fp);
            return 1;
        } else {
            n = atoi(argv[1]);
            options.command_line("%s %d", argv[0], n - 1);
        }
    }

    ACE_Process child;
    child.spawn(options);
    child.wait();
    int factorial = n * child.return_value();
    fprintf(fp, "[%s|%d]: %d! == %d\n",
            ACE_OS::getenv("PROGRAM"), ACE_OS::getpid(),
            n, factorial);
    fclose(fp);
    return factorial;
}
예제 #23
0
int main(int argc, char *argv[])
{
    ACE_Process_Options options;
    char *n_env = 0;
    int n;

    if (argc == 1) {
        n_env = ACE_OS::getenv("FACTORIAL");
        n = n_env == 0 ? 10 : atoi(n_env);
        options.command_line("%s %d", argv[0], n - 1);
    } else if (atoi(argv[1]) == 1) {
        return 1;
    } else {
        n = atoi(argv[1]);
        options.command_line("%s %d", argv[0], n - 1);
    }

    ACE_Process child;
    child.spawn(options);
    child.wait();
    return n * child.return_value();
}
예제 #24
0
파일: Spawn.cpp 프로젝트: azraelly/knetwork
 // Listing 2 code/ch10
  // prepare() is inherited from ACE_Process.
  int prepare (ACE_Process_Options &options)
  {
    ACE_TRACE ("Manager::prepare");

    options.command_line (ACE_TEXT ("%s 1"), this->programName_);
    if (this->setStdHandles (options) == -1 ||
        this->setEnvVariable (options) == -1)
      return -1;
#if !defined (ACE_WIN32) && !defined (ACE_LACKS_PWD_FUNCTIONS)
    return this->setUserID (options);
#else
    return 0;
#endif
  }
예제 #25
0
파일: imore.cpp 프로젝트: annp/ACE
static int
setup_named_pipes (ACE_Process_Options &opt)
{
  // Create a unique temporary name for named pipe.
  ACE_TCHAR *rendezvous = ACE_OS::tempnam (rendezvous_dir,
                                           rendezvous_pfx);

  // Out of memory?
  if (rendezvous == 0)
    return -1;

  // Alright, this is indeed strange.  Named pipes are meant to be
  // used for unrelated processes.  Because of the constraints in
  // ACE_Process, I have to pre-open the named pipes here.
  ACE_FIFO_Recv rfifo;          // read end fifo.
  ACE_FIFO_Send wfifo;          // write end fifo.

  // Check if the pipes are created successfully.
  if (rfifo.open (rendezvous) == -1 || wfifo.open (rendezvous) == -1)
    {
      ACE_OS::free (rendezvous);
      ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "fifo.open"), -1);
    }

  // Remove (rm, del) the file after no one uses it any more.
  ACE_OS::unlink (rendezvous);
  ACE_OS::free (rendezvous);

  // Setting up pipe between parent and child process.  Use the read
  // end of the named pipe as child process'es ACE_STDIN.
  // ACE_Process_Options will keep copies (by dup) of fd's that we
  // pass in.  Notice that we have to specify child process to use
  // ACE_STDOUT for output explicitly because we'll close it down in
  // the line after.  Child process will use whatever we use to dup2
  // ACE_STDOUT as its stdout.
  opt.set_handles (rfifo.get_handle (), ACE_STDOUT);

  // The previous keep a copy of original ACE_STDOUT fd, now we
  // can replace ACE_STDOUT of parent process to the write end
  // of the named pipe.
  ACE_OS::dup2 (wfifo.get_handle (), ACE_STDOUT);

  // Close unused fd's.  Notice ACE_FIFO doesn't close the fd
  // when it goes out of scope.
  rfifo.close ();
  wfifo.close ();
  return 0;
}
예제 #26
0
파일: imore.cpp 프로젝트: annp/ACE
int
ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
  // Ignore SIGPIPE signal on Unix platforms in case
  // child process (more) terminates before we finish
  // writing to stdout.
#if !defined (ACE_WIN32)
  ACE_Sig_Action sig_act (SIG_IGN);
  if (sig_act.register_action (SIGPIPE) == -1)
    ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "ACE_Sig_Action::register_action"), -1);
#endif /* ACE_WIN32 */

  // Alright, what you want me to do now?
  if (::parse_args (argc, argv) == -1)
    return -1;

  // Can I find the file you want?
  ACE_HANDLE infile = ACE_OS::open (fname, O_RDONLY);
  if (infile == ACE_INVALID_HANDLE)
      ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", fname), -1);

  ACE_Process new_process;

  // The ACE_Process_Options does not need to be enclosed in a block
  // because it does not close the file handles, the ACE_Process closes
  // them upon destruction.
#if !defined (ACE_WIN32)
  ACE_Process_Options options;

  if ((use_named_pipe ? ::setup_named_pipes :
       ::setup_unnamed_pipe) (options) == -1)
    ACE_ERROR_RETURN ((LM_ERROR, "Error, bailing out!\n"), -1);

  options.command_line (executable);
  if (new_process.spawn (options) == -1)
    {
      int const error_number = ACE_OS::last_error ();
      ACE_ERROR_RETURN ((LM_ERROR, "%p errno = %d.\n",
                         "test_more", error_number), -1);
    }

  // write file to ACE_STDOUT.
  if (::print_file (infile) == -1)
    ACE_ERROR_RETURN ((LM_ERROR, "Error, bailing out!\n"), -1);

  // Close the STDOUT to inform child eof.
  ACE_OS::close (ACE_STDOUT);
#else
  // We can only pass a file handler directly to child process
  // otherwise "more" doesn't act quite the way we want.  Nonetheless,
  // if your child process don't need to interact with the terminal,
  // we can use the exact code for Unixes on NT.
  ACE_Process_Options options;
  options.command_line (executable);
  options.set_handles (infile);
  if (new_process.spawn (options) == -1)
    {
      int error = ACE_OS::last_error ();
      ACE_ERROR_RETURN ((LM_ERROR, "%p errno = %d.\n",
                         "test_more", error), -1);
    }
#endif /* ! ACE_WIN32 */

  // Wait till we are done.
  ACE_exitcode status;
  new_process.wait (&status);
  ACE_DEBUG ((LM_DEBUG, "Process exit with status %d\n", status));

  ACE_OS::close (infile);

  return 0;
}
예제 #27
0
Test::Process_ptr
Process_Factory::create_new_process (void)
{
  Startup_Callback *startup_callback_impl;
  ACE_NEW_THROW_EX (startup_callback_impl,
                    Startup_Callback,
                    CORBA::NO_MEMORY ());

  PortableServer::ServantBase_var owner_transfer(startup_callback_impl);

  CORBA::Object_var poa_object =
    this->orb_->resolve_initial_references("RootPOA");

  PortableServer::POA_var root_poa =
    PortableServer::POA::_narrow (poa_object.in ());

  PortableServer::ObjectId_var id =
    root_poa->activate_object (startup_callback_impl);

  CORBA::Object_var object = root_poa->id_to_reference (id.in ());

  Test::Startup_Callback_var startup_callback =
    Test::Startup_Callback::_narrow (object.in ());

  CORBA::String_var ior =
    this->orb_->object_to_string (startup_callback.in ());

  const ACE_TCHAR* argv[3] = {
    ACE_TEXT("child"),
    ACE_TEXT_CHAR_TO_TCHAR(ior.in ()),
    0};

  ACE_Process_Options options;
#if !defined(ACE_WIN32)
  options.avoid_zombies (1);
#endif /* ACE_WIN32 */
  options.command_line (argv);

  ACE_Process child_process;
  pid_t pid =
    child_process.spawn (options);

  if (pid == -1)
    {
      ACE_DEBUG ((LM_DEBUG,
                  "(%P|%t) Process_Factory::create_new_process, "
                  " spawn call failed (%d)\n",
                  ACE_ERRNO_GET));
      throw Test::Spawn_Failed ();
    }

  int process_has_started = 0;
  Test::Process_var the_process;
  for (int i = 0; i != 500 && !process_has_started; ++i)
    {
      ACE_Time_Value interval (0, 10000);
      this->orb_->perform_work (interval);

      process_has_started =
        startup_callback_impl->process_has_started (the_process.out ());
    }

  try
    {
      PortableServer::POA_var poa =
        startup_callback_impl->_default_POA ();
      PortableServer::ObjectId_var id =
        poa->servant_to_id (startup_callback_impl);
      poa->deactivate_object (id.in ());
    }
  catch (const CORBA::Exception&)
    {
    }

  if (process_has_started == 0)
    {
      ACE_DEBUG ((LM_DEBUG,
                  "(%P|%t) Process_Factory::create_new_process, "
                  " timeout while waiting for child\n"));
      (void) child_process.terminate ();
      throw Test::Spawn_Failed ();
    }

  return the_process._retn ();
}
예제 #28
0
pid_t
ACE_Process::spawn (ACE_Process_Options &options)
{
  if (this->prepare (options) < 0)
    return ACE_INVALID_PID;

  // Stash the passed/duped handle sets away in this object for later
  // closing if needed or requested. At the same time, figure out which
  // ones to include in command line options if that's needed below.
  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 */
}
예제 #29
0
파일: process.cpp 프로젝트: akostrikov/ATCD
int
ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
    if (ACE_LOG_MSG->open (argv[0]) == -1)
        ACE_ERROR ((LM_ERROR,
                    ACE_TEXT ("cannot open logger!!!\n")));

    ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("starting...\n")));

    if (::parse_args (argc, argv) == -1)
        return -1;

    if (run_all)
    {
#if defined (ACE_WIN32) || !defined (ACE_USES_WCHAR)
        const ACE_TCHAR *cmdline = ACE_TEXT ("%s -d -l -s -w");
#else
        const ACE_TCHAR *cmdline = ACE_TEXT ("%ls -d -l -s -w");
#endif
        ACE_Process_Options options;
        options.command_line (cmdline, argv[0]);
        ACE_Process process;
        if (process.spawn (options) == -1)
            ACE_ERROR_RETURN ((LM_ERROR,
                               ACE_TEXT ("%p.\n"),
                               ACE_TEXT ("main")),
                              -1);
        ACE_exitcode status;
        process.wait (&status);
        ACE_DEBUG ((LM_DEBUG,
                    ACE_TEXT ("Process exit with status %d\n"),
                    status));
    }

    if (run_date)
        ::test_date ();

    if (run_setenv)
        ::test_setenv (argv[0]);

    if (get_env)
    {
        ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("checking ACE_PROCESS_TEST\n")));
        char *value = ACE_OS::getenv ("ACE_PROCESS_TEST");
        char *value2 = ACE_OS::getenv ("ACE_PROCESS_TEST2");
        ACE_DEBUG ((LM_DEBUG,
                    "ACE_PROCESS_TEST = %C.\n"
                    "ACE_PROCESS_TEST2 = %C.\n",
                    value == 0 ? "no value" : value,
                    value2 == 0 ? "no value" : value2));
    }

    if (run_ls)
        ::test_ls ();

    if (run_wait)
        ::test_wait ();

#if defined (ACE_WIN32)
    ACE_UNUSED_ARG (&win32_test_ls);

    if (environment_string != 0)
        win32_spawn_environment_process ();
#endif /* ACE_WIN32 */

    if (print_file != 0)
        test_more ();

    ACE_TCHAR buf1[30];
    ACE_TCHAR buf2[30];
    ACE_OS::strcpy(buf1, ACE_TEXT (" -f hi honey -g \"I\'m home\""));
    ACE_OS::strcpy(buf2, ACE_TEXT ("\"token 1\"\'token 2\'\"token 3\" "));

    if (run_tokenizer)
    {
        tokenize (buf1);
        tokenize (buf2);
    }

    return 0;
}
예제 #30
0
파일: process.cpp 프로젝트: akostrikov/ATCD
static void
test_wait (void)
{
    ACE_Process_Options options;
#if defined (ACE_WIN32) || !defined (ACE_USES_WCHAR)
    options.command_line (ACE_TEXT ("%s 10"), SLEEP_PATH);
#else
    options.command_line (ACE_TEXT ("%ls 10"), SLEEP_PATH);
#endif
    ACE_Process process1;
    if (process1.spawn (options) == -1)
    {
        int const error_number = ACE_OS::last_error ();
        ACE_ERROR ((LM_ERROR,
                    ACE_TEXT ("%p errno = %d.\n"),
                    ACE_TEXT ("test_ls"),
                    error_number));
    }

    int result;
    ACE_exitcode status;

    //FUZZ: disable check_for_lack_ACE_OS
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("[%T] New process sleeping 10; try wait(2)\n")));
    //FUZZ: enable check_for_lack_ACE_OS

    result = process1.wait (ACE_Time_Value (2), &status);

    //FUZZ: disable check_for_lack_ACE_OS
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("[%T] wait(2) returns %d(%d)...now try regular wait\n"),
                result,
                status));
    //FUZZ: enable check_for_lack_ACE_OS

    result = process1.wait (&status);

    //FUZZ: disable check_for_lack_ACE_OS
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("[%T] wait() returns %d(%d)\n"),
                result,
                status));
    //FUZZ: enable check_for_lack_ACE_OS

    ACE_Process process2;
    if (process2.spawn (options) == -1)
    {
        int const error_number = ACE_OS::last_error ();
        ACE_ERROR ((LM_ERROR,
                    ACE_TEXT ("%p errno = %d.\n"),
                    ACE_TEXT ("test_ls"),
                    error_number));
    }

    //FUZZ: disable check_for_lack_ACE_OS
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("[%T] New process sleeping 10; try wait(12)\n"),
                status));
    //FUZZ: enable check_for_lack_ACE_OS

    result = process2.wait (ACE_Time_Value (12), &status);

    //FUZZ: disable check_for_lack_ACE_OS
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("[%T] wait(12) returns %d(%d)...now try regular wait\n"),
                result,
                status));
    //FUZZ: enable check_for_lack_ACE_OS

    result = process2.wait (&status);
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("[%T] wait returns %d(%d)\n"),
                result,
                status));
}