summaryrefslogtreecommitdiff
path: root/src/util/helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/helper.c')
-rw-r--r--src/util/helper.c562
1 files changed, 279 insertions, 283 deletions
diff --git a/src/util/helper.c b/src/util/helper.c
index aa452d22b..f0892a485 100644
--- a/src/util/helper.c
+++ b/src/util/helper.c
@@ -11,12 +11,12 @@
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU Affero General Public License 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/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
18 SPDX-License-Identifier: AGPL3.0-or-later 18 SPDX-License-Identifier: AGPL3.0-or-later
19*/ 19 */
20 20
21/** 21/**
22 * @file util/helper.c 22 * @file util/helper.c
@@ -33,9 +33,7 @@
33/** 33/**
34 * Entry in the queue of messages we need to transmit to the helper. 34 * Entry in the queue of messages we need to transmit to the helper.
35 */ 35 */
36struct GNUNET_HELPER_SendHandle 36struct GNUNET_HELPER_SendHandle {
37{
38
39 /** 37 /**
40 * This is an entry in a DLL. 38 * This is an entry in a DLL.
41 */ 39 */
@@ -76,9 +74,7 @@ struct GNUNET_HELPER_SendHandle
76/** 74/**
77 * The handle to a helper process. 75 * The handle to a helper process.
78 */ 76 */
79struct GNUNET_HELPER_Handle 77struct GNUNET_HELPER_Handle {
80{
81
82 /** 78 /**
83 * PipeHandle to receive data from the helper 79 * PipeHandle to receive data from the helper
84 */ 80 */
@@ -176,40 +172,40 @@ struct GNUNET_HELPER_Handle
176 * @return #GNUNET_OK on success; #GNUNET_SYSERR on error 172 * @return #GNUNET_OK on success; #GNUNET_SYSERR on error
177 */ 173 */
178int 174int
179GNUNET_HELPER_kill (struct GNUNET_HELPER_Handle *h, int soft_kill) 175GNUNET_HELPER_kill(struct GNUNET_HELPER_Handle *h, int soft_kill)
180{ 176{
181 struct GNUNET_HELPER_SendHandle *sh; 177 struct GNUNET_HELPER_SendHandle *sh;
182 int ret; 178 int ret;
183 179
184 while (NULL != (sh = h->sh_head)) 180 while (NULL != (sh = h->sh_head))
185 { 181 {
186 GNUNET_CONTAINER_DLL_remove (h->sh_head, h->sh_tail, sh); 182 GNUNET_CONTAINER_DLL_remove(h->sh_head, h->sh_tail, sh);
187 if (NULL != sh->cont) 183 if (NULL != sh->cont)
188 sh->cont (sh->cont_cls, GNUNET_NO); 184 sh->cont(sh->cont_cls, GNUNET_NO);
189 GNUNET_free (sh); 185 GNUNET_free(sh);
190 } 186 }
191 if (NULL != h->restart_task) 187 if (NULL != h->restart_task)
192 { 188 {
193 GNUNET_SCHEDULER_cancel (h->restart_task); 189 GNUNET_SCHEDULER_cancel(h->restart_task);
194 h->restart_task = NULL; 190 h->restart_task = NULL;
195 } 191 }
196 if (NULL != h->read_task) 192 if (NULL != h->read_task)
197 { 193 {
198 GNUNET_SCHEDULER_cancel (h->read_task); 194 GNUNET_SCHEDULER_cancel(h->read_task);
199 h->read_task = NULL; 195 h->read_task = NULL;
200 } 196 }
201 if (NULL == h->helper_proc) 197 if (NULL == h->helper_proc)
202 return GNUNET_SYSERR; 198 return GNUNET_SYSERR;
203 if (GNUNET_YES == soft_kill) 199 if (GNUNET_YES == soft_kill)
204 { 200 {
205 /* soft-kill only possible with pipes */ 201 /* soft-kill only possible with pipes */
206 GNUNET_assert (NULL != h->helper_in); 202 GNUNET_assert(NULL != h->helper_in);
207 ret = GNUNET_DISK_pipe_close (h->helper_in); 203 ret = GNUNET_DISK_pipe_close(h->helper_in);
208 h->helper_in = NULL; 204 h->helper_in = NULL;
209 h->fh_to_helper = NULL; 205 h->fh_to_helper = NULL;
210 return ret; 206 return ret;
211 } 207 }
212 if (0 != GNUNET_OS_process_kill (h->helper_proc, GNUNET_TERM_SIG)) 208 if (0 != GNUNET_OS_process_kill(h->helper_proc, GNUNET_TERM_SIG))
213 return GNUNET_SYSERR; 209 return GNUNET_SYSERR;
214 return GNUNET_OK; 210 return GNUNET_OK;
215} 211}
@@ -224,50 +220,50 @@ GNUNET_HELPER_kill (struct GNUNET_HELPER_Handle *h, int soft_kill)
224 * @return #GNUNET_OK on success; #GNUNET_SYSERR on error 220 * @return #GNUNET_OK on success; #GNUNET_SYSERR on error
225 */ 221 */
226int 222int
227GNUNET_HELPER_wait (struct GNUNET_HELPER_Handle *h) 223GNUNET_HELPER_wait(struct GNUNET_HELPER_Handle *h)
228{ 224{
229 struct GNUNET_HELPER_SendHandle *sh; 225 struct GNUNET_HELPER_SendHandle *sh;
230 int ret; 226 int ret;
231 227
232 ret = GNUNET_SYSERR; 228 ret = GNUNET_SYSERR;
233 if (NULL != h->helper_proc) 229 if (NULL != h->helper_proc)
234 { 230 {
235 ret = GNUNET_OS_process_wait (h->helper_proc); 231 ret = GNUNET_OS_process_wait(h->helper_proc);
236 GNUNET_OS_process_destroy (h->helper_proc); 232 GNUNET_OS_process_destroy(h->helper_proc);
237 h->helper_proc = NULL; 233 h->helper_proc = NULL;
238 } 234 }
239 if (NULL != h->read_task) 235 if (NULL != h->read_task)
240 { 236 {
241 GNUNET_SCHEDULER_cancel (h->read_task); 237 GNUNET_SCHEDULER_cancel(h->read_task);
242 h->read_task = NULL; 238 h->read_task = NULL;
243 } 239 }
244 if (NULL != h->write_task) 240 if (NULL != h->write_task)
245 { 241 {
246 GNUNET_SCHEDULER_cancel (h->write_task); 242 GNUNET_SCHEDULER_cancel(h->write_task);
247 h->write_task = NULL; 243 h->write_task = NULL;
248 } 244 }
249 if (NULL != h->helper_in) 245 if (NULL != h->helper_in)
250 { 246 {
251 GNUNET_DISK_pipe_close (h->helper_in); 247 GNUNET_DISK_pipe_close(h->helper_in);
252 h->helper_in = NULL; 248 h->helper_in = NULL;
253 h->fh_to_helper = NULL; 249 h->fh_to_helper = NULL;
254 } 250 }
255 if (NULL != h->helper_out) 251 if (NULL != h->helper_out)
256 { 252 {
257 GNUNET_DISK_pipe_close (h->helper_out); 253 GNUNET_DISK_pipe_close(h->helper_out);
258 h->helper_out = NULL; 254 h->helper_out = NULL;
259 h->fh_from_helper = NULL; 255 h->fh_from_helper = NULL;
260 } 256 }
261 while (NULL != (sh = h->sh_head)) 257 while (NULL != (sh = h->sh_head))
262 { 258 {
263 GNUNET_CONTAINER_DLL_remove (h->sh_head, h->sh_tail, sh); 259 GNUNET_CONTAINER_DLL_remove(h->sh_head, h->sh_tail, sh);
264 if (NULL != sh->cont) 260 if (NULL != sh->cont)
265 sh->cont (sh->cont_cls, GNUNET_NO); 261 sh->cont(sh->cont_cls, GNUNET_NO);
266 GNUNET_free (sh); 262 GNUNET_free(sh);
267 } 263 }
268 /* purge MST buffer */ 264 /* purge MST buffer */
269 if (NULL != h->mst) 265 if (NULL != h->mst)
270 (void) GNUNET_MST_from_buffer (h->mst, NULL, 0, GNUNET_YES, GNUNET_NO); 266 (void)GNUNET_MST_from_buffer(h->mst, NULL, 0, GNUNET_YES, GNUNET_NO);
271 return ret; 267 return ret;
272} 268}
273 269
@@ -280,18 +276,18 @@ GNUNET_HELPER_wait (struct GNUNET_HELPER_Handle *h)
280 * stdin; #GNUNET_NO to signal termination by sending SIGTERM to helper 276 * stdin; #GNUNET_NO to signal termination by sending SIGTERM to helper
281 */ 277 */
282static void 278static void
283stop_helper (struct GNUNET_HELPER_Handle *h, int soft_kill) 279stop_helper(struct GNUNET_HELPER_Handle *h, int soft_kill)
284{ 280{
285 if (NULL != h->restart_task) 281 if (NULL != h->restart_task)
286 { 282 {
287 GNUNET_SCHEDULER_cancel (h->restart_task); 283 GNUNET_SCHEDULER_cancel(h->restart_task);
288 h->restart_task = NULL; 284 h->restart_task = NULL;
289 } 285 }
290 else 286 else
291 { 287 {
292 GNUNET_break (GNUNET_OK == GNUNET_HELPER_kill (h, soft_kill)); 288 GNUNET_break(GNUNET_OK == GNUNET_HELPER_kill(h, soft_kill));
293 GNUNET_break (GNUNET_OK == GNUNET_HELPER_wait (h)); 289 GNUNET_break(GNUNET_OK == GNUNET_HELPER_wait(h));
294 } 290 }
295} 291}
296 292
297 293
@@ -301,7 +297,7 @@ stop_helper (struct GNUNET_HELPER_Handle *h, int soft_kill)
301 * @param cls handle to the helper process 297 * @param cls handle to the helper process
302 */ 298 */
303static void 299static void
304restart_task (void *cls); 300restart_task(void *cls);
305 301
306 302
307/** 303/**
@@ -310,87 +306,87 @@ restart_task (void *cls);
310 * @param cls handle to the helper process 306 * @param cls handle to the helper process
311 */ 307 */
312static void 308static void
313helper_read (void *cls) 309helper_read(void *cls)
314{ 310{
315 struct GNUNET_HELPER_Handle *h = cls; 311 struct GNUNET_HELPER_Handle *h = cls;
316 char buf[GNUNET_MAX_MESSAGE_SIZE] GNUNET_ALIGN; 312 char buf[GNUNET_MAX_MESSAGE_SIZE] GNUNET_ALIGN;
317 ssize_t t; 313 ssize_t t;
318 314
319 h->read_task = NULL; 315 h->read_task = NULL;
320 t = GNUNET_DISK_file_read (h->fh_from_helper, &buf, sizeof (buf)); 316 t = GNUNET_DISK_file_read(h->fh_from_helper, &buf, sizeof(buf));
321 if (t < 0) 317 if (t < 0)
322 {
323 /* On read-error, restart the helper */
324 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
325 _ ("Error reading from `%s': %s\n"),
326 h->binary_name,
327 strerror (errno));
328 if (NULL != h->exp_cb)
329 { 318 {
330 h->exp_cb (h->cb_cls); 319 /* On read-error, restart the helper */
331 GNUNET_HELPER_stop (h, GNUNET_NO); 320 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
321 _("Error reading from `%s': %s\n"),
322 h->binary_name,
323 strerror(errno));
324 if (NULL != h->exp_cb)
325 {
326 h->exp_cb(h->cb_cls);
327 GNUNET_HELPER_stop(h, GNUNET_NO);
328 return;
329 }
330 stop_helper(h, GNUNET_NO);
331 /* Restart the helper */
332 h->restart_task = GNUNET_SCHEDULER_add_delayed(
333 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS,
334 h->retry_back_off),
335 &restart_task,
336 h);
332 return; 337 return;
333 } 338 }
334 stop_helper (h, GNUNET_NO);
335 /* Restart the helper */
336 h->restart_task = GNUNET_SCHEDULER_add_delayed (
337 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
338 h->retry_back_off),
339 &restart_task,
340 h);
341 return;
342 }
343 if (0 == t) 339 if (0 == t)
344 {
345 /* this happens if the helper is shut down via a
346 signal, so it is not a "hard" error */
347 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
348 "Got 0 bytes from helper `%s' (EOF)\n",
349 h->binary_name);
350 if (NULL != h->exp_cb)
351 { 340 {
352 h->exp_cb (h->cb_cls); 341 /* this happens if the helper is shut down via a
353 GNUNET_HELPER_stop (h, GNUNET_NO); 342 signal, so it is not a "hard" error */
343 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
344 "Got 0 bytes from helper `%s' (EOF)\n",
345 h->binary_name);
346 if (NULL != h->exp_cb)
347 {
348 h->exp_cb(h->cb_cls);
349 GNUNET_HELPER_stop(h, GNUNET_NO);
350 return;
351 }
352 stop_helper(h, GNUNET_NO);
353 /* Restart the helper */
354 h->restart_task = GNUNET_SCHEDULER_add_delayed(
355 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS,
356 h->retry_back_off),
357 &restart_task,
358 h);
354 return; 359 return;
355 } 360 }
356 stop_helper (h, GNUNET_NO); 361 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
357 /* Restart the helper */ 362 "Got %u bytes from helper `%s'\n",
358 h->restart_task = GNUNET_SCHEDULER_add_delayed ( 363 (unsigned int)t,
359 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 364 h->binary_name);
360 h->retry_back_off), 365 h->read_task = GNUNET_SCHEDULER_add_read_file(GNUNET_TIME_UNIT_FOREVER_REL,
361 &restart_task, 366 h->fh_from_helper,
362 h); 367 &helper_read,
363 return; 368 h);
364 }
365 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
366 "Got %u bytes from helper `%s'\n",
367 (unsigned int) t,
368 h->binary_name);
369 h->read_task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
370 h->fh_from_helper,
371 &helper_read,
372 h);
373 if (GNUNET_SYSERR == 369 if (GNUNET_SYSERR ==
374 GNUNET_MST_from_buffer (h->mst, buf, t, GNUNET_NO, GNUNET_NO)) 370 GNUNET_MST_from_buffer(h->mst, buf, t, GNUNET_NO, GNUNET_NO))
375 {
376 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
377 _ ("Failed to parse inbound message from helper `%s'\n"),
378 h->binary_name);
379 if (NULL != h->exp_cb)
380 { 371 {
381 h->exp_cb (h->cb_cls); 372 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
382 GNUNET_HELPER_stop (h, GNUNET_NO); 373 _("Failed to parse inbound message from helper `%s'\n"),
374 h->binary_name);
375 if (NULL != h->exp_cb)
376 {
377 h->exp_cb(h->cb_cls);
378 GNUNET_HELPER_stop(h, GNUNET_NO);
379 return;
380 }
381 stop_helper(h, GNUNET_NO);
382 /* Restart the helper */
383 h->restart_task = GNUNET_SCHEDULER_add_delayed(
384 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS,
385 h->retry_back_off),
386 &restart_task,
387 h);
383 return; 388 return;
384 } 389 }
385 stop_helper (h, GNUNET_NO);
386 /* Restart the helper */
387 h->restart_task = GNUNET_SCHEDULER_add_delayed (
388 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
389 h->retry_back_off),
390 &restart_task,
391 h);
392 return;
393 }
394} 390}
395 391
396 392
@@ -400,55 +396,55 @@ helper_read (void *cls)
400 * @param h handle to the helper process 396 * @param h handle to the helper process
401 */ 397 */
402static void 398static void
403start_helper (struct GNUNET_HELPER_Handle *h) 399start_helper(struct GNUNET_HELPER_Handle *h)
404{ 400{
405 h->helper_in = 401 h->helper_in =
406 GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO); 402 GNUNET_DISK_pipe(GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO);
407 h->helper_out = 403 h->helper_out =
408 GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES); 404 GNUNET_DISK_pipe(GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES);
409 if ((h->helper_in == NULL) || (h->helper_out == NULL)) 405 if ((h->helper_in == NULL) || (h->helper_out == NULL))
410 { 406 {
411 /* out of file descriptors? try again later... */ 407 /* out of file descriptors? try again later... */
412 stop_helper (h, GNUNET_NO); 408 stop_helper(h, GNUNET_NO);
413 h->restart_task = GNUNET_SCHEDULER_add_delayed ( 409 h->restart_task = GNUNET_SCHEDULER_add_delayed(
414 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 410 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS,
415 h->retry_back_off), 411 h->retry_back_off),
416 &restart_task, 412 &restart_task,
417 h); 413 h);
418 return; 414 return;
419 } 415 }
420 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 416 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
421 "Starting HELPER process `%s'\n", 417 "Starting HELPER process `%s'\n",
422 h->binary_name); 418 h->binary_name);
423 h->fh_from_helper = 419 h->fh_from_helper =
424 GNUNET_DISK_pipe_handle (h->helper_out, GNUNET_DISK_PIPE_END_READ); 420 GNUNET_DISK_pipe_handle(h->helper_out, GNUNET_DISK_PIPE_END_READ);
425 h->fh_to_helper = 421 h->fh_to_helper =
426 GNUNET_DISK_pipe_handle (h->helper_in, GNUNET_DISK_PIPE_END_WRITE); 422 GNUNET_DISK_pipe_handle(h->helper_in, GNUNET_DISK_PIPE_END_WRITE);
427 h->helper_proc = GNUNET_OS_start_process_vap (h->with_control_pipe, 423 h->helper_proc = GNUNET_OS_start_process_vap(h->with_control_pipe,
428 GNUNET_OS_INHERIT_STD_ERR, 424 GNUNET_OS_INHERIT_STD_ERR,
429 h->helper_in, 425 h->helper_in,
430 h->helper_out, 426 h->helper_out,
431 NULL, 427 NULL,
432 h->binary_name, 428 h->binary_name,
433 h->binary_argv); 429 h->binary_argv);
434 if (NULL == h->helper_proc) 430 if (NULL == h->helper_proc)
435 { 431 {
436 /* failed to start process? try again later... */ 432 /* failed to start process? try again later... */
437 stop_helper (h, GNUNET_NO); 433 stop_helper(h, GNUNET_NO);
438 h->restart_task = GNUNET_SCHEDULER_add_delayed ( 434 h->restart_task = GNUNET_SCHEDULER_add_delayed(
439 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 435 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS,
440 h->retry_back_off), 436 h->retry_back_off),
441 &restart_task, 437 &restart_task,
442 h); 438 h);
443 return; 439 return;
444 } 440 }
445 GNUNET_DISK_pipe_close_end (h->helper_out, GNUNET_DISK_PIPE_END_WRITE); 441 GNUNET_DISK_pipe_close_end(h->helper_out, GNUNET_DISK_PIPE_END_WRITE);
446 GNUNET_DISK_pipe_close_end (h->helper_in, GNUNET_DISK_PIPE_END_READ); 442 GNUNET_DISK_pipe_close_end(h->helper_in, GNUNET_DISK_PIPE_END_READ);
447 if (NULL != h->mst) 443 if (NULL != h->mst)
448 h->read_task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 444 h->read_task = GNUNET_SCHEDULER_add_read_file(GNUNET_TIME_UNIT_FOREVER_REL,
449 h->fh_from_helper, 445 h->fh_from_helper,
450 &helper_read, 446 &helper_read,
451 h); 447 h);
452} 448}
453 449
454 450
@@ -458,16 +454,16 @@ start_helper (struct GNUNET_HELPER_Handle *h)
458 * @param cls handle to the helper process 454 * @param cls handle to the helper process
459 */ 455 */
460static void 456static void
461restart_task (void *cls) 457restart_task(void *cls)
462{ 458{
463 struct GNUNET_HELPER_Handle *h = cls; 459 struct GNUNET_HELPER_Handle *h = cls;
464 460
465 h->restart_task = NULL; 461 h->restart_task = NULL;
466 h->retry_back_off++; 462 h->retry_back_off++;
467 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 463 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
468 "Restarting helper with back-off %u\n", 464 "Restarting helper with back-off %u\n",
469 h->retry_back_off); 465 h->retry_back_off);
470 start_helper (h); 466 start_helper(h);
471} 467}
472 468
473 469
@@ -488,35 +484,35 @@ restart_task (void *cls)
488 * @return the new Handle, NULL on error 484 * @return the new Handle, NULL on error
489 */ 485 */
490struct GNUNET_HELPER_Handle * 486struct GNUNET_HELPER_Handle *
491GNUNET_HELPER_start (int with_control_pipe, 487GNUNET_HELPER_start(int with_control_pipe,
492 const char *binary_name, 488 const char *binary_name,
493 char *const binary_argv[], 489 char *const binary_argv[],
494 GNUNET_MessageTokenizerCallback cb, 490 GNUNET_MessageTokenizerCallback cb,
495 GNUNET_HELPER_ExceptionCallback exp_cb, 491 GNUNET_HELPER_ExceptionCallback exp_cb,
496 void *cb_cls) 492 void *cb_cls)
497{ 493{
498 struct GNUNET_HELPER_Handle *h; 494 struct GNUNET_HELPER_Handle *h;
499 unsigned int c; 495 unsigned int c;
500 496
501 h = GNUNET_new (struct GNUNET_HELPER_Handle); 497 h = GNUNET_new(struct GNUNET_HELPER_Handle);
502 h->with_control_pipe = with_control_pipe; 498 h->with_control_pipe = with_control_pipe;
503 /* Lookup in libexec path only if we are starting gnunet helpers */ 499 /* Lookup in libexec path only if we are starting gnunet helpers */
504 if (NULL != strstr (binary_name, "gnunet")) 500 if (NULL != strstr(binary_name, "gnunet"))
505 h->binary_name = GNUNET_OS_get_libexec_binary_path (binary_name); 501 h->binary_name = GNUNET_OS_get_libexec_binary_path(binary_name);
506 else 502 else
507 h->binary_name = GNUNET_strdup (binary_name); 503 h->binary_name = GNUNET_strdup(binary_name);
508 for (c = 0; NULL != binary_argv[c]; c++) 504 for (c = 0; NULL != binary_argv[c]; c++)
509 ; 505 ;
510 h->binary_argv = GNUNET_malloc (sizeof (char *) * (c + 1)); 506 h->binary_argv = GNUNET_malloc(sizeof(char *) * (c + 1));
511 for (c = 0; NULL != binary_argv[c]; c++) 507 for (c = 0; NULL != binary_argv[c]; c++)
512 h->binary_argv[c] = GNUNET_strdup (binary_argv[c]); 508 h->binary_argv[c] = GNUNET_strdup(binary_argv[c]);
513 h->binary_argv[c] = NULL; 509 h->binary_argv[c] = NULL;
514 h->cb_cls = cb_cls; 510 h->cb_cls = cb_cls;
515 if (NULL != cb) 511 if (NULL != cb)
516 h->mst = GNUNET_MST_create (cb, h->cb_cls); 512 h->mst = GNUNET_MST_create(cb, h->cb_cls);
517 h->exp_cb = exp_cb; 513 h->exp_cb = exp_cb;
518 h->retry_back_off = 0; 514 h->retry_back_off = 0;
519 start_helper (h); 515 start_helper(h);
520 return h; 516 return h;
521} 517}
522 518
@@ -527,32 +523,32 @@ GNUNET_HELPER_start (int with_control_pipe,
527 * @param h the helper handle to free 523 * @param h the helper handle to free
528 */ 524 */
529void 525void
530GNUNET_HELPER_destroy (struct GNUNET_HELPER_Handle *h) 526GNUNET_HELPER_destroy(struct GNUNET_HELPER_Handle *h)
531{ 527{
532 unsigned int c; 528 unsigned int c;
533 struct GNUNET_HELPER_SendHandle *sh; 529 struct GNUNET_HELPER_SendHandle *sh;
534 530
535 if (NULL != h->write_task) 531 if (NULL != h->write_task)
536 { 532 {
537 GNUNET_SCHEDULER_cancel (h->write_task); 533 GNUNET_SCHEDULER_cancel(h->write_task);
538 h->write_task = NULL; 534 h->write_task = NULL;
539 } 535 }
540 GNUNET_assert (NULL == h->read_task); 536 GNUNET_assert(NULL == h->read_task);
541 GNUNET_assert (NULL == h->restart_task); 537 GNUNET_assert(NULL == h->restart_task);
542 while (NULL != (sh = h->sh_head)) 538 while (NULL != (sh = h->sh_head))
543 { 539 {
544 GNUNET_CONTAINER_DLL_remove (h->sh_head, h->sh_tail, sh); 540 GNUNET_CONTAINER_DLL_remove(h->sh_head, h->sh_tail, sh);
545 if (NULL != sh->cont) 541 if (NULL != sh->cont)
546 sh->cont (sh->cont_cls, GNUNET_SYSERR); 542 sh->cont(sh->cont_cls, GNUNET_SYSERR);
547 GNUNET_free (sh); 543 GNUNET_free(sh);
548 } 544 }
549 if (NULL != h->mst) 545 if (NULL != h->mst)
550 GNUNET_MST_destroy (h->mst); 546 GNUNET_MST_destroy(h->mst);
551 GNUNET_free (h->binary_name); 547 GNUNET_free(h->binary_name);
552 for (c = 0; h->binary_argv[c] != NULL; c++) 548 for (c = 0; h->binary_argv[c] != NULL; c++)
553 GNUNET_free (h->binary_argv[c]); 549 GNUNET_free(h->binary_argv[c]);
554 GNUNET_free (h->binary_argv); 550 GNUNET_free(h->binary_argv);
555 GNUNET_free (h); 551 GNUNET_free(h);
556} 552}
557 553
558 554
@@ -564,11 +560,11 @@ GNUNET_HELPER_destroy (struct GNUNET_HELPER_Handle *h)
564 * stdin; #GNUNET_NO to signal termination by sending SIGTERM to helper 560 * stdin; #GNUNET_NO to signal termination by sending SIGTERM to helper
565 */ 561 */
566void 562void
567GNUNET_HELPER_stop (struct GNUNET_HELPER_Handle *h, int soft_kill) 563GNUNET_HELPER_stop(struct GNUNET_HELPER_Handle *h, int soft_kill)
568{ 564{
569 h->exp_cb = NULL; 565 h->exp_cb = NULL;
570 stop_helper (h, soft_kill); 566 stop_helper(h, soft_kill);
571 GNUNET_HELPER_destroy (h); 567 GNUNET_HELPER_destroy(h);
572} 568}
573 569
574 570
@@ -578,7 +574,7 @@ GNUNET_HELPER_stop (struct GNUNET_HELPER_Handle *h, int soft_kill)
578 * @param cls handle to the helper process 574 * @param cls handle to the helper process
579 */ 575 */
580static void 576static void
581helper_write (void *cls) 577helper_write(void *cls)
582{ 578{
583 struct GNUNET_HELPER_Handle *h = cls; 579 struct GNUNET_HELPER_Handle *h = cls;
584 struct GNUNET_HELPER_SendHandle *sh; 580 struct GNUNET_HELPER_SendHandle *sh;
@@ -587,56 +583,56 @@ helper_write (void *cls)
587 583
588 h->write_task = NULL; 584 h->write_task = NULL;
589 if (NULL == (sh = h->sh_head)) 585 if (NULL == (sh = h->sh_head))
590 { 586 {
591 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Helper write had no work!\n"); 587 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Helper write had no work!\n");
592 return; /* how did this happen? */ 588 return; /* how did this happen? */
593 } 589 }
594 buf = (const char *) sh->msg; 590 buf = (const char *)sh->msg;
595 t = GNUNET_DISK_file_write (h->fh_to_helper, 591 t = GNUNET_DISK_file_write(h->fh_to_helper,
596 &buf[sh->wpos], 592 &buf[sh->wpos],
597 ntohs (sh->msg->size) - sh->wpos); 593 ntohs(sh->msg->size) - sh->wpos);
598 if (-1 == t) 594 if (-1 == t)
599 {
600 /* On write-error, restart the helper */
601 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
602 _ ("Error writing to `%s': %s\n"),
603 h->binary_name,
604 strerror (errno));
605 if (NULL != h->exp_cb)
606 { 595 {
607 h->exp_cb (h->cb_cls); 596 /* On write-error, restart the helper */
608 GNUNET_HELPER_stop (h, GNUNET_NO); 597 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
598 _("Error writing to `%s': %s\n"),
599 h->binary_name,
600 strerror(errno));
601 if (NULL != h->exp_cb)
602 {
603 h->exp_cb(h->cb_cls);
604 GNUNET_HELPER_stop(h, GNUNET_NO);
605 return;
606 }
607 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
608 "Stopping and restarting helper task!\n");
609 stop_helper(h, GNUNET_NO);
610 /* Restart the helper */
611 h->restart_task = GNUNET_SCHEDULER_add_delayed(
612 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS,
613 h->retry_back_off),
614 &restart_task,
615 h);
609 return; 616 return;
610 } 617 }
611 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 618 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
612 "Stopping and restarting helper task!\n"); 619 "Transmitted %u bytes to %s\n",
613 stop_helper (h, GNUNET_NO); 620 (unsigned int)t,
614 /* Restart the helper */ 621 h->binary_name);
615 h->restart_task = GNUNET_SCHEDULER_add_delayed (
616 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
617 h->retry_back_off),
618 &restart_task,
619 h);
620 return;
621 }
622 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
623 "Transmitted %u bytes to %s\n",
624 (unsigned int) t,
625 h->binary_name);
626 sh->wpos += t; 622 sh->wpos += t;
627 if (sh->wpos == ntohs (sh->msg->size)) 623 if (sh->wpos == ntohs(sh->msg->size))
628 { 624 {
629 GNUNET_CONTAINER_DLL_remove (h->sh_head, h->sh_tail, sh); 625 GNUNET_CONTAINER_DLL_remove(h->sh_head, h->sh_tail, sh);
630 if (NULL != sh->cont) 626 if (NULL != sh->cont)
631 sh->cont (sh->cont_cls, GNUNET_YES); 627 sh->cont(sh->cont_cls, GNUNET_YES);
632 GNUNET_free (sh); 628 GNUNET_free(sh);
633 } 629 }
634 if (NULL != h->sh_head) 630 if (NULL != h->sh_head)
635 h->write_task = 631 h->write_task =
636 GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, 632 GNUNET_SCHEDULER_add_write_file(GNUNET_TIME_UNIT_FOREVER_REL,
637 h->fh_to_helper, 633 h->fh_to_helper,
638 &helper_write, 634 &helper_write,
639 h); 635 h);
640} 636}
641 637
642 638
@@ -654,11 +650,11 @@ helper_write (void *cls)
654 * not be abortable) 650 * not be abortable)
655 */ 651 */
656struct GNUNET_HELPER_SendHandle * 652struct GNUNET_HELPER_SendHandle *
657GNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h, 653GNUNET_HELPER_send(struct GNUNET_HELPER_Handle *h,
658 const struct GNUNET_MessageHeader *msg, 654 const struct GNUNET_MessageHeader *msg,
659 int can_drop, 655 int can_drop,
660 GNUNET_HELPER_Continuation cont, 656 GNUNET_HELPER_Continuation cont,
661 void *cont_cls) 657 void *cont_cls)
662{ 658{
663 struct GNUNET_HELPER_SendHandle *sh; 659 struct GNUNET_HELPER_SendHandle *sh;
664 uint16_t mlen; 660 uint16_t mlen;
@@ -667,20 +663,20 @@ GNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h,
667 return NULL; 663 return NULL;
668 if ((GNUNET_YES == can_drop) && (NULL != h->sh_head)) 664 if ((GNUNET_YES == can_drop) && (NULL != h->sh_head))
669 return NULL; 665 return NULL;
670 mlen = ntohs (msg->size); 666 mlen = ntohs(msg->size);
671 sh = GNUNET_malloc (sizeof (struct GNUNET_HELPER_SendHandle) + mlen); 667 sh = GNUNET_malloc(sizeof(struct GNUNET_HELPER_SendHandle) + mlen);
672 sh->msg = (const struct GNUNET_MessageHeader *) &sh[1]; 668 sh->msg = (const struct GNUNET_MessageHeader *)&sh[1];
673 GNUNET_memcpy (&sh[1], msg, mlen); 669 GNUNET_memcpy(&sh[1], msg, mlen);
674 sh->h = h; 670 sh->h = h;
675 sh->cont = cont; 671 sh->cont = cont;
676 sh->cont_cls = cont_cls; 672 sh->cont_cls = cont_cls;
677 GNUNET_CONTAINER_DLL_insert_tail (h->sh_head, h->sh_tail, sh); 673 GNUNET_CONTAINER_DLL_insert_tail(h->sh_head, h->sh_tail, sh);
678 if (NULL == h->write_task) 674 if (NULL == h->write_task)
679 h->write_task = 675 h->write_task =
680 GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, 676 GNUNET_SCHEDULER_add_write_file(GNUNET_TIME_UNIT_FOREVER_REL,
681 h->fh_to_helper, 677 h->fh_to_helper,
682 &helper_write, 678 &helper_write,
683 h); 679 h);
684 680
685 return sh; 681 return sh;
686} 682}
@@ -693,22 +689,22 @@ GNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h,
693 * @param sh operation to cancel 689 * @param sh operation to cancel
694 */ 690 */
695void 691void
696GNUNET_HELPER_send_cancel (struct GNUNET_HELPER_SendHandle *sh) 692GNUNET_HELPER_send_cancel(struct GNUNET_HELPER_SendHandle *sh)
697{ 693{
698 struct GNUNET_HELPER_Handle *h = sh->h; 694 struct GNUNET_HELPER_Handle *h = sh->h;
699 695
700 sh->cont = NULL; 696 sh->cont = NULL;
701 sh->cont_cls = NULL; 697 sh->cont_cls = NULL;
702 if (0 == sh->wpos) 698 if (0 == sh->wpos)
703 {
704 GNUNET_CONTAINER_DLL_remove (h->sh_head, h->sh_tail, sh);
705 GNUNET_free (sh);
706 if (NULL == h->sh_head)
707 { 699 {
708 GNUNET_SCHEDULER_cancel (h->write_task); 700 GNUNET_CONTAINER_DLL_remove(h->sh_head, h->sh_tail, sh);
709 h->write_task = NULL; 701 GNUNET_free(sh);
702 if (NULL == h->sh_head)
703 {
704 GNUNET_SCHEDULER_cancel(h->write_task);
705 h->write_task = NULL;
706 }
710 } 707 }
711 }
712} 708}
713 709
714 710