1 /*
2      This file is part of libmicrohttpd
3      Copyright (C) 2008,2016 Christian Grothoff
4 
5      libmicrohttpd is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 2, or (at your
8      option) any later version.
9 
10      libmicrohttpd 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      General Public License for more details.
14 
15      You should have received a copy of the GNU General Public License
16      along with libmicrohttpd; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, USA.
19 */
20 
21 /**
22  * @file socat.c
23  * @brief  Code to fork-exec zzuf and start the socat process
24  * @author Christian Grothoff
25  */
26 
27 #include <errno.h>
28 #include <sys/types.h>
29 #include <sys/wait.h>
30 #include <signal.h>
31 
32 #ifdef _WIN32
33 #ifndef WIN32_LEAN_AND_MEAN
34 #define WIN32_LEAN_AND_MEAN 1
35 #endif /* !WIN32_LEAN_AND_MEAN */
36 #include <windows.h>
37 #endif
38 
39 
40 /**
41  * A larger loop count will run more random tests --
42  * which would be good, except that it may take too
43  * long for most user's patience.  So this small
44  * value is the default.
45  */
46 #ifndef _MHD_HEAVY_TESTS
47 #define LOOP_COUNT 10
48 #else  /* ! _MHD_HEAVY_TESTS */
49 #define LOOP_COUNT 200
50 #endif /* ! _MHD_HEAVY_TESTS */
51 
52 #define CURL_TIMEOUT 50L
53 
54 static pid_t zzuf_pid;
55 
56 static void
zzuf_socat_start()57 zzuf_socat_start ()
58 {
59   int status;
60   char *const args[] = {
61     "zzuf",
62     "--ratio=0.0:0.75",
63     "-n",
64     "-A",
65     "socat",
66     "-lf",
67     "/dev/null",
68     "TCP4-LISTEN:11081,reuseaddr,fork",
69     "TCP4:127.0.0.1:11080",
70     NULL,
71   };
72   zzuf_pid = fork ();
73   if (zzuf_pid == -1)
74   {
75     fprintf (stderr, "fork failed: %s\n", strerror (errno));
76     exit (1);
77   }
78   if (zzuf_pid != 0)
79   {
80     (void) sleep (1);                 /* allow zzuf and socat to start */
81     status = 0;
82     if (0 < waitpid (zzuf_pid, &status, WNOHANG))
83     {
84       if (WIFEXITED (status))
85         fprintf (stderr,
86                  "zzuf died with status code %d!\n",
87                  WEXITSTATUS (status));
88       if (WIFSIGNALED (status))
89         fprintf (stderr,
90                  "zzuf died from signal %d!\n", WTERMSIG (status));
91       exit (1);
92     }
93     return;
94   }
95   setpgid (0, 0);
96   execvp ("zzuf", args);
97   fprintf (stderr, "execution of `zzuf' failed: %s\n", strerror (errno));
98   exit (1);
99 }
100 
101 
102 static void
zzuf_socat_stop()103 zzuf_socat_stop ()
104 {
105   int status;
106   if (zzuf_pid != 0)
107   {
108     if (0 != killpg (zzuf_pid, SIGINT))
109       fprintf (stderr, "Failed to killpg: %s\n", strerror (errno));
110     kill (zzuf_pid, SIGINT);
111     waitpid (zzuf_pid, &status, 0);
112     (void) sleep (1);                 /* allow socat to also die in peace */
113   }
114 }
115 
116 
117 /* end of socat.c */
118