4 * Author: Arvin Schnell <arvin@suse.de>
10 #include <sys/types.h>
25 // SIGCHLD is blocked anyways
26 #define sigprocmask(x, y, z)
33 dprintf ("%s\n", __PRETTY_FUNCTION__);
35 sigemptyset (&block_chld);
36 sigaddset (&block_chld, SIGCHLD);
40 processes.push_back (this);
46 dprintf ("%s\n", __PRETTY_FUNCTION__);
47 processes.remove (this);
58 has_died_flag = false;
69 const unsigned int nargs = args.size ();
74 // We have to block the child signal, otherwise the signal can
75 // arrive before the fork return and the pid is set. Then our
76 // signal handler would not work.
77 sigprocmask (SIG_BLOCK, &block_chld, 0);
79 has_died_flag = false;
81 sigprocmask (SIG_UNBLOCK, &block_chld, 0);
87 for (int fd = 0; fd < 3; fd++) {
88 int null_fd = open (_PATH_DEVNULL, O_RDONLY);
94 for (int tty = 3; tty < 256; tty++) {
96 for (unsigned int i = 0; i < fd_notclose.size (); i++)
97 if (tty == fd_notclose[i])
103 char** ptr = new char* [nargs + 1];
104 for (unsigned int i = 0; i < nargs; i++)
105 ptr[i] = strdup (args[i].c_str ());
108 // pppd may call kill (0, SIGTERM), but I don't want to die.
111 execvp (ptr[0], ptr);
112 _exit (EXIT_FAILURE);
127 Process::close_stuff ()
129 for (unsigned int i = 0; i < fd_notclose.size (); i++)
130 close (fd_notclose[i]);
140 pid_t ret = waitpid (pid, &status, WNOHANG);
144 has_died_flag = true;
151 Process::kill (int timeout, bool group)
153 sigprocmask (SIG_BLOCK, &block_chld, 0);
155 ::kill (!group ? pid : -pid, SIGTERM);
156 sigprocmask (SIG_UNBLOCK, &block_chld, 0);
161 for (int i = 0; i < timeout; i++) {
167 sigprocmask (SIG_BLOCK, &block_chld, 0);
169 ::kill (!group ? pid : -pid, SIGKILL);
170 sigprocmask (SIG_UNBLOCK, &block_chld, 0);
175 Process::wait_for_dead ()
177 sigprocmask (SIG_BLOCK, &block_chld, 0);
179 pid_t ret = waitpid (pid, &status, 0);
182 has_died_flag = true;
186 sigprocmask (SIG_UNBLOCK, &block_chld, 0);
194 has_died_flag = false;
203 Process::normal_exit ()
206 return WIFEXITED (tmp);
211 Process::exit_status ()
214 return WEXITSTATUS (tmp);
219 Process::operator << (const char* arg)
221 args.push_back (arg);
227 Process::operator << (const string& arg)
229 args.push_back (arg);
235 Process::operator << (const vector <string>& arg)
237 for (vector <string>::const_iterator it = arg.begin ();
238 it != arg.end (); it++)
239 args.push_back (*it);
245 Process::operator << (int num)
248 snprintf (buffer, 32, "%d", num);
249 args.push_back (buffer);
255 Process::add_fd_notclose (int fd)
257 fd_notclose.push_back (fd);
262 Process::dump_args () const
266 for (std::vector <string>::const_iterator it = args.begin ();
267 it != args.end (); it++) {
268 if (it != args.begin ())
280 Processes::sigterm ()
282 // waitpid changes errno, so save it.
284 int saved_errno = errno;
286 for (const_iterator it = begin (); it != end (); it++)
294 Processes::terminated (pid_t pid)
296 for (const_iterator it = begin (); it != end (); it++)
298 if(pid == (*it)->pid)
300 dprintf("pid %d found\n", pid);
301 if ((*it)->exitcallback)
302 (*(*it)->exitcallback)(*it);
307 dprintf("pid %d NOT found\n", pid);
311 Process::set_exitcallback(ProcessExit* handler)
313 exitcallback = handler;