RAUL  0.8.0
Process.hpp
1 /* This file is part of Raul.
2  * Copyright (C) 2007-2009 David Robillard <http://drobilla.net>
3  *
4  * Raul is free software; you can redistribute it and/or modify it under the
5  * terms of the GNU General Public License as published by the Free Software
6  * Foundation; either version 2 of the License, or (at your option) any later
7  * version.
8  *
9  * Raul is distributed in the hope that it will be useful, but WITHOUT ANY
10  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16  */
17 
18 #ifndef RAUL_PROCESS_HPP
19 #define RAUL_PROCESS_HPP
20 
21 #include <sys/resource.h>
22 #include <sys/time.h>
23 #include <unistd.h>
24 
25 #include <iostream>
26 #include <string>
27 
28 #include <boost/utility.hpp>
29 
30 #include "raul/log.hpp"
31 
32 namespace Raul {
33 
34 
39 class Process : boost::noncopyable
40 {
41 public:
42 
47  static bool launch(const std::string& command) {
48  const std::string executable = (command.find(" ") != std::string::npos)
49  ? command.substr(0, command.find(" "))
50  : command;
51 
52  const std::string arguments = command.substr((command.find(" ") + 1));
53 
54  info << "Launching child process '" << executable << "' with arguments '"
55  << arguments << "'" << std::endl;
56 
57  // Use the same double fork() trick as JACK to prevent zombie children
58  const int err = fork();
59 
60  if (err == 0) {
61  // (child)
62 
63  // close all nonstandard file descriptors
64  struct rlimit max_fds;
65  getrlimit(RLIMIT_NOFILE, &max_fds);
66 
67  for (rlim_t fd = 3; fd < max_fds.rlim_cur; ++fd)
68  close(fd);
69 
70  switch (fork()) {
71  case 0:
72  // (grandchild)
73  setsid();
74  execlp(executable.c_str(), arguments.c_str(), NULL);
75  _exit(-1);
76 
77  case -1:
78  // (second) fork failed, there is no grandchild
79  _exit (-1);
80 
81  /* exit the child process here */
82  default:
83  _exit (0);
84  }
85  }
86 
87  return (err > 0);
88  }
89 
90 private:
91  Process() {}
92 };
93 
94 
95 } // namespace Raul
96 
97 #endif // RAUL_PROCESS_HPP