GNUnet 0.22.2
os_priority.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet
3 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2011 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet 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 Affero General Public License for more details.
14
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/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
28#include "platform.h"
29#include "gnunet_util_lib.h"
30#include "disk.h"
31#include <unistr.h>
32
33#define LOG(kind, ...) GNUNET_log_from (kind, "util-os-priority", __VA_ARGS__)
34
35#define LOG_STRERROR(kind, syscall) \
36 GNUNET_log_from_strerror (kind, "util-os-priority", syscall)
37
38#define LOG_STRERROR_FILE(kind, syscall, filename) \
39 GNUNET_log_from_strerror_file (kind, "util-os-priority", syscall, filename)
40
41#define GNUNET_OS_CONTROL_PIPE "GNUNET_OS_CONTROL_PIPE"
42
43
45{
49 pid_t pid;
50
56};
57
58
63
68
73
74
80static void
81shutdown_pch (void *cls)
82{
83 struct GNUNET_DISK_FileHandle *control_pipe = cls;
84
86 pch = NULL;
87 GNUNET_DISK_file_close (control_pipe);
88 control_pipe = NULL;
89}
90
91
97static void
99{
100 struct GNUNET_DISK_FileHandle *control_pipe = cls;
101 char sig;
102 char *pipe_fd;
103 ssize_t ret;
104
105 pch = NULL;
106 ret = GNUNET_DISK_file_read (control_pipe, &sig, sizeof(sig));
107 if (sizeof(sig) != ret)
108 {
109 if (-1 == ret)
110 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "GNUNET_DISK_file_read");
111 LOG (GNUNET_ERROR_TYPE_DEBUG, "Closing control pipe\n");
112 GNUNET_DISK_file_close (control_pipe);
113 control_pipe = NULL;
115 spch = NULL;
116 return;
117 }
118 pipe_fd = getenv (GNUNET_OS_CONTROL_PIPE);
119 GNUNET_assert ((NULL == pipe_fd) || (strlen (pipe_fd) <= 0));
121 "Got control code %d from parent via pipe %s\n",
122 sig,
123 pipe_fd);
125 control_pipe,
127 control_pipe);
128 GNUNET_SIGNAL_raise ((int) sig);
129}
130
131
132void
134{
135 const char *env_buf;
136 char *env_buf_end;
137 struct GNUNET_DISK_FileHandle *control_pipe;
138 uint64_t pipe_fd;
139
140 (void) cls;
141 if (NULL != pch)
142 {
143 /* already done, we've been called twice... */
144 GNUNET_break (0);
145 return;
146 }
147 env_buf = getenv (GNUNET_OS_CONTROL_PIPE);
148 if ((NULL == env_buf) || (strlen (env_buf) <= 0))
149 {
151 "Not installing a handler because $%s is empty\n",
153 setenv (GNUNET_OS_CONTROL_PIPE, "", 1);
154 return;
155 }
156 errno = 0;
157 pipe_fd = strtoull (env_buf, &env_buf_end, 16);
158 if ((0 != errno) || (env_buf == env_buf_end))
159 {
160 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "strtoull", env_buf);
161 setenv (GNUNET_OS_CONTROL_PIPE, "", 1);
162 return;
163 }
164 if (pipe_fd >= FD_SETSIZE)
165 {
167 "GNUNET_OS_CONTROL_PIPE `%s' contains garbage?\n",
168 env_buf);
169 setenv (GNUNET_OS_CONTROL_PIPE, "", 1);
170 return;
171 }
172
173 control_pipe = GNUNET_DISK_get_handle_from_int_fd ((int) pipe_fd);
174
175 if (NULL == control_pipe)
176 {
178 setenv (GNUNET_OS_CONTROL_PIPE, "", 1);
179 return;
180 }
182 "Adding parent control handler pipe `%s' to the scheduler\n",
183 env_buf);
185 control_pipe,
187 control_pipe);
189 setenv (GNUNET_OS_CONTROL_PIPE, "", 1);
190}
191
192
201struct GNUNET_OS_Process *
203{
205 return &current_process;
206}
207
208
209int
211 int sig)
212{
213 int ret;
214 char csig;
215
216 csig = (char) sig;
217 if (NULL != proc->control_pipe)
218 {
220 "Sending signal %d to pid: %u via pipe\n",
221 sig,
222 proc->pid);
223 ret = GNUNET_DISK_file_write (proc->control_pipe, &csig, sizeof(csig));
224 if (sizeof(csig) == ret)
225 return 0;
226 }
227 /* pipe failed or non-existent, try other methods */
228 switch (sig)
229 {
230 case SIGHUP:
231 case SIGINT:
232 case SIGKILL:
233 case SIGTERM:
234#if (SIGTERM != GNUNET_TERM_SIG)
235 case GNUNET_TERM_SIG:
236#endif
238 "Sending signal %d to pid: %u via system call\n",
239 sig,
240 proc->pid);
241 return kill (proc->pid, sig);
242 default:
244 "Sending signal %d to pid: %u via system call\n",
245 sig,
246 proc->pid);
247 return kill (proc->pid, sig);
248 }
249}
250
251
252pid_t
254{
255 return proc->pid;
256}
257
258
259void
261{
262 if (NULL != proc->control_pipe)
264
265 GNUNET_free (proc);
266}
267
268
276static void
277open_dev_null (int target_fd,
278 int flags)
279{
280 int fd;
281
282 fd = open ("/dev/null", flags);
283 if (-1 == fd)
284 {
286 return;
287 }
288 if (fd == target_fd)
289 return;
290 if (-1 == dup2 (fd, target_fd))
291 {
293 GNUNET_break (0 == close (fd));
294 return;
295 }
296 GNUNET_break (0 == close (fd));
297}
298
299
316static struct GNUNET_OS_Process *
318 struct GNUNET_DISK_PipeHandle *pipe_stdin,
319 struct GNUNET_DISK_PipeHandle *pipe_stdout,
320 struct GNUNET_DISK_PipeHandle *pipe_stderr,
321 const int *lsocks,
322 const char *filename,
323 char *const argv[])
324{
325 pid_t ret;
326 char fds[16];
327 struct GNUNET_OS_Process *gnunet_proc;
328 struct GNUNET_DISK_FileHandle *childpipe_read;
329 struct GNUNET_DISK_FileHandle *childpipe_write;
330 int childpipe_read_fd;
331 int i;
332 int j;
333 int k;
334 int tgt;
335 int flags;
336 int *lscp;
337 unsigned int ls;
338 int fd_stdout_write;
339 int fd_stdout_read;
340 int fd_stderr_write;
341 int fd_stderr_read;
342 int fd_stdin_read;
343 int fd_stdin_write;
344
345 if (GNUNET_SYSERR ==
347 return NULL; /* not executable */
348 if (0 != (std_inheritance & GNUNET_OS_USE_PIPE_CONTROL))
349 {
350 struct GNUNET_DISK_PipeHandle *childpipe;
351 int dup_childpipe_read_fd = -1;
352
354 if (NULL == childpipe)
355 return NULL;
356 childpipe_read =
358 childpipe_write =
360 GNUNET_DISK_pipe_close (childpipe);
361 if ((NULL == childpipe_read) || (NULL == childpipe_write) ||
363 &childpipe_read_fd)) ||
364 (-1 == (dup_childpipe_read_fd = dup (childpipe_read_fd))))
365 {
366 if (NULL != childpipe_read)
367 GNUNET_DISK_file_close (childpipe_read);
368 if (NULL != childpipe_write)
369 GNUNET_DISK_file_close (childpipe_write);
370 if (0 <= dup_childpipe_read_fd)
371 GNUNET_break (0 == close (dup_childpipe_read_fd));
372 return NULL;
373 }
374 childpipe_read_fd = dup_childpipe_read_fd;
375 GNUNET_DISK_file_close (childpipe_read);
376 }
377 else
378 {
379 childpipe_write = NULL;
380 childpipe_read_fd = -1;
381 }
382 if (NULL != pipe_stdin)
383 {
385 GNUNET_OK ==
388 &fd_stdin_read));
390 GNUNET_OK ==
393 &fd_stdin_write));
394 }
395 if (NULL != pipe_stdout)
396 {
398 GNUNET_OK ==
401 &fd_stdout_write));
403 GNUNET_OK ==
406 &fd_stdout_read));
407 }
408 if (NULL != pipe_stderr)
409 {
411 GNUNET_OK ==
414 &fd_stderr_read));
416 GNUNET_OK ==
419 &fd_stderr_write));
420 }
421 lscp = NULL;
422 ls = 0;
423 if (NULL != lsocks)
424 {
425 i = 0;
426 while (-1 != (k = lsocks[i++]))
427 GNUNET_array_append (lscp, ls, k);
428 GNUNET_array_append (lscp, ls, -1);
429 }
430#if DARWIN
431 /* see https://web.archive.org/web/20150924082249/gnunet.org/vfork */
432 #pragma GCC diagnostic push
433 #pragma GCC diagnostic ignored "-Wdeprecated"
434 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
435 #pragma clang diagnostic push
436 #pragma clang diagnostic ignored "-Wdeprecated"
437 ret = vfork ();
438 #pragma clang diagnostic pop
439 #pragma GCC diagnostic pop
440#else
441 ret = fork ();
442#endif
443 if (-1 == ret)
444 {
445 int eno = errno;
447 GNUNET_array_grow (lscp, ls, 0);
448 if (NULL != childpipe_write)
449 GNUNET_DISK_file_close (childpipe_write);
450 if (0 <= childpipe_read_fd)
451 GNUNET_break (0 == close (childpipe_read_fd));
452 errno = eno;
453 return NULL;
454 }
455 if (0 != ret)
456 {
457 unsetenv (GNUNET_OS_CONTROL_PIPE);
458 gnunet_proc = GNUNET_new (struct GNUNET_OS_Process);
459 gnunet_proc->pid = ret;
460 gnunet_proc->control_pipe = childpipe_write;
461 if (0 != (std_inheritance & GNUNET_OS_USE_PIPE_CONTROL))
462 {
463 GNUNET_break (0 == close (childpipe_read_fd));
464 }
465 GNUNET_array_grow (lscp, ls, 0);
466 return gnunet_proc;
467 }
468 if (0 <= childpipe_read_fd)
469 {
470 char fdbuf[100];
471#ifndef DARWIN
472 /* due to vfork, we must NOT free memory on DARWIN! */
473 GNUNET_DISK_file_close (childpipe_write);
474#endif
475 snprintf (fdbuf, 100, "%x", childpipe_read_fd);
476 setenv (GNUNET_OS_CONTROL_PIPE, fdbuf, 1);
477 }
478 else
479 unsetenv (GNUNET_OS_CONTROL_PIPE);
480 if (NULL != pipe_stdin)
481 {
482 GNUNET_break (0 == close (fd_stdin_write));
483 if (-1 == dup2 (fd_stdin_read, 0))
485 GNUNET_break (0 == close (fd_stdin_read));
486 }
487 else if (0 == (std_inheritance & GNUNET_OS_INHERIT_STD_IN))
488 {
489 GNUNET_break (0 == close (0));
490 open_dev_null (0, O_RDONLY);
491 }
492 if (NULL != pipe_stdout)
493 {
494 GNUNET_break (0 == close (fd_stdout_read));
495 if (-1 == dup2 (fd_stdout_write, 1))
497 GNUNET_break (0 == close (fd_stdout_write));
498 }
499 else if (0 == (std_inheritance & GNUNET_OS_INHERIT_STD_OUT))
500 {
501 GNUNET_break (0 == close (1));
502 open_dev_null (1, O_WRONLY);
503 }
504 if (NULL != pipe_stderr)
505 {
506 GNUNET_break (0 == close (fd_stderr_read));
507 if (-1 == dup2 (fd_stderr_write, 2))
509 GNUNET_break (0 == close (fd_stderr_write));
510 }
511 else if (0 == (std_inheritance & GNUNET_OS_INHERIT_STD_ERR))
512 {
513 GNUNET_break (0 == close (2));
514 open_dev_null (2, O_WRONLY);
515 }
516 if (NULL != lscp)
517 {
518 /* read systemd documentation... */
519 i = 0;
520 tgt = 3;
521 while (-1 != lscp[i])
522 {
523 j = i + 1;
524 while (-1 != lscp[j])
525 {
526 if (lscp[j] == tgt)
527 {
528 /* dup away */
529 k = dup (lscp[j]);
530 GNUNET_assert (-1 != k);
531 GNUNET_assert (0 == close (lscp[j]));
532 lscp[j] = k;
533 break;
534 }
535 j++;
536 }
537 if (lscp[i] != tgt)
538 {
539 /* Bury any existing FD, no matter what; they should all be closed
540 * on exec anyway and the important ones have been dup'ed away */
541 GNUNET_break (0 == close (tgt));
542 GNUNET_assert (-1 != dup2 (lscp[i], tgt));
543 }
544 /* unset close-on-exec flag */
545 flags = fcntl (tgt, F_GETFD);
546 GNUNET_assert (flags >= 0);
547 flags &= ~FD_CLOEXEC;
548 fflush (stderr);
549 (void) fcntl (tgt, F_SETFD, flags);
550 tgt++;
551 i++;
552 }
553 GNUNET_snprintf (fds, sizeof(fds), "%u", i);
554 setenv ("LISTEN_FDS", fds, 1);
555 }
556#ifndef DARWIN
557 /* due to vfork, we must NOT free memory on DARWIN! */
558 GNUNET_array_grow (lscp, ls, 0);
559#endif
560 execvp (filename, argv);
562 _exit (1);
563}
564
565
566struct GNUNET_OS_Process *
568 struct GNUNET_DISK_PipeHandle *pipe_stdin,
569 struct GNUNET_DISK_PipeHandle *pipe_stdout,
570 struct GNUNET_DISK_PipeHandle *pipe_stderr,
571 const char *filename,
572 char *const argv[])
573{
574 return start_process (std_inheritance,
575 pipe_stdin,
576 pipe_stdout,
577 pipe_stderr,
578 NULL,
579 filename,
580 argv);
581}
582
583
584struct GNUNET_OS_Process *
586 struct GNUNET_DISK_PipeHandle *pipe_stdin,
587 struct GNUNET_DISK_PipeHandle *pipe_stdout,
588 struct GNUNET_DISK_PipeHandle *pipe_stderr,
589 const char *filename,
590 va_list va)
591{
592 struct GNUNET_OS_Process *ret;
593 va_list ap;
594 char **argv;
595 int argc;
596
597 argc = 0;
598 va_copy (ap, va);
599 while (NULL != va_arg (ap, char *))
600 argc++;
601 va_end (ap);
602 argv = GNUNET_malloc (sizeof(char *) * (argc + 1));
603 argc = 0;
604 va_copy (ap, va);
605 while (NULL != (argv[argc] = va_arg (ap, char *)))
606 argc++;
607 va_end (ap);
608 ret = GNUNET_OS_start_process_vap (std_inheritance,
609 pipe_stdin,
610 pipe_stdout,
611 pipe_stderr,
612 filename,
613 argv);
614 GNUNET_free (argv);
615 return ret;
616}
617
618
619struct GNUNET_OS_Process *
621 struct GNUNET_DISK_PipeHandle *pipe_stdin,
622 struct GNUNET_DISK_PipeHandle *pipe_stdout,
623 struct GNUNET_DISK_PipeHandle *pipe_stderr,
624 const char *filename,
625 ...)
626{
627 struct GNUNET_OS_Process *ret;
628 va_list ap;
629
630 va_start (ap, filename);
631 ret = GNUNET_OS_start_process_va (std_inheritance,
632 pipe_stdin,
633 pipe_stdout,
634 pipe_stderr,
635 filename,
636 ap);
637 va_end (ap);
638 return ret;
639}
640
641
642struct GNUNET_OS_Process *
644 const int *lsocks,
645 const char *filename,
646 char *const argv[])
647{
648 return start_process (std_inheritance,
649 NULL,
650 NULL,
651 NULL,
652 lsocks,
653 filename,
654 argv);
655}
656
657
658struct GNUNET_OS_Process *
660 const int *lsocks,
661 const char *filename,
662 ...)
663{
664 va_list ap;
665 char **argv;
666 unsigned int argv_size;
667 const char *arg;
668 const char *rpos;
669 char *pos;
670 char *cp;
671 const char *last;
672 struct GNUNET_OS_Process *proc;
673 char *binary_path;
674 int quote_on;
675 unsigned int i;
676 size_t len;
677
678 argv_size = 1;
679 va_start (ap, filename);
680 arg = filename;
681 last = NULL;
682 do
683 {
684 rpos = arg;
685 quote_on = 0;
686 while ('\0' != *rpos)
687 {
688 if ('"' == *rpos)
689 {
690 if (1 == quote_on)
691 quote_on = 0;
692 else
693 quote_on = 1;
694 }
695 if ((' ' == *rpos) && (0 == quote_on))
696 {
697 if (NULL != last)
698 argv_size++;
699 last = NULL;
700 rpos++;
701 while (' ' == *rpos)
702 rpos++;
703 }
704 if ((NULL == last) && ('\0' != *rpos)) // FIXME: == or !=?
705 last = rpos;
706 if ('\0' != *rpos)
707 rpos++;
708 }
709 if (NULL != last)
710 argv_size++;
711 }
712 while (NULL != (arg = (va_arg (ap, const char *))));
713 va_end (ap);
714
715 argv = GNUNET_malloc (argv_size * sizeof(char *));
716 argv_size = 0;
717 va_start (ap, filename);
718 arg = filename;
719 last = NULL;
720 do
721 {
722 cp = GNUNET_strdup (arg);
723 quote_on = 0;
724 pos = cp;
725 while ('\0' != *pos)
726 {
727 if ('"' == *pos)
728 {
729 if (1 == quote_on)
730 quote_on = 0;
731 else
732 quote_on = 1;
733 }
734 if ((' ' == *pos) && (0 == quote_on))
735 {
736 *pos = '\0';
737 if (NULL != last)
738 argv[argv_size++] = GNUNET_strdup (last);
739 last = NULL;
740 pos++;
741 while (' ' == *pos)
742 pos++;
743 }
744 if ((NULL == last) && ('\0' != *pos)) // FIXME: == or !=?
745 last = pos;
746 if ('\0' != *pos)
747 pos++;
748 }
749 if (NULL != last)
750 argv[argv_size++] = GNUNET_strdup (last);
751 last = NULL;
752 GNUNET_free (cp);
753 }
754 while (NULL != (arg = (va_arg (ap, const char *))));
755 va_end (ap);
756 argv[argv_size] = NULL;
757
758 for (i = 0; i < argv_size; i++)
759 {
760 len = strlen (argv[i]);
761 if ((argv[i][0] == '"') && (argv[i][len - 1] == '"'))
762 {
763 memmove (&argv[i][0], &argv[i][1], len - 2);
764 argv[i][len - 2] = '\0';
765 }
766 }
767 binary_path = argv[0];
768 proc = GNUNET_OS_start_process_v (std_inheritance,
769 lsocks,
770 binary_path,
771 argv);
772 while (argv_size > 0)
773 GNUNET_free_nz (argv[--argv_size]);
774 GNUNET_free (argv);
775 return proc;
776}
777
778
792 unsigned long *code,
793 int options)
794{
795 int status;
796 int ret;
797
798 GNUNET_assert (0 != proc);
799 ret = waitpid (proc->pid,
800 &status,
801 options);
802 if (ret < 0)
803 {
805 "waitpid");
806 return GNUNET_SYSERR;
807 }
808 if (0 == ret)
809 {
811 *code = 0;
812 return GNUNET_NO;
813 }
814 if (proc->pid != ret)
815 {
817 "waitpid");
818 return GNUNET_SYSERR;
819 }
820 if (WIFEXITED (status))
821 {
823 *code = WEXITSTATUS (status);
824 }
825 else if (WIFSIGNALED (status))
826 {
828 *code = WTERMSIG (status);
829 }
830 else if (WIFSTOPPED (status))
831 {
833 *code = WSTOPSIG (status);
834 }
835#ifdef WIFCONTINUED
836 else if (WIFCONTINUED (status))
837 {
839 *code = 0;
840 }
841#endif
842 else
843 {
845 *code = 0;
846 }
847
848 return GNUNET_OK;
849}
850
851
855 unsigned long *code)
856{
857 return process_status (proc, type, code, WNOHANG);
858}
859
860
864 unsigned long *code)
865{
866 return process_status (proc, type, code, 0);
867}
868
869
872{
873 pid_t pid = proc->pid;
874 pid_t ret;
875
876 while ((pid != (ret = waitpid (pid, NULL, 0))) && (EINTR == errno))
877 ;
878 if (pid != ret)
879 {
881 "waitpid");
882 return GNUNET_SYSERR;
883 }
884 return GNUNET_OK;
885}
886
887
892{
897
902
907
912
916 void *proc_cls;
917
921 char buf[1024];
922
927
932
936 size_t off;
937};
938
939
940void
942{
943 if (NULL != cmd->proc)
944 {
945 GNUNET_assert (NULL != cmd->rtask);
947 }
948 (void) GNUNET_OS_process_kill (cmd->eip, SIGKILL);
952 GNUNET_free (cmd);
953}
954
955
961static void
962cmd_read (void *cls)
963{
964 struct GNUNET_OS_CommandHandle *cmd = cls;
965 const struct GNUNET_SCHEDULER_TaskContext *tc;
967 char *end;
968 ssize_t ret;
969
970 cmd->rtask = NULL;
973 {
974 /* timeout */
975 proc = cmd->proc;
976 cmd->proc = NULL;
977 proc (cmd->proc_cls, NULL);
978 return;
979 }
981 &cmd->buf[cmd->off],
982 sizeof(cmd->buf) - cmd->off);
983 if (ret <= 0)
984 {
985 if ((cmd->off > 0) && (cmd->off < sizeof(cmd->buf)))
986 {
987 cmd->buf[cmd->off] = '\0';
988 cmd->proc (cmd->proc_cls, cmd->buf);
989 }
990 proc = cmd->proc;
991 cmd->proc = NULL;
992 proc (cmd->proc_cls, NULL);
993 return;
994 }
995 end = memchr (&cmd->buf[cmd->off], '\n', ret);
996 cmd->off += ret;
997 while (NULL != end)
998 {
999 *end = '\0';
1000 cmd->proc (cmd->proc_cls, cmd->buf);
1001 memmove (cmd->buf, end + 1, cmd->off - (end + 1 - cmd->buf));
1002 cmd->off -= (end + 1 - cmd->buf);
1003 end = memchr (cmd->buf, '\n', cmd->off);
1004 }
1005 cmd->rtask =
1007 cmd->timeout),
1008 cmd->r,
1009 &cmd_read,
1010 cmd);
1011}
1012
1013
1016 void *proc_cls,
1018 const char *binary,
1019 ...)
1020{
1021 struct GNUNET_OS_CommandHandle *cmd;
1022 struct GNUNET_OS_Process *eip;
1023 struct GNUNET_DISK_PipeHandle *opipe;
1024 va_list ap;
1025
1027 if (NULL == opipe)
1028 return NULL;
1029 va_start (ap, binary);
1030 /* redirect stdout, don't inherit stderr/stdin */
1031 eip =
1033 NULL,
1034 opipe,
1035 NULL,
1036 binary,
1037 ap);
1038 va_end (ap);
1039 if (NULL == eip)
1040 {
1041 GNUNET_DISK_pipe_close (opipe);
1042 return NULL;
1043 }
1045 cmd = GNUNET_new (struct GNUNET_OS_CommandHandle);
1047 cmd->eip = eip;
1048 cmd->opipe = opipe;
1049 cmd->proc = proc;
1050 cmd->proc_cls = proc_cls;
1053 return cmd;
1054}
1055
1056
1057/* end of os_priority.c */
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
enum GNUNET_GenericReturnValue GNUNET_DISK_internal_file_handle_(const struct GNUNET_DISK_FileHandle *fh, int *dst)
Retrieve OS file handle.
Definition: disk.c:1619
Internal DISK related helper functions.
char * getenv()
static int ret
Final status code.
Definition: gnunet-arm.c:93
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
Definition: gnunet-arm.c:118
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:33
static char * filename
static uint32_t type
Type string converted to DNS type value.
static struct GNUNET_NETWORK_Handle * ls
Listen socket for STUN processing.
Definition: gnunet-nat.c:85
static int status
The program status; 0 for success.
Definition: gnunet-nse.c:39
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
const struct GNUNET_DISK_FileHandle * GNUNET_DISK_pipe_handle(const struct GNUNET_DISK_PipeHandle *p, enum GNUNET_DISK_PipeEnd n)
Get the handle to a particular pipe end.
Definition: disk.c:1602
struct GNUNET_DISK_FileHandle * GNUNET_DISK_pipe_detach_end(struct GNUNET_DISK_PipeHandle *p, enum GNUNET_DISK_PipeEnd end)
Detaches one of the ends from the pipe.
Definition: disk.c:1545
ssize_t GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
Definition: disk.c:682
struct GNUNET_DISK_PipeHandle * GNUNET_DISK_pipe(enum GNUNET_DISK_PipeFlags pf)
Creates an interprocess channel.
Definition: disk.c:1425
enum GNUNET_GenericReturnValue GNUNET_DISK_pipe_close(struct GNUNET_DISK_PipeHandle *p)
Closes an interprocess channel.
Definition: disk.c:1572
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1289
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_int_fd(int fno)
Get a handle from a native integer FD.
Definition: disk.c:1311
ssize_t GNUNET_DISK_file_read(const struct GNUNET_DISK_FileHandle *h, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: disk.c:646
enum GNUNET_GenericReturnValue GNUNET_DISK_pipe_close_end(struct GNUNET_DISK_PipeHandle *p, enum GNUNET_DISK_PipeEnd end)
Closes one half of an interprocess channel.
Definition: disk.c:1519
@ GNUNET_DISK_PF_NONE
No special options, use non-blocking read/write operations.
@ GNUNET_DISK_PF_BLOCKING_RW
Configure both pipe ends for blocking operations if set.
@ GNUNET_DISK_PIPE_END_WRITE
The writing-end of a pipe.
@ GNUNET_DISK_PIPE_END_READ
The reading-end of a pipe.
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_array_append(arr, len, element)
Append an element to an array (growing the array by one).
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_free_nz(ptr)
Wrapper around free.
int GNUNET_NETWORK_fdset_handle_isset(const struct GNUNET_NETWORK_FDSet *fds, const struct GNUNET_DISK_FileHandle *h)
Check if a file handle is part of an fd set.
Definition: network.c:1127
void(* GNUNET_OS_LineProcessor)(void *cls, const char *line)
Type of a function to process a line of output.
struct GNUNET_OS_Process * GNUNET_OS_start_process(enum GNUNET_OS_InheritStdioFlags std_inheritance, struct GNUNET_DISK_PipeHandle *pipe_stdin, struct GNUNET_DISK_PipeHandle *pipe_stdout, struct GNUNET_DISK_PipeHandle *pipe_stderr, const char *filename,...)
Start a process.
Definition: os_priority.c:620
GNUNET_OS_InheritStdioFlags
Flags that determine which of the standard streams should be inherited by the child process.
Definition: gnunet_os_lib.h:73
struct GNUNET_OS_Process * GNUNET_OS_start_process_v(enum GNUNET_OS_InheritStdioFlags std_inheritance, const int *lsocks, const char *filename, char *const argv[])
Start a process.
Definition: os_priority.c:643
struct GNUNET_OS_Process * GNUNET_OS_process_current()
Get process structure for current process.
Definition: os_priority.c:202
enum GNUNET_GenericReturnValue GNUNET_OS_process_wait_status(struct GNUNET_OS_Process *proc, enum GNUNET_OS_ProcessStatusType *type, unsigned long *code)
Retrieve the status of a process, waiting on it if dead.
Definition: os_priority.c:862
void GNUNET_OS_install_parent_control_handler(void *cls)
Connects this process to its parent via pipe; essentially, the parent control handler will read signa...
Definition: os_priority.c:133
void GNUNET_OS_command_stop(struct GNUNET_OS_CommandHandle *cmd)
Stop/kill a command.
Definition: os_priority.c:941
struct GNUNET_OS_CommandHandle * GNUNET_OS_command_run(GNUNET_OS_LineProcessor proc, void *proc_cls, struct GNUNET_TIME_Relative timeout, const char *binary,...)
Run the given command line and call the given function for each line of the output.
Definition: os_priority.c:1015
struct GNUNET_OS_Process * GNUNET_OS_start_process_s(enum GNUNET_OS_InheritStdioFlags std_inheritance, const int *lsocks, const char *filename,...)
Start a process.
Definition: os_priority.c:659
pid_t GNUNET_OS_process_get_pid(struct GNUNET_OS_Process *proc)
Get the pid of the process in question.
Definition: os_priority.c:253
GNUNET_OS_ProcessStatusType
Process status types.
void GNUNET_OS_process_destroy(struct GNUNET_OS_Process *proc)
Cleans up process structure contents (OS-dependent) and deallocates it.
Definition: os_priority.c:260
enum GNUNET_GenericReturnValue GNUNET_OS_check_helper_binary(const char *binary, bool check_suid, const char *params)
Check whether an executable exists and possibly if the suid bit is set on the file.
int GNUNET_OS_process_kill(struct GNUNET_OS_Process *proc, int sig)
Sends a signal to the process.
Definition: os_priority.c:210
enum GNUNET_GenericReturnValue GNUNET_OS_process_status(struct GNUNET_OS_Process *proc, enum GNUNET_OS_ProcessStatusType *type, unsigned long *code)
Retrieve the status of a process.
Definition: os_priority.c:853
enum GNUNET_GenericReturnValue GNUNET_OS_process_wait(struct GNUNET_OS_Process *proc)
Wait for a process to terminate.
Definition: os_priority.c:871
struct GNUNET_OS_Process * GNUNET_OS_start_process_va(enum GNUNET_OS_InheritStdioFlags std_inheritance, struct GNUNET_DISK_PipeHandle *pipe_stdin, struct GNUNET_DISK_PipeHandle *pipe_stdout, struct GNUNET_DISK_PipeHandle *pipe_stderr, const char *filename, va_list va)
Start a process.
Definition: os_priority.c:585
struct GNUNET_OS_Process * GNUNET_OS_start_process_vap(enum GNUNET_OS_InheritStdioFlags std_inheritance, struct GNUNET_DISK_PipeHandle *pipe_stdin, struct GNUNET_DISK_PipeHandle *pipe_stdout, struct GNUNET_DISK_PipeHandle *pipe_stderr, const char *filename, char *const argv[])
Start a process.
Definition: os_priority.c:567
@ GNUNET_OS_INHERIT_STD_IN
When this flag is set, the child process will inherit stdin of the parent.
Definition: gnunet_os_lib.h:83
@ GNUNET_OS_INHERIT_STD_OUT
When this flag is set, the child process will inherit stdout of the parent.
Definition: gnunet_os_lib.h:89
@ GNUNET_OS_INHERIT_STD_ERR
When this flag is set, the child process will inherit stderr of the parent.
Definition: gnunet_os_lib.h:95
@ GNUNET_OS_INHERIT_STD_NONE
No standard streams should be inherited.
Definition: gnunet_os_lib.h:77
@ GNUNET_OS_USE_PIPE_CONTROL
Should a pipe be used to send signals to the child?
@ GNUNET_OS_PROCESS_SIGNALED
The process was killed by a signal.
@ GNUNET_OS_PROCESS_EXITED
The process exited with a return code.
@ GNUNET_OS_PROCESS_UNKNOWN
The process is not known to the OS (or at least not one of our children).
@ GNUNET_OS_PROCESS_RUNNING
The process is still running.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_file(struct GNUNET_TIME_Relative delay, const struct GNUNET_DISK_FileHandle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition: scheduler.c:1661
const struct GNUNET_SCHEDULER_TaskContext * GNUNET_SCHEDULER_get_task_context(void)
Obtain the reasoning why the current task was started.
Definition: scheduler.c:758
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1339
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:980
void GNUNET_SIGNAL_raise(const int sig)
Raise the given signal by calling the installed signal handlers.
Definition: signal.c:98
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:406
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:316
#define GNUNET_OS_CONTROL_PIPE
Definition: os_priority.c:41
static void parent_control_handler(void *cls)
This handler is called when there are control data to be read on the pipe.
Definition: os_priority.c:98
static struct GNUNET_OS_Process current_process
Handle for 'this' process.
Definition: os_priority.c:62
static struct GNUNET_SCHEDULER_Task * pch
Handle for the parent_control_handler() Task.
Definition: os_priority.c:67
#define LOG_STRERROR_FILE(kind, syscall, filename)
Definition: os_priority.c:38
static void shutdown_pch(void *cls)
This handler is called on shutdown to remove the pch.
Definition: os_priority.c:81
static void open_dev_null(int target_fd, int flags)
Open '/dev/null' and make the result the given file descriptor.
Definition: os_priority.c:277
static struct GNUNET_OS_Process * start_process(enum GNUNET_OS_InheritStdioFlags std_inheritance, struct GNUNET_DISK_PipeHandle *pipe_stdin, struct GNUNET_DISK_PipeHandle *pipe_stdout, struct GNUNET_DISK_PipeHandle *pipe_stderr, const int *lsocks, const char *filename, char *const argv[])
Start a process.
Definition: os_priority.c:317
static struct GNUNET_SCHEDULER_Task * spch
Handle for the shutdown_pch() Task.
Definition: os_priority.c:72
#define LOG(kind,...)
Definition: os_priority.c:33
#define LOG_STRERROR(kind, syscall)
Definition: os_priority.c:35
static void cmd_read(void *cls)
Read from the process and call the line processor.
Definition: os_priority.c:962
static enum GNUNET_GenericReturnValue process_status(struct GNUNET_OS_Process *proc, enum GNUNET_OS_ProcessStatusType *type, unsigned long *code, int options)
Retrieve the status of a process, waiting on it if dead.
Definition: os_priority.c:790
#define GNUNET_TERM_SIG
The termination signal.
Definition: platform.h:234
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:431
Handle used to access files (and pipes).
Handle used to manage a pipe.
Definition: disk.c:69
Handle to a command.
Definition: os_priority.c:892
struct GNUNET_DISK_PipeHandle * opipe
Handle to the output pipe.
Definition: os_priority.c:901
struct GNUNET_OS_Process * eip
Process handle.
Definition: os_priority.c:896
size_t off
Current read offset in buf.
Definition: os_priority.c:936
char buf[1024]
Buffer for the output.
Definition: os_priority.c:921
struct GNUNET_SCHEDULER_Task * rtask
Task reading from pipe.
Definition: os_priority.c:926
struct GNUNET_TIME_Absolute timeout
When to time out.
Definition: os_priority.c:931
void * proc_cls
Closure for proc.
Definition: os_priority.c:916
GNUNET_OS_LineProcessor proc
Function to call on each line of output.
Definition: os_priority.c:911
const struct GNUNET_DISK_FileHandle * r
Read-end of output pipe.
Definition: os_priority.c:906
pid_t pid
PID of the process.
Definition: os_priority.c:49
struct GNUNET_DISK_FileHandle * control_pipe
Pipe we use to signal the process.
Definition: os_priority.c:55
Context information passed to each scheduler task.
const struct GNUNET_NETWORK_FDSet * read_ready
Set of file descriptors ready for reading; note that additional bits may be set that were not in the ...
Entry in list of pending tasks.
Definition: scheduler.c:136
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.