GNUnet 0.26.2-32-gd298f7855
 
Loading...
Searching...
No Matches
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
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "disk.h"
29#include <unistr.h>
30
31#define LOG(kind, ...) GNUNET_log_from (kind, "util-os-priority", __VA_ARGS__)
32
33#define LOG_STRERROR(kind, syscall) \
34 GNUNET_log_from_strerror (kind, "util-os-priority", syscall)
35
36#define LOG_STRERROR_FILE(kind, syscall, filename) \
37 GNUNET_log_from_strerror_file (kind, "util-os-priority", syscall, \
38 filename)
39
40#define GNUNET_OS_CONTROL_PIPE "GNUNET_OS_CONTROL_PIPE"
41
42
56
57
62
67
72
73
79static void
80shutdown_pch (void *cls)
81{
82 struct GNUNET_DISK_FileHandle *control_pipe = cls;
83
85 pch = NULL;
86 GNUNET_DISK_file_close (control_pipe);
87 control_pipe = NULL;
88}
89
90
96static void
98{
99 struct GNUNET_DISK_FileHandle *control_pipe = cls;
100 char sig;
101 char *pipe_fd;
102 ssize_t ret;
103
104 pch = NULL;
105 ret = GNUNET_DISK_file_read (control_pipe, &sig, sizeof(sig));
106 if (sizeof(sig) != ret)
107 {
108 if (-1 == ret)
109 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "GNUNET_DISK_file_read");
110 LOG (GNUNET_ERROR_TYPE_DEBUG, "Closing control pipe\n");
111 GNUNET_DISK_file_close (control_pipe);
112 control_pipe = NULL;
114 spch = NULL;
115 return;
116 }
117 pipe_fd = getenv (GNUNET_OS_CONTROL_PIPE);
118 GNUNET_assert ((NULL == pipe_fd) || (strlen (pipe_fd) <= 0));
120 "Got control code %d from parent via pipe %s\n",
121 sig,
122 pipe_fd);
124 control_pipe,
126 control_pipe);
127 GNUNET_SIGNAL_raise ((int) sig);
128}
129
130
131void
133{
134 const char *env_buf;
135 char *env_buf_end;
136 struct GNUNET_DISK_FileHandle *control_pipe;
137 uint64_t pipe_fd;
138
139 (void) cls;
140 if (NULL != pch)
141 {
142 /* already done, we've been called twice... */
143 GNUNET_break (0);
144 return;
145 }
146 env_buf = getenv (GNUNET_OS_CONTROL_PIPE);
147 if ((NULL == env_buf) || (strlen (env_buf) <= 0))
148 {
150 "Not installing a handler because $%s is empty\n",
152 setenv (GNUNET_OS_CONTROL_PIPE, "", 1);
153 return;
154 }
155 errno = 0;
156 pipe_fd = strtoull (env_buf, &env_buf_end, 16);
157 if ((0 != errno) || (env_buf == env_buf_end))
158 {
159 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "strtoull", env_buf);
160 setenv (GNUNET_OS_CONTROL_PIPE, "", 1);
161 return;
162 }
163 if (pipe_fd >= FD_SETSIZE)
164 {
166 "GNUNET_OS_CONTROL_PIPE `%s' contains garbage?\n",
167 env_buf);
168 setenv (GNUNET_OS_CONTROL_PIPE, "", 1);
169 return;
170 }
171
172 control_pipe = GNUNET_DISK_get_handle_from_int_fd ((int) pipe_fd);
173
174 if (NULL == control_pipe)
175 {
177 setenv (GNUNET_OS_CONTROL_PIPE, "", 1);
178 return;
179 }
181 "Adding parent control handler pipe `%s' to the scheduler\n",
182 env_buf);
184 control_pipe,
186 control_pipe);
188 setenv (GNUNET_OS_CONTROL_PIPE, "", 1);
189}
190
191
200struct GNUNET_OS_Process *
206
207
208int
210 int sig)
211{
212 int ret;
213 char csig;
214
215 csig = (char) sig;
216 if (NULL != proc->control_pipe)
217 {
219 "Sending signal %d to pid: %u via pipe\n",
220 sig,
221 proc->pid);
222 ret = GNUNET_DISK_file_write (proc->control_pipe, &csig, sizeof(csig));
223 if (sizeof(csig) == ret)
224 return 0;
225 }
226 /* pipe failed or non-existent, try other methods */
227 switch (sig)
228 {
229 case SIGHUP:
230 case SIGINT:
231 case SIGKILL:
232 case SIGTERM:
233#if (SIGTERM != GNUNET_TERM_SIG)
234 case GNUNET_TERM_SIG:
235#endif
237 "Sending signal %d to pid: %u via system call\n",
238 sig,
239 proc->pid);
240 return kill (proc->pid, sig);
241 default:
243 "Sending signal %d to pid: %u via system call\n",
244 sig,
245 proc->pid);
246 return kill (proc->pid, sig);
247 }
248}
249
250
251pid_t
253{
254 return proc->pid;
255}
256
257
258void
260{
261 if (NULL != proc->control_pipe)
263
264 GNUNET_free (proc);
265}
266
267
275static void
276open_dev_null (int target_fd,
277 int flags)
278{
279 int fd;
280
281 fd = open ("/dev/null", flags);
282 if (-1 == fd)
283 {
285 return;
286 }
287 if (fd == target_fd)
288 return;
289 if (-1 == dup2 (fd, target_fd))
290 {
292 GNUNET_break (0 == close (fd));
293 return;
294 }
295 GNUNET_break (0 == close (fd));
296}
297
298
315static struct GNUNET_OS_Process *
317 struct GNUNET_DISK_PipeHandle *pipe_stdin,
318 struct GNUNET_DISK_PipeHandle *pipe_stdout,
319 struct GNUNET_DISK_PipeHandle *pipe_stderr,
320 const int *lsocks,
321 const char *filename,
322 char *const argv[])
323{
324 pid_t ret;
325 char fds[16];
326 struct GNUNET_OS_Process *gnunet_proc;
327 struct GNUNET_DISK_FileHandle *childpipe_read;
328 struct GNUNET_DISK_FileHandle *childpipe_write;
329 int childpipe_read_fd;
330 int i;
331 int j;
332 int k;
333 int tgt;
334 int flags;
335 int *lscp;
336 unsigned int ls;
337 int fd_stdout_write;
338 int fd_stdout_read;
339 int fd_stderr_write;
340 int fd_stderr_read;
341 int fd_stdin_read;
342 int fd_stdin_write;
343
344 if (GNUNET_SYSERR ==
346 return NULL; /* not executable */
347 if (0 != (std_inheritance & GNUNET_OS_USE_PIPE_CONTROL))
348 {
349 struct GNUNET_DISK_PipeHandle *childpipe;
350 int dup_childpipe_read_fd = -1;
351
353 if (NULL == childpipe)
354 return NULL;
355 childpipe_read =
357 childpipe_write =
359 GNUNET_DISK_pipe_close (childpipe);
360 if ((NULL == childpipe_read) || (NULL == childpipe_write) ||
362 &childpipe_read_fd)) ||
363 (-1 == (dup_childpipe_read_fd = dup (childpipe_read_fd))))
364 {
365 if (NULL != childpipe_read)
366 GNUNET_DISK_file_close (childpipe_read);
367 if (NULL != childpipe_write)
368 GNUNET_DISK_file_close (childpipe_write);
369 if (0 <= dup_childpipe_read_fd)
370 GNUNET_break (0 == close (dup_childpipe_read_fd));
371 return NULL;
372 }
373 childpipe_read_fd = dup_childpipe_read_fd;
374 GNUNET_DISK_file_close (childpipe_read);
375 }
376 else
377 {
378 childpipe_write = NULL;
379 childpipe_read_fd = -1;
380 }
381 if (NULL != pipe_stdin)
382 {
384 GNUNET_OK ==
387 &fd_stdin_read));
389 GNUNET_OK ==
392 &fd_stdin_write));
393 }
394 if (NULL != pipe_stdout)
395 {
397 GNUNET_OK ==
400 &fd_stdout_write));
402 GNUNET_OK ==
405 &fd_stdout_read));
406 }
407 if (NULL != pipe_stderr)
408 {
410 GNUNET_OK ==
413 &fd_stderr_read));
415 GNUNET_OK ==
418 &fd_stderr_write));
419 }
420 lscp = NULL;
421 ls = 0;
422 if (NULL != lsocks)
423 {
424 i = 0;
425 while (-1 != (k = lsocks[i++]))
426 GNUNET_array_append (lscp, ls, k);
427 GNUNET_array_append (lscp, ls, -1);
428 }
429#if DARWIN
430 /* see https://web.archive.org/web/20150924082249/gnunet.org/vfork */
431 #pragma GCC diagnostic push
432 #pragma GCC diagnostic ignored "-Wdeprecated"
433 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
434 #pragma clang diagnostic push
435 #pragma clang diagnostic ignored "-Wdeprecated"
436 ret = vfork ();
437 #pragma clang diagnostic pop
438 #pragma GCC diagnostic pop
439#else
440 ret = fork ();
441#endif
442 if (-1 == ret)
443 {
444 int eno = errno;
445
447 "fork");
448 GNUNET_array_grow (lscp,
449 ls,
450 0);
451 if (NULL != childpipe_write)
452 GNUNET_DISK_file_close (childpipe_write);
453 if (0 <= childpipe_read_fd)
454 GNUNET_break (0 == close (childpipe_read_fd));
455 errno = eno;
456 return NULL;
457 }
458 if (0 != ret)
459 {
460 unsetenv (GNUNET_OS_CONTROL_PIPE);
461 gnunet_proc = GNUNET_new (struct GNUNET_OS_Process);
462 gnunet_proc->pid = ret;
463 gnunet_proc->control_pipe = childpipe_write;
464 if (0 != (std_inheritance & GNUNET_OS_USE_PIPE_CONTROL))
465 {
466 GNUNET_break (0 == close (childpipe_read_fd));
467 }
468 GNUNET_array_grow (lscp, ls, 0);
469 return gnunet_proc;
470 }
471 if (0 <= childpipe_read_fd)
472 {
473 char fdbuf[100];
474#ifndef DARWIN
475 /* due to vfork, we must NOT free memory on DARWIN! */
476 GNUNET_DISK_file_close (childpipe_write);
477#endif
478 snprintf (fdbuf,
479 sizeof (fdbuf),
480 "%x",
481 childpipe_read_fd);
483 fdbuf,
484 1);
485 }
486 else
487 unsetenv (GNUNET_OS_CONTROL_PIPE);
488 if (NULL != pipe_stdin)
489 {
490 GNUNET_break (0 == close (fd_stdin_write));
491 if (-1 == dup2 (fd_stdin_read,
492 0))
494 "dup2");
495 GNUNET_break (0 == close (fd_stdin_read));
496 }
497 else if (0 == (std_inheritance & GNUNET_OS_INHERIT_STD_IN))
498 {
499 GNUNET_break (0 == close (0));
500 open_dev_null (0,
501 O_RDONLY);
502 }
503 if (NULL != pipe_stdout)
504 {
505 GNUNET_break (0 == close (fd_stdout_read));
506 if (-1 == dup2 (fd_stdout_write,
507 1))
509 "dup2");
510 GNUNET_break (0 ==
511 close (fd_stdout_write));
512 }
513 else if (0 == (std_inheritance & GNUNET_OS_INHERIT_STD_OUT))
514 {
515 GNUNET_break (0 == close (1));
516 open_dev_null (1,
517 O_WRONLY);
518 }
519 if (NULL != pipe_stderr)
520 {
521 GNUNET_break (0 == close (fd_stderr_read));
522 if (-1 == dup2 (fd_stderr_write,
523 2))
525 GNUNET_break (0 == close (fd_stderr_write));
526 }
527 else if (0 == (std_inheritance & GNUNET_OS_INHERIT_STD_ERR))
528 {
529 GNUNET_break (0 == close (2));
530 open_dev_null (2,
531 O_WRONLY);
532 }
533 if (NULL != lscp)
534 {
535 char *fdnames = GNUNET_strdup ("");
536
537 /* read systemd documentation... */
538 i = 0;
539 tgt = 3;
540 while (-1 != lscp[i])
541 {
542 j = i + 1;
543 while (-1 != lscp[j])
544 {
545 if (lscp[j] == tgt)
546 {
547 /* dup away */
548 k = dup (lscp[j]);
549 GNUNET_assert (-1 != k);
550 GNUNET_assert (0 == close (lscp[j]));
551 lscp[j] = k;
552 break;
553 }
554 j++;
555 }
556 if (lscp[i] != tgt)
557 {
558 /* Bury any existing FD, no matter what; they should all be closed
559 * on exec anyway and the important ones have been dup'ed away */
560 GNUNET_break (0 == close (tgt));
561 GNUNET_assert (-1 != dup2 (lscp[i],
562 tgt));
563 }
564 /* unset close-on-exec flag */
565 flags = fcntl (tgt,
566 F_GETFD);
567 GNUNET_assert (flags >= 0);
568 flags &= ~FD_CLOEXEC;
569 fflush (stderr);
570 (void) fcntl (tgt,
571 F_SETFD,
572 flags);
573 {
574 char *tmp;
575
576 GNUNET_asprintf (&tmp,
577 "%s:%d",
578 fdnames,
579 tgt);
580 GNUNET_free (fdnames);
581 fdnames = tmp;
582 }
583 tgt++;
584 i++;
585 }
586 GNUNET_snprintf (fds,
587 sizeof(fds),
588 "%u",
589 i);
590 setenv ("LISTEN_FDS",
591 fds,
592 1);
593 if (0 != strlen (fdnames))
594 setenv ("LISTEN_FDNAMES",
595 fdnames + 1, /* skip leading ':' */
596 1);
597 GNUNET_free (fdnames);
598 }
599#ifndef DARWIN
600 /* due to vfork, we must NOT free memory on DARWIN! */
601 GNUNET_array_grow (lscp,
602 ls,
603 0);
604#endif
605 execvp (filename,
606 argv);
608 "execvp",
609 filename);
610 _exit (1);
611}
612
613
614struct GNUNET_OS_Process *
616 struct GNUNET_DISK_PipeHandle *pipe_stdin,
617 struct GNUNET_DISK_PipeHandle *pipe_stdout,
618 struct GNUNET_DISK_PipeHandle *pipe_stderr,
619 const char *filename,
620 char *const argv[])
621{
622 return start_process (std_inheritance,
623 pipe_stdin,
624 pipe_stdout,
625 pipe_stderr,
626 NULL,
627 filename,
628 argv);
629}
630
631
632struct GNUNET_OS_Process *
634 struct GNUNET_DISK_PipeHandle *pipe_stdin,
635 struct GNUNET_DISK_PipeHandle *pipe_stdout,
636 struct GNUNET_DISK_PipeHandle *pipe_stderr,
637 const char *filename,
638 va_list va)
639{
640 struct GNUNET_OS_Process *ret;
641 va_list ap;
642 char **argv;
643 int argc;
644
645 argc = 0;
646 va_copy (ap, va);
647 while (NULL != va_arg (ap, char *))
648 argc++;
649 va_end (ap);
650 argv = GNUNET_malloc (sizeof(char *) * (argc + 1));
651 argc = 0;
652 va_copy (ap, va);
653 while (NULL != (argv[argc] = va_arg (ap, char *)))
654 argc++;
655 va_end (ap);
656 ret = GNUNET_OS_start_process_vap (std_inheritance,
657 pipe_stdin,
658 pipe_stdout,
659 pipe_stderr,
660 filename,
661 argv);
662 GNUNET_free (argv);
663 return ret;
664}
665
666
667struct GNUNET_OS_Process *
669 struct GNUNET_DISK_PipeHandle *pipe_stdin,
670 struct GNUNET_DISK_PipeHandle *pipe_stdout,
671 struct GNUNET_DISK_PipeHandle *pipe_stderr,
672 const char *filename,
673 ...)
674{
675 struct GNUNET_OS_Process *ret;
676 va_list ap;
677
678 va_start (ap, filename);
679 ret = GNUNET_OS_start_process_va (std_inheritance,
680 pipe_stdin,
681 pipe_stdout,
682 pipe_stderr,
683 filename,
684 ap);
685 va_end (ap);
686 return ret;
687}
688
689
690struct GNUNET_OS_Process *
692 const int *lsocks,
693 const char *filename,
694 char *const argv[])
695{
696 return start_process (std_inheritance,
697 NULL,
698 NULL,
699 NULL,
700 lsocks,
701 filename,
702 argv);
703}
704
705
706struct GNUNET_OS_Process *
708 const int *lsocks,
709 const char *filename,
710 ...)
711{
712 va_list ap;
713 char **argv;
714 unsigned int argv_size;
715 const char *arg;
716 const char *rpos;
717 char *pos;
718 char *cp;
719 const char *last;
720 struct GNUNET_OS_Process *proc;
721 char *binary_path;
722 int quote_on;
723 unsigned int i;
724 size_t len;
725
726 argv_size = 1;
727 va_start (ap, filename);
728 arg = filename;
729 last = NULL;
730 do
731 {
732 rpos = arg;
733 quote_on = 0;
734 while ('\0' != *rpos)
735 {
736 if ('"' == *rpos)
737 {
738 if (1 == quote_on)
739 quote_on = 0;
740 else
741 quote_on = 1;
742 }
743 if ((' ' == *rpos) && (0 == quote_on))
744 {
745 if (NULL != last)
746 argv_size++;
747 last = NULL;
748 rpos++;
749 while (' ' == *rpos)
750 rpos++;
751 }
752 if ((NULL == last) && ('\0' != *rpos)) // FIXME: == or !=?
753 last = rpos;
754 if ('\0' != *rpos)
755 rpos++;
756 }
757 if (NULL != last)
758 argv_size++;
759 }
760 while (NULL != (arg = (va_arg (ap, const char *))));
761 va_end (ap);
762
763 argv = GNUNET_malloc (argv_size * sizeof(char *));
764 argv_size = 0;
765 va_start (ap, filename);
766 arg = filename;
767 last = NULL;
768 do
769 {
770 cp = GNUNET_strdup (arg);
771 quote_on = 0;
772 pos = cp;
773 while ('\0' != *pos)
774 {
775 if ('"' == *pos)
776 {
777 if (1 == quote_on)
778 quote_on = 0;
779 else
780 quote_on = 1;
781 }
782 if ((' ' == *pos) && (0 == quote_on))
783 {
784 *pos = '\0';
785 if (NULL != last)
786 argv[argv_size++] = GNUNET_strdup (last);
787 last = NULL;
788 pos++;
789 while (' ' == *pos)
790 pos++;
791 }
792 if ((NULL == last) && ('\0' != *pos)) // FIXME: == or !=?
793 last = pos;
794 if ('\0' != *pos)
795 pos++;
796 }
797 if (NULL != last)
798 argv[argv_size++] = GNUNET_strdup (last);
799 last = NULL;
800 GNUNET_free (cp);
801 }
802 while (NULL != (arg = (va_arg (ap, const char *))));
803 va_end (ap);
804 argv[argv_size] = NULL;
805
806 for (i = 0; i < argv_size; i++)
807 {
808 len = strlen (argv[i]);
809 if ((argv[i][0] == '"') && (argv[i][len - 1] == '"'))
810 {
811 memmove (&argv[i][0], &argv[i][1], len - 2);
812 argv[i][len - 2] = '\0';
813 }
814 }
815 binary_path = argv[0];
816 proc = GNUNET_OS_start_process_v (std_inheritance,
817 lsocks,
818 binary_path,
819 argv);
820 while (argv_size > 0)
821 GNUNET_free_nz (argv[--argv_size]);
822 GNUNET_free (argv);
823 return proc;
824}
825
826
840 unsigned long *code,
841 int options)
842{
843 int status;
844 int ret;
845
846 GNUNET_assert (0 != proc);
847 ret = waitpid (proc->pid,
848 &status,
849 options);
850 if (ret < 0)
851 {
853 "waitpid");
854 return GNUNET_SYSERR;
855 }
856 if (0 == ret)
857 {
859 *code = 0;
860 return GNUNET_NO;
861 }
862 if (proc->pid != ret)
863 {
865 "waitpid");
866 return GNUNET_SYSERR;
867 }
868 if (WIFEXITED (status))
869 {
871 *code = WEXITSTATUS (status);
872 }
873 else if (WIFSIGNALED (status))
874 {
876 *code = WTERMSIG (status);
877 }
878 else if (WIFSTOPPED (status))
879 {
881 *code = WSTOPSIG (status);
882 }
883#ifdef WIFCONTINUED
884 else if (WIFCONTINUED (status))
885 {
887 *code = 0;
888 }
889#endif
890 else
891 {
893 *code = 0;
894 }
895
896 return GNUNET_OK;
897}
898
899
903 unsigned long *code)
904{
905 return process_status (proc, type, code, WNOHANG);
906}
907
908
912 unsigned long *code)
913{
914 return process_status (proc, type, code, 0);
915}
916
917
920{
921 pid_t pid = proc->pid;
922 pid_t ret;
923
924 while ((pid != (ret = waitpid (pid, NULL, 0))) && (EINTR == errno))
925 ;
926 if (pid != ret)
927 {
929 "waitpid");
930 return GNUNET_SYSERR;
931 }
932 return GNUNET_OK;
933}
934
935
986
987
988void
990{
991 if (NULL != cmd->proc)
992 {
993 GNUNET_assert (NULL != cmd->rtask);
995 }
996 (void) GNUNET_OS_process_kill (cmd->eip, SIGKILL);
1000 GNUNET_free (cmd);
1001}
1002
1003
1009static void
1010cmd_read (void *cls)
1011{
1012 struct GNUNET_OS_CommandHandle *cmd = cls;
1013 const struct GNUNET_SCHEDULER_TaskContext *tc;
1015 char *end;
1016 ssize_t ret;
1017
1018 cmd->rtask = NULL;
1021 {
1022 /* timeout */
1023 proc = cmd->proc;
1024 cmd->proc = NULL;
1025 proc (cmd->proc_cls, NULL);
1026 return;
1027 }
1028 ret = GNUNET_DISK_file_read (cmd->r,
1029 &cmd->buf[cmd->off],
1030 sizeof(cmd->buf) - cmd->off);
1031 if (ret <= 0)
1032 {
1033 if ((cmd->off > 0) && (cmd->off < sizeof(cmd->buf)))
1034 {
1035 cmd->buf[cmd->off] = '\0';
1036 cmd->proc (cmd->proc_cls, cmd->buf);
1037 }
1038 proc = cmd->proc;
1039 cmd->proc = NULL;
1040 proc (cmd->proc_cls, NULL);
1041 return;
1042 }
1043 end = memchr (&cmd->buf[cmd->off], '\n', ret);
1044 cmd->off += ret;
1045 while (NULL != end)
1046 {
1047 *end = '\0';
1048 cmd->proc (cmd->proc_cls, cmd->buf);
1049 memmove (cmd->buf, end + 1, cmd->off - (end + 1 - cmd->buf));
1050 cmd->off -= (end + 1 - cmd->buf);
1051 end = memchr (cmd->buf, '\n', cmd->off);
1052 }
1053 cmd->rtask =
1055 cmd->timeout),
1056 cmd->r,
1057 &cmd_read,
1058 cmd);
1059}
1060
1061
1064 void *proc_cls,
1066 const char *binary,
1067 ...)
1068{
1070 struct GNUNET_OS_Process *eip;
1071 struct GNUNET_DISK_PipeHandle *opipe;
1072 va_list ap;
1073
1075 if (NULL == opipe)
1076 return NULL;
1077 va_start (ap, binary);
1078 /* redirect stdout, don't inherit stderr/stdin */
1079 eip =
1081 NULL,
1082 opipe,
1083 NULL,
1084 binary,
1085 ap);
1086 va_end (ap);
1087 if (NULL == eip)
1088 {
1089 GNUNET_DISK_pipe_close (opipe);
1090 return NULL;
1091 }
1093 cmd = GNUNET_new (struct GNUNET_OS_CommandHandle);
1095 cmd->eip = eip;
1096 cmd->opipe = opipe;
1097 cmd->proc = proc;
1098 cmd->proc_cls = proc_cls;
1101 return cmd;
1102}
1103
1104
1105/* 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:1719
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 void start_process()
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:1702
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:1643
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:745
struct GNUNET_DISK_PipeHandle * GNUNET_DISK_pipe(enum GNUNET_DISK_PipeFlags pf)
Creates an interprocess channel.
Definition disk.c:1523
enum GNUNET_GenericReturnValue GNUNET_DISK_pipe_close(struct GNUNET_DISK_PipeHandle *p)
Closes an interprocess channel.
Definition disk.c:1670
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition disk.c:1386
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_int_fd(int fno)
Get a handle from a native integer FD.
Definition disk.c:1409
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:704
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:1617
@ 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
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#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.
GNUNET_OS_InheritStdioFlags
Flags that determine which of the standard streams should be inherited by the child process.
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.
struct GNUNET_OS_Process * GNUNET_OS_process_current()
Get process structure for current process.
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.
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...
void GNUNET_OS_command_stop(struct GNUNET_OS_CommandHandle *cmd)
Stop/kill a command.
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.
struct GNUNET_OS_Process * GNUNET_OS_start_process_s(enum GNUNET_OS_InheritStdioFlags std_inheritance, const int *lsocks, const char *filename,...)
Start a process.
pid_t GNUNET_OS_process_get_pid(struct GNUNET_OS_Process *proc)
Get the pid of the process in question.
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.
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.
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.
enum GNUNET_GenericReturnValue GNUNET_OS_process_wait(struct GNUNET_OS_Process *proc)
Wait for a process to terminate.
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.
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.
@ GNUNET_OS_INHERIT_STD_IN
When this flag is set, the child process will inherit stdin of the parent.
@ GNUNET_OS_INHERIT_STD_OUT
When this flag is set, the child process will inherit stdout of the parent.
@ GNUNET_OS_INHERIT_STD_ERR
When this flag is set, the child process will inherit stderr of the parent.
@ GNUNET_OS_INHERIT_STD_NONE
No standard streams should be inherited.
@ 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:1667
const struct GNUNET_SCHEDULER_TaskContext * GNUNET_SCHEDULER_get_task_context(void)
Obtain the reasoning why the current task was started.
Definition scheduler.c:764
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:1345
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
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:40
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:97
static struct GNUNET_OS_Process current_process
Handle for 'this' process.
Definition os_priority.c:61
static struct GNUNET_SCHEDULER_Task * pch
Handle for the parent_control_handler() Task.
Definition os_priority.c:66
#define LOG_STRERROR_FILE(kind, syscall, filename)
Definition os_priority.c:36
static void shutdown_pch(void *cls)
This handler is called on shutdown to remove the pch.
Definition os_priority.c:80
static void open_dev_null(int target_fd, int flags)
Open '/dev/null' and make the result the given file descriptor.
static struct GNUNET_SCHEDULER_Task * spch
Handle for the shutdown_pch() Task.
Definition os_priority.c:71
#define LOG(kind,...)
Definition os_priority.c:31
#define LOG_STRERROR(kind, syscall)
Definition os_priority.c:33
static void cmd_read(void *cls)
Read from the process and call the line processor.
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.
#define GNUNET_TERM_SIG
The termination signal.
Definition platform.h:235
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition scheduler.c:436
Handle used to access files (and pipes).
Handle used to manage a pipe.
Definition disk.c:69
Handle to a command.
struct GNUNET_DISK_PipeHandle * opipe
Handle to the output pipe.
struct GNUNET_OS_Process * eip
Process handle.
size_t off
Current read offset in buf.
char buf[1024]
Buffer for the output.
struct GNUNET_SCHEDULER_Task * rtask
Task reading from pipe.
struct GNUNET_TIME_Absolute timeout
When to time out.
void * proc_cls
Closure for proc.
GNUNET_OS_LineProcessor proc
Function to call on each line of output.
const struct GNUNET_DISK_FileHandle * r
Read-end of output pipe.
pid_t pid
PID of the process.
Definition os_priority.c:48
struct GNUNET_DISK_FileHandle * control_pipe
Pipe we use to signal the process.
Definition os_priority.c:54
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:141
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.