aboutsummaryrefslogtreecommitdiff
path: root/src/util/helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/helper.c')
-rw-r--r--src/util/helper.c221
1 files changed, 108 insertions, 113 deletions
diff --git a/src/util/helper.c b/src/util/helper.c
index 7eb2ce6d9..aa452d22b 100644
--- a/src/util/helper.c
+++ b/src/util/helper.c
@@ -70,7 +70,6 @@ struct GNUNET_HELPER_SendHandle
70 * Current write position. 70 * Current write position.
71 */ 71 */
72 unsigned int wpos; 72 unsigned int wpos;
73
74}; 73};
75 74
76 75
@@ -177,17 +176,14 @@ struct GNUNET_HELPER_Handle
177 * @return #GNUNET_OK on success; #GNUNET_SYSERR on error 176 * @return #GNUNET_OK on success; #GNUNET_SYSERR on error
178 */ 177 */
179int 178int
180GNUNET_HELPER_kill (struct GNUNET_HELPER_Handle *h, 179GNUNET_HELPER_kill (struct GNUNET_HELPER_Handle *h, int soft_kill)
181 int soft_kill)
182{ 180{
183 struct GNUNET_HELPER_SendHandle *sh; 181 struct GNUNET_HELPER_SendHandle *sh;
184 int ret; 182 int ret;
185 183
186 while (NULL != (sh = h->sh_head)) 184 while (NULL != (sh = h->sh_head))
187 { 185 {
188 GNUNET_CONTAINER_DLL_remove (h->sh_head, 186 GNUNET_CONTAINER_DLL_remove (h->sh_head, h->sh_tail, sh);
189 h->sh_tail,
190 sh);
191 if (NULL != sh->cont) 187 if (NULL != sh->cont)
192 sh->cont (sh->cont_cls, GNUNET_NO); 188 sh->cont (sh->cont_cls, GNUNET_NO);
193 GNUNET_free (sh); 189 GNUNET_free (sh);
@@ -264,19 +260,14 @@ GNUNET_HELPER_wait (struct GNUNET_HELPER_Handle *h)
264 } 260 }
265 while (NULL != (sh = h->sh_head)) 261 while (NULL != (sh = h->sh_head))
266 { 262 {
267 GNUNET_CONTAINER_DLL_remove (h->sh_head, 263 GNUNET_CONTAINER_DLL_remove (h->sh_head, h->sh_tail, sh);
268 h->sh_tail,
269 sh);
270 if (NULL != sh->cont) 264 if (NULL != sh->cont)
271 sh->cont (sh->cont_cls, GNUNET_NO); 265 sh->cont (sh->cont_cls, GNUNET_NO);
272 GNUNET_free (sh); 266 GNUNET_free (sh);
273 } 267 }
274 /* purge MST buffer */ 268 /* purge MST buffer */
275 if (NULL != h->mst) 269 if (NULL != h->mst)
276 (void) GNUNET_MST_from_buffer (h->mst, 270 (void) GNUNET_MST_from_buffer (h->mst, NULL, 0, GNUNET_YES, GNUNET_NO);
277 NULL, 0,
278 GNUNET_YES,
279 GNUNET_NO);
280 return ret; 271 return ret;
281} 272}
282 273
@@ -289,8 +280,7 @@ GNUNET_HELPER_wait (struct GNUNET_HELPER_Handle *h)
289 * stdin; #GNUNET_NO to signal termination by sending SIGTERM to helper 280 * stdin; #GNUNET_NO to signal termination by sending SIGTERM to helper
290 */ 281 */
291static void 282static void
292stop_helper (struct GNUNET_HELPER_Handle *h, 283stop_helper (struct GNUNET_HELPER_Handle *h, int soft_kill)
293 int soft_kill)
294{ 284{
295 if (NULL != h->restart_task) 285 if (NULL != h->restart_task)
296 { 286 {
@@ -332,9 +322,9 @@ helper_read (void *cls)
332 { 322 {
333 /* On read-error, restart the helper */ 323 /* On read-error, restart the helper */
334 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 324 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
335 _("Error reading from `%s': %s\n"), 325 _ ("Error reading from `%s': %s\n"),
336 h->binary_name, 326 h->binary_name,
337 STRERROR (errno)); 327 strerror (errno));
338 if (NULL != h->exp_cb) 328 if (NULL != h->exp_cb)
339 { 329 {
340 h->exp_cb (h->cb_cls); 330 h->exp_cb (h->cb_cls);
@@ -343,9 +333,11 @@ helper_read (void *cls)
343 } 333 }
344 stop_helper (h, GNUNET_NO); 334 stop_helper (h, GNUNET_NO);
345 /* Restart the helper */ 335 /* Restart the helper */
346 h->restart_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 336 h->restart_task = GNUNET_SCHEDULER_add_delayed (
347 h->retry_back_off), 337 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
348 &restart_task, h); 338 h->retry_back_off),
339 &restart_task,
340 h);
349 return; 341 return;
350 } 342 }
351 if (0 == t) 343 if (0 == t)
@@ -353,8 +345,8 @@ helper_read (void *cls)
353 /* this happens if the helper is shut down via a 345 /* this happens if the helper is shut down via a
354 signal, so it is not a "hard" error */ 346 signal, so it is not a "hard" error */
355 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 347 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
356 "Got 0 bytes from helper `%s' (EOF)\n", 348 "Got 0 bytes from helper `%s' (EOF)\n",
357 h->binary_name); 349 h->binary_name);
358 if (NULL != h->exp_cb) 350 if (NULL != h->exp_cb)
359 { 351 {
360 h->exp_cb (h->cb_cls); 352 h->exp_cb (h->cb_cls);
@@ -363,28 +355,27 @@ helper_read (void *cls)
363 } 355 }
364 stop_helper (h, GNUNET_NO); 356 stop_helper (h, GNUNET_NO);
365 /* Restart the helper */ 357 /* Restart the helper */
366 h->restart_task 358 h->restart_task = GNUNET_SCHEDULER_add_delayed (
367 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 359 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
368 h->retry_back_off), 360 h->retry_back_off),
369 &restart_task, h); 361 &restart_task,
362 h);
370 return; 363 return;
371 } 364 }
372 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 365 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
373 "Got %u bytes from helper `%s'\n", 366 "Got %u bytes from helper `%s'\n",
374 (unsigned int) t, 367 (unsigned int) t,
375 h->binary_name); 368 h->binary_name);
376 h->read_task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 369 h->read_task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
377 h->fh_from_helper, 370 h->fh_from_helper,
378 &helper_read, h); 371 &helper_read,
372 h);
379 if (GNUNET_SYSERR == 373 if (GNUNET_SYSERR ==
380 GNUNET_MST_from_buffer (h->mst, 374 GNUNET_MST_from_buffer (h->mst, buf, t, GNUNET_NO, GNUNET_NO))
381 buf, t,
382 GNUNET_NO,
383 GNUNET_NO))
384 { 375 {
385 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 376 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
386 _("Failed to parse inbound message from helper `%s'\n"), 377 _ ("Failed to parse inbound message from helper `%s'\n"),
387 h->binary_name); 378 h->binary_name);
388 if (NULL != h->exp_cb) 379 if (NULL != h->exp_cb)
389 { 380 {
390 h->exp_cb (h->cb_cls); 381 h->exp_cb (h->cb_cls);
@@ -393,9 +384,11 @@ helper_read (void *cls)
393 } 384 }
394 stop_helper (h, GNUNET_NO); 385 stop_helper (h, GNUNET_NO);
395 /* Restart the helper */ 386 /* Restart the helper */
396 h->restart_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 387 h->restart_task = GNUNET_SCHEDULER_add_delayed (
397 h->retry_back_off), 388 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
398 &restart_task, h); 389 h->retry_back_off),
390 &restart_task,
391 h);
399 return; 392 return;
400 } 393 }
401} 394}
@@ -409,46 +402,53 @@ helper_read (void *cls)
409static void 402static void
410start_helper (struct GNUNET_HELPER_Handle *h) 403start_helper (struct GNUNET_HELPER_Handle *h)
411{ 404{
412 h->helper_in = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO); 405 h->helper_in =
413 h->helper_out = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES); 406 GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO);
414 if ( (h->helper_in == NULL) || (h->helper_out == NULL)) 407 h->helper_out =
408 GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES);
409 if ((h->helper_in == NULL) || (h->helper_out == NULL))
415 { 410 {
416 /* out of file descriptors? try again later... */ 411 /* out of file descriptors? try again later... */
417 stop_helper (h, GNUNET_NO); 412 stop_helper (h, GNUNET_NO);
418 h->restart_task = 413 h->restart_task = GNUNET_SCHEDULER_add_delayed (
419 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 414 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
420 h->retry_back_off), 415 h->retry_back_off),
421 &restart_task, h); 416 &restart_task,
417 h);
422 return; 418 return;
423 } 419 }
424 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 420 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
425 "Starting HELPER process `%s'\n", 421 "Starting HELPER process `%s'\n",
426 h->binary_name); 422 h->binary_name);
427 h->fh_from_helper = 423 h->fh_from_helper =
428 GNUNET_DISK_pipe_handle (h->helper_out, GNUNET_DISK_PIPE_END_READ); 424 GNUNET_DISK_pipe_handle (h->helper_out, GNUNET_DISK_PIPE_END_READ);
429 h->fh_to_helper = 425 h->fh_to_helper =
430 GNUNET_DISK_pipe_handle (h->helper_in, GNUNET_DISK_PIPE_END_WRITE); 426 GNUNET_DISK_pipe_handle (h->helper_in, GNUNET_DISK_PIPE_END_WRITE);
431 h->helper_proc = 427 h->helper_proc = GNUNET_OS_start_process_vap (h->with_control_pipe,
432 GNUNET_OS_start_process_vap (h->with_control_pipe, GNUNET_OS_INHERIT_STD_ERR, 428 GNUNET_OS_INHERIT_STD_ERR,
433 h->helper_in, h->helper_out, NULL, 429 h->helper_in,
434 h->binary_name, 430 h->helper_out,
435 h->binary_argv); 431 NULL,
432 h->binary_name,
433 h->binary_argv);
436 if (NULL == h->helper_proc) 434 if (NULL == h->helper_proc)
437 { 435 {
438 /* failed to start process? try again later... */ 436 /* failed to start process? try again later... */
439 stop_helper (h, GNUNET_NO); 437 stop_helper (h, GNUNET_NO);
440 h->restart_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 438 h->restart_task = GNUNET_SCHEDULER_add_delayed (
441 h->retry_back_off), 439 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
442 &restart_task, h); 440 h->retry_back_off),
441 &restart_task,
442 h);
443 return; 443 return;
444 } 444 }
445 GNUNET_DISK_pipe_close_end (h->helper_out, GNUNET_DISK_PIPE_END_WRITE); 445 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); 446 GNUNET_DISK_pipe_close_end (h->helper_in, GNUNET_DISK_PIPE_END_READ);
447 if (NULL != h->mst) 447 if (NULL != h->mst)
448 h->read_task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 448 h->read_task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
449 h->fh_from_helper, 449 h->fh_from_helper,
450 &helper_read, 450 &helper_read,
451 h); 451 h);
452} 452}
453 453
454 454
@@ -460,7 +460,7 @@ start_helper (struct GNUNET_HELPER_Handle *h)
460static void 460static void
461restart_task (void *cls) 461restart_task (void *cls)
462{ 462{
463 struct GNUNET_HELPER_Handle*h = cls; 463 struct GNUNET_HELPER_Handle *h = cls;
464 464
465 h->restart_task = NULL; 465 h->restart_task = NULL;
466 h->retry_back_off++; 466 h->retry_back_off++;
@@ -489,11 +489,11 @@ restart_task (void *cls)
489 */ 489 */
490struct GNUNET_HELPER_Handle * 490struct GNUNET_HELPER_Handle *
491GNUNET_HELPER_start (int with_control_pipe, 491GNUNET_HELPER_start (int with_control_pipe,
492 const char *binary_name, 492 const char *binary_name,
493 char *const binary_argv[], 493 char *const binary_argv[],
494 GNUNET_MessageTokenizerCallback cb, 494 GNUNET_MessageTokenizerCallback cb,
495 GNUNET_HELPER_ExceptionCallback exp_cb, 495 GNUNET_HELPER_ExceptionCallback exp_cb,
496 void *cb_cls) 496 void *cb_cls)
497{ 497{
498 struct GNUNET_HELPER_Handle *h; 498 struct GNUNET_HELPER_Handle *h;
499 unsigned int c; 499 unsigned int c;
@@ -505,15 +505,15 @@ GNUNET_HELPER_start (int with_control_pipe,
505 h->binary_name = GNUNET_OS_get_libexec_binary_path (binary_name); 505 h->binary_name = GNUNET_OS_get_libexec_binary_path (binary_name);
506 else 506 else
507 h->binary_name = GNUNET_strdup (binary_name); 507 h->binary_name = GNUNET_strdup (binary_name);
508 for (c = 0; NULL != binary_argv[c]; c++); 508 for (c = 0; NULL != binary_argv[c]; c++)
509 ;
509 h->binary_argv = GNUNET_malloc (sizeof (char *) * (c + 1)); 510 h->binary_argv = GNUNET_malloc (sizeof (char *) * (c + 1));
510 for (c = 0; NULL != binary_argv[c]; c++) 511 for (c = 0; NULL != binary_argv[c]; c++)
511 h->binary_argv[c] = GNUNET_strdup (binary_argv[c]); 512 h->binary_argv[c] = GNUNET_strdup (binary_argv[c]);
512 h->binary_argv[c] = NULL; 513 h->binary_argv[c] = NULL;
513 h->cb_cls = cb_cls; 514 h->cb_cls = cb_cls;
514 if (NULL != cb) 515 if (NULL != cb)
515 h->mst = GNUNET_MST_create (cb, 516 h->mst = GNUNET_MST_create (cb, h->cb_cls);
516 h->cb_cls);
517 h->exp_cb = exp_cb; 517 h->exp_cb = exp_cb;
518 h->retry_back_off = 0; 518 h->retry_back_off = 0;
519 start_helper (h); 519 start_helper (h);
@@ -541,9 +541,7 @@ GNUNET_HELPER_destroy (struct GNUNET_HELPER_Handle *h)
541 GNUNET_assert (NULL == h->restart_task); 541 GNUNET_assert (NULL == h->restart_task);
542 while (NULL != (sh = h->sh_head)) 542 while (NULL != (sh = h->sh_head))
543 { 543 {
544 GNUNET_CONTAINER_DLL_remove (h->sh_head, 544 GNUNET_CONTAINER_DLL_remove (h->sh_head, h->sh_tail, sh);
545 h->sh_tail,
546 sh);
547 if (NULL != sh->cont) 545 if (NULL != sh->cont)
548 sh->cont (sh->cont_cls, GNUNET_SYSERR); 546 sh->cont (sh->cont_cls, GNUNET_SYSERR);
549 GNUNET_free (sh); 547 GNUNET_free (sh);
@@ -566,8 +564,7 @@ GNUNET_HELPER_destroy (struct GNUNET_HELPER_Handle *h)
566 * stdin; #GNUNET_NO to signal termination by sending SIGTERM to helper 564 * stdin; #GNUNET_NO to signal termination by sending SIGTERM to helper
567 */ 565 */
568void 566void
569GNUNET_HELPER_stop (struct GNUNET_HELPER_Handle *h, 567GNUNET_HELPER_stop (struct GNUNET_HELPER_Handle *h, int soft_kill)
570 int soft_kill)
571{ 568{
572 h->exp_cb = NULL; 569 h->exp_cb = NULL;
573 stop_helper (h, soft_kill); 570 stop_helper (h, soft_kill);
@@ -591,21 +588,20 @@ helper_write (void *cls)
591 h->write_task = NULL; 588 h->write_task = NULL;
592 if (NULL == (sh = h->sh_head)) 589 if (NULL == (sh = h->sh_head))
593 { 590 {
594 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 591 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Helper write had no work!\n");
595 "Helper write had no work!\n");
596 return; /* how did this happen? */ 592 return; /* how did this happen? */
597 } 593 }
598 buf = (const char*) sh->msg; 594 buf = (const char *) sh->msg;
599 t = GNUNET_DISK_file_write (h->fh_to_helper, 595 t = GNUNET_DISK_file_write (h->fh_to_helper,
600 &buf[sh->wpos], 596 &buf[sh->wpos],
601 ntohs (sh->msg->size) - sh->wpos); 597 ntohs (sh->msg->size) - sh->wpos);
602 if (-1 == t) 598 if (-1 == t)
603 { 599 {
604 /* On write-error, restart the helper */ 600 /* On write-error, restart the helper */
605 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 601 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
606 _("Error writing to `%s': %s\n"), 602 _ ("Error writing to `%s': %s\n"),
607 h->binary_name, 603 h->binary_name,
608 STRERROR (errno)); 604 strerror (errno));
609 if (NULL != h->exp_cb) 605 if (NULL != h->exp_cb)
610 { 606 {
611 h->exp_cb (h->cb_cls); 607 h->exp_cb (h->cb_cls);
@@ -613,33 +609,34 @@ helper_write (void *cls)
613 return; 609 return;
614 } 610 }
615 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 611 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
616 "Stopping and restarting helper task!\n"); 612 "Stopping and restarting helper task!\n");
617 stop_helper (h, GNUNET_NO); 613 stop_helper (h, GNUNET_NO);
618 /* Restart the helper */ 614 /* Restart the helper */
619 h->restart_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 615 h->restart_task = GNUNET_SCHEDULER_add_delayed (
620 h->retry_back_off), 616 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
621 &restart_task, h); 617 h->retry_back_off),
618 &restart_task,
619 h);
622 return; 620 return;
623 } 621 }
624 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 622 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
625 "Transmitted %u bytes to %s\n", 623 "Transmitted %u bytes to %s\n",
626 (unsigned int) t, 624 (unsigned int) t,
627 h->binary_name); 625 h->binary_name);
628 sh->wpos += t; 626 sh->wpos += t;
629 if (sh->wpos == ntohs (sh->msg->size)) 627 if (sh->wpos == ntohs (sh->msg->size))
630 { 628 {
631 GNUNET_CONTAINER_DLL_remove (h->sh_head, 629 GNUNET_CONTAINER_DLL_remove (h->sh_head, h->sh_tail, sh);
632 h->sh_tail,
633 sh);
634 if (NULL != sh->cont) 630 if (NULL != sh->cont)
635 sh->cont (sh->cont_cls, GNUNET_YES); 631 sh->cont (sh->cont_cls, GNUNET_YES);
636 GNUNET_free (sh); 632 GNUNET_free (sh);
637 } 633 }
638 if (NULL != h->sh_head) 634 if (NULL != h->sh_head)
639 h->write_task = GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, 635 h->write_task =
640 h->fh_to_helper, 636 GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
641 &helper_write, 637 h->fh_to_helper,
642 h); 638 &helper_write,
639 h);
643} 640}
644 641
645 642
@@ -658,34 +655,32 @@ helper_write (void *cls)
658 */ 655 */
659struct GNUNET_HELPER_SendHandle * 656struct GNUNET_HELPER_SendHandle *
660GNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h, 657GNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h,
661 const struct GNUNET_MessageHeader *msg, 658 const struct GNUNET_MessageHeader *msg,
662 int can_drop, 659 int can_drop,
663 GNUNET_HELPER_Continuation cont, 660 GNUNET_HELPER_Continuation cont,
664 void *cont_cls) 661 void *cont_cls)
665{ 662{
666 struct GNUNET_HELPER_SendHandle *sh; 663 struct GNUNET_HELPER_SendHandle *sh;
667 uint16_t mlen; 664 uint16_t mlen;
668 665
669 if (NULL == h->fh_to_helper) 666 if (NULL == h->fh_to_helper)
670 return NULL; 667 return NULL;
671 if ( (GNUNET_YES == can_drop) && 668 if ((GNUNET_YES == can_drop) && (NULL != h->sh_head))
672 (NULL != h->sh_head) )
673 return NULL; 669 return NULL;
674 mlen = ntohs (msg->size); 670 mlen = ntohs (msg->size);
675 sh = GNUNET_malloc (sizeof (struct GNUNET_HELPER_SendHandle) + mlen); 671 sh = GNUNET_malloc (sizeof (struct GNUNET_HELPER_SendHandle) + mlen);
676 sh->msg = (const struct GNUNET_MessageHeader*) &sh[1]; 672 sh->msg = (const struct GNUNET_MessageHeader *) &sh[1];
677 GNUNET_memcpy (&sh[1], msg, mlen); 673 GNUNET_memcpy (&sh[1], msg, mlen);
678 sh->h = h; 674 sh->h = h;
679 sh->cont = cont; 675 sh->cont = cont;
680 sh->cont_cls = cont_cls; 676 sh->cont_cls = cont_cls;
681 GNUNET_CONTAINER_DLL_insert_tail (h->sh_head, 677 GNUNET_CONTAINER_DLL_insert_tail (h->sh_head, h->sh_tail, sh);
682 h->sh_tail,
683 sh);
684 if (NULL == h->write_task) 678 if (NULL == h->write_task)
685 h->write_task = GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, 679 h->write_task =
686 h->fh_to_helper, 680 GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
687 &helper_write, 681 h->fh_to_helper,
688 h); 682 &helper_write,
683 h);
689 684
690 return sh; 685 return sh;
691} 686}