use existing pf probe function from network.c instead of re-implementing it in service.c
[oweals/gnunet.git] / src / util / gnunet-timeout.c
1 /*
2      This file is part of GNUnet
3      Copyright (C) 2010 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License, or
8      (at your option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Affero General Public License for more details.
14
15      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21 /**
22  * @file src/util/gnunet-timeout.c
23  * @brief small tool starting a child process, waiting that it terminates or killing it after a given timeout period
24  * @author Matthias Wachs
25  */
26
27 #include <sys/types.h>
28 #include <sys/wait.h>
29 #include <signal.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <unistd.h>
33
34 static pid_t child;
35
36
37 static void
38 sigchld_handler (int val)
39 {
40   int status = 0;
41   int ret = 0;
42
43   (void) val;
44   waitpid (child,
45            &status,
46            0);
47   if (WIFEXITED (status) != 0)
48   {
49     ret = WEXITSTATUS (status);
50     fprintf (stderr,
51              "Process exited with result %u\n",
52              ret);
53     exit (ret); /* return same status code */
54   }
55   if (WIFSIGNALED (status) != 0)
56   {
57     ret = WTERMSIG (status);
58     fprintf (stderr,
59              "Process received signal %u\n",
60              ret);
61     kill (getpid (),
62           ret); /* kill self with the same signal */
63   }
64   exit (-1);
65 }
66
67
68 static void
69 sigint_handler (int val)
70 {
71   kill (0,
72         val);
73   exit (val);
74 }
75
76
77 int
78 main (int argc,
79       char *argv[])
80 {
81   int timeout = 0;
82   pid_t gpid = 0;
83
84   if (argc < 3)
85   {
86     fprintf (stderr,
87              "arg 1: timeout in sec., arg 2: executable, arg<n> arguments\n");
88     exit (-1);
89   }
90
91   timeout = atoi (argv[1]);
92
93   if (timeout == 0)
94     timeout = 600;
95
96   /* with getpgid() it does not compile, but getpgrp is the BSD version and working */
97   gpid = getpgrp ();
98
99   signal (SIGCHLD, sigchld_handler);
100   signal (SIGABRT, sigint_handler);
101   signal (SIGFPE, sigint_handler);
102   signal (SIGILL, sigint_handler);
103   signal (SIGINT, sigint_handler);
104   signal (SIGSEGV, sigint_handler);
105   signal (SIGTERM, sigint_handler);
106
107   child = fork ();
108   if (child == 0)
109   {
110     /*  int setpgrp(pid_t pid, pid_t pgid); is not working on this machine */
111     //setpgrp (0, pid_t gpid);
112     if (-1 != gpid)
113       setpgid (0, gpid);
114     execvp (argv[2],
115             &argv[2]);
116     exit (-1);
117   }
118   if (child > 0)
119   {
120     sleep (timeout);
121     printf ("Child processes were killed after timeout of %u seconds\n",
122             timeout);
123     kill (0,
124           SIGTERM);
125     exit (3);
126   }
127   exit (-1);
128 }
129
130 /* end of timeout_watchdog.c */