aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-12-17 13:13:09 +0100
committerChristian Grothoff <christian@grothoff.org>2019-12-17 13:13:09 +0100
commitd3332b0876af7e4cea1e582e30613d6460b5de3c (patch)
tree737cfdf749f7981f89c547f839c0e767cec348ff
parenta6380e0e3c37fad3c8920dbb250878b680342b06 (diff)
downloadgnunet-d3332b0876af7e4cea1e582e30613d6460b5de3c.tar.gz
gnunet-d3332b0876af7e4cea1e582e30613d6460b5de3c.zip
fix gnunet-qr logic
-rw-r--r--src/util/gnunet-qr.c50
1 files changed, 42 insertions, 8 deletions
diff --git a/src/util/gnunet-qr.c b/src/util/gnunet-qr.c
index 122b81f39..cd23c3a9c 100644
--- a/src/util/gnunet-qr.c
+++ b/src/util/gnunet-qr.c
@@ -58,12 +58,21 @@ static long unsigned int exit_code = 1;
58 */ 58 */
59static struct GNUNET_OS_Process *p; 59static struct GNUNET_OS_Process *p;
60 60
61/**
62 * Child signal handler.
63 */
64static struct GNUNET_SIGNAL_Context *shc_chld;
61 65
62/** 66/**
63 * Pipe used to communicate child death via signal. 67 * Pipe used to communicate child death via signal.
64 */ 68 */
65static struct GNUNET_DISK_PipeHandle *sigpipe; 69static struct GNUNET_DISK_PipeHandle *sigpipe;
66 70
71/**
72 * Process ID of this process at the time we installed the various
73 * signal handlers.
74 */
75static pid_t my_pid;
67 76
68/** 77/**
69 * Task triggered whenever we receive a SIGCHLD (child 78 * Task triggered whenever we receive a SIGCHLD (child
@@ -79,6 +88,8 @@ maint_child_death (void *cls)
79 if ((GNUNET_OK != GNUNET_OS_process_status (p, &type, &exit_code)) || 88 if ((GNUNET_OK != GNUNET_OS_process_status (p, &type, &exit_code)) ||
80 (type != GNUNET_OS_PROCESS_EXITED)) 89 (type != GNUNET_OS_PROCESS_EXITED))
81 GNUNET_break (0 == GNUNET_OS_process_kill (p, GNUNET_TERM_SIG)); 90 GNUNET_break (0 == GNUNET_OS_process_kill (p, GNUNET_TERM_SIG));
91 GNUNET_SIGNAL_handler_uninstall (shc_chld);
92 shc_chld = NULL;
82 if (NULL != sigpipe) 93 if (NULL != sigpipe)
83 { 94 {
84 GNUNET_DISK_pipe_close (sigpipe); 95 GNUNET_DISK_pipe_close (sigpipe);
@@ -89,6 +100,25 @@ maint_child_death (void *cls)
89 100
90 101
91/** 102/**
103 * Signal handler called for signals that causes us to wait for the child process.
104 */
105static void
106sighandler_chld ()
107{
108 static char c;
109 int old_errno = errno; /* backup errno */
110
111 if (getpid () != my_pid)
112 _exit (1); /* we have fork'ed since the signal handler was created,
113 * ignore the signal, see https://gnunet.org/vfork discussion */
114 GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle
115 (sigpipe, GNUNET_DISK_PIPE_END_WRITE),
116 &c, sizeof(c));
117 errno = old_errno;
118}
119
120
121/**
92 * Dispatch URIs to the appropriate GNUnet helper process 122 * Dispatch URIs to the appropriate GNUnet helper process
93 * 123 *
94 * @param cls closure 124 * @param cls closure
@@ -141,14 +171,15 @@ gnunet_uri (void *cls,
141 GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ), 171 GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ),
142 &maint_child_death, 172 &maint_child_death,
143 NULL); 173 NULL);
174 my_pid = getpid ();
175 shc_chld = GNUNET_SIGNAL_handler_install (SIGCHLD,
176 &sighandler_chld);
177
144 { 178 {
145 char **argv = NULL; 179 char **argv = NULL;
146 unsigned int argc = 0; 180 unsigned int argc = 0;
147 char *u = GNUNET_strdup (orig_uri); 181 char *u = GNUNET_strdup (program);
148 182
149 GNUNET_array_append (argv,
150 argc,
151 GNUNET_strdup (program));
152 for (const char *tok = strtok (u, " "); 183 for (const char *tok = strtok (u, " ");
153 NULL != tok; 184 NULL != tok;
154 tok = strtok (NULL, " ")) 185 tok = strtok (NULL, " "))
@@ -157,24 +188,27 @@ gnunet_uri (void *cls,
157 GNUNET_strdup (tok)); 188 GNUNET_strdup (tok));
158 GNUNET_array_append (argv, 189 GNUNET_array_append (argv,
159 argc, 190 argc,
191 GNUNET_strdup (orig_uri));
192 GNUNET_array_append (argv,
193 argc,
160 NULL); 194 NULL);
161 p = GNUNET_OS_start_process_vap (GNUNET_NO, 195 p = GNUNET_OS_start_process_vap (GNUNET_NO,
162 0, 196 GNUNET_OS_INHERIT_STD_ALL,
163 NULL, 197 NULL,
164 NULL, 198 NULL,
165 NULL, 199 NULL,
166 program, 200 argv[0],
167 argv); 201 argv);
168 for (unsigned int i = 0; i<argc; i++) 202 for (unsigned int i = 0; i<argc - 1; i++)
169 GNUNET_free (argv[i]); 203 GNUNET_free (argv[i]);
170 GNUNET_array_grow (argv, 204 GNUNET_array_grow (argv,
171 argc, 205 argc,
172 0); 206 0);
173 GNUNET_free (u); 207 GNUNET_free (u);
174 } 208 }
175 GNUNET_free (program);
176 if (NULL == p) 209 if (NULL == p)
177 GNUNET_SCHEDULER_cancel (rt); 210 GNUNET_SCHEDULER_cancel (rt);
211 GNUNET_free (program);
178} 212}
179 213
180 214