diff options
author | Christian Grothoff <christian@grothoff.org> | 2019-12-17 13:13:09 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2019-12-17 13:13:09 +0100 |
commit | d3332b0876af7e4cea1e582e30613d6460b5de3c (patch) | |
tree | 737cfdf749f7981f89c547f839c0e767cec348ff | |
parent | a6380e0e3c37fad3c8920dbb250878b680342b06 (diff) | |
download | gnunet-d3332b0876af7e4cea1e582e30613d6460b5de3c.tar.gz gnunet-d3332b0876af7e4cea1e582e30613d6460b5de3c.zip |
fix gnunet-qr logic
-rw-r--r-- | src/util/gnunet-qr.c | 50 |
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 | */ |
59 | static struct GNUNET_OS_Process *p; | 59 | static struct GNUNET_OS_Process *p; |
60 | 60 | ||
61 | /** | ||
62 | * Child signal handler. | ||
63 | */ | ||
64 | static 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 | */ |
65 | static struct GNUNET_DISK_PipeHandle *sigpipe; | 69 | static 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 | */ | ||
75 | static 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 | */ | ||
105 | static void | ||
106 | sighandler_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 | ||