33#define LOG(kind, ...) GNUNET_log_from (kind, "util-os-priority", __VA_ARGS__)
35#define LOG_STRERROR(kind, syscall) \
36 GNUNET_log_from_strerror (kind, "util-os-priority", syscall)
38#define LOG_STRERROR_FILE(kind, syscall, filename) \
39 GNUNET_log_from_strerror_file (kind, "util-os-priority", syscall, \
42#define GNUNET_OS_CONTROL_PIPE "GNUNET_OS_CONTROL_PIPE"
108 if (
sizeof(sig) !=
ret)
120 GNUNET_assert ((NULL == pipe_fd) || (strlen (pipe_fd) <= 0));
122 "Got control code %d from parent via pipe %s\n",
149 if ((NULL == env_buf) || (strlen (env_buf) <= 0))
152 "Not installing a handler because $%s is empty\n",
158 pipe_fd = strtoull (env_buf, &env_buf_end, 16);
159 if ((0 != errno) || (env_buf == env_buf_end))
165 if (pipe_fd >= FD_SETSIZE)
168 "GNUNET_OS_CONTROL_PIPE `%s' contains garbage?\n",
176 if (NULL == control_pipe)
183 "Adding parent control handler pipe `%s' to the scheduler\n",
221 "Sending signal %d to pid: %u via pipe\n",
225 if (
sizeof(csig) ==
ret)
235#if (SIGTERM != GNUNET_TERM_SIG)
239 "Sending signal %d to pid: %u via system call\n",
242 return kill (proc->
pid, sig);
245 "Sending signal %d to pid: %u via system call\n",
248 return kill (proc->
pid, sig);
283 fd = open (
"/dev/null", flags);
291 if (-1 == dup2 (fd, target_fd))
331 int childpipe_read_fd;
352 int dup_childpipe_read_fd = -1;
355 if (NULL == childpipe)
362 if ((NULL == childpipe_read) || (NULL == childpipe_write) ||
364 &childpipe_read_fd)) ||
365 (-1 == (dup_childpipe_read_fd = dup (childpipe_read_fd))))
367 if (NULL != childpipe_read)
369 if (NULL != childpipe_write)
371 if (0 <= dup_childpipe_read_fd)
375 childpipe_read_fd = dup_childpipe_read_fd;
380 childpipe_write = NULL;
381 childpipe_read_fd = -1;
383 if (NULL != pipe_stdin)
396 if (NULL != pipe_stdout)
409 if (NULL != pipe_stderr)
427 while (-1 != (k = lsocks[i++]))
433 #pragma GCC diagnostic push
434 #pragma GCC diagnostic ignored "-Wdeprecated"
435 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
436 #pragma clang diagnostic push
437 #pragma clang diagnostic ignored "-Wdeprecated"
439 #pragma clang diagnostic pop
440 #pragma GCC diagnostic pop
453 if (NULL != childpipe_write)
455 if (0 <= childpipe_read_fd)
473 if (0 <= childpipe_read_fd)
490 if (NULL != pipe_stdin)
493 if (-1 == dup2 (fd_stdin_read,
505 if (NULL != pipe_stdout)
508 if (-1 == dup2 (fd_stdout_write,
513 close (fd_stdout_write));
521 if (NULL != pipe_stderr)
524 if (-1 == dup2 (fd_stderr_write,
542 while (-1 != lscp[i])
545 while (-1 != lscp[j])
570 flags &= ~FD_CLOEXEC;
592 setenv (
"LISTEN_FDS",
595 if (0 != strlen (fdnames))
596 setenv (
"LISTEN_FDNAMES",
649 while (NULL != va_arg (ap,
char *))
655 while (NULL != (argv[argc] = va_arg (ap,
char *)))
716 unsigned int argv_size;
736 while (
'\0' != *rpos)
745 if ((
' ' == *rpos) && (0 == quote_on))
754 if ((NULL == last) && (
'\0' != *rpos))
762 while (NULL != (
arg = (va_arg (ap,
const char *))));
784 if ((
' ' == *pos) && (0 == quote_on))
794 if ((NULL == last) && (
'\0' != *pos))
804 while (NULL != (
arg = (va_arg (ap,
const char *))));
806 argv[argv_size] = NULL;
808 for (i = 0; i < argv_size; i++)
810 len = strlen (argv[i]);
811 if ((argv[i][0] ==
'"') && (argv[i][len - 1] ==
'"'))
813 memmove (&argv[i][0], &argv[i][1], len - 2);
814 argv[i][len - 2] =
'\0';
817 binary_path = argv[0];
822 while (argv_size > 0)
873 *code = WEXITSTATUS (
status);
875 else if (WIFSIGNALED (
status))
878 *code = WTERMSIG (
status);
880 else if (WIFSTOPPED (
status))
883 *code = WSTOPSIG (
status);
886 else if (WIFCONTINUED (
status))
926 while ((
pid != (
ret = waitpid (
pid, NULL, 0))) && (EINTR == errno))
993 if (NULL != cmd->
proc)
1032 sizeof(cmd->
buf) - cmd->
off);
1035 if ((cmd->
off > 0) && (cmd->
off <
sizeof(cmd->
buf)))
1037 cmd->
buf[cmd->
off] =
'\0';
1053 end = memchr (cmd->
buf,
'\n', cmd->
off);
1079 va_start (ap, binary);
struct GNUNET_GETOPT_CommandLineOption options[]
enum GNUNET_GenericReturnValue GNUNET_DISK_internal_file_handle_(const struct GNUNET_DISK_FileHandle *fh, int *dst)
Retrieve OS file handle.
Internal DISK related helper functions.
static int ret
Final status code.
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
static int end
Set if we are to shutdown all services (including ARM).
static uint32_t type
Type string converted to DNS type value.
static struct GNUNET_NETWORK_Handle * ls
Listen socket for STUN processing.
static int status
The program status; 0 for success.
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.
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.
ssize_t GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
struct GNUNET_DISK_PipeHandle * GNUNET_DISK_pipe(enum GNUNET_DISK_PipeFlags pf)
Creates an interprocess channel.
enum GNUNET_GenericReturnValue GNUNET_DISK_pipe_close(struct GNUNET_DISK_PipeHandle *p)
Closes an interprocess channel.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_int_fd(int fno)
Get a handle from a native integer FD.
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.
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.
@ 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.
#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.
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...
const struct GNUNET_SCHEDULER_TaskContext * GNUNET_SCHEDULER_get_task_context(void)
Obtain the reasoning why the current task was started.
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,...
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
void GNUNET_SIGNAL_raise(const int sig)
Raise the given signal by calling the installed signal handlers.
#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?
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
#define GNUNET_OS_CONTROL_PIPE
static void parent_control_handler(void *cls)
This handler is called when there are control data to be read on the pipe.
static struct GNUNET_OS_Process current_process
Handle for 'this' process.
static struct GNUNET_SCHEDULER_Task * pch
Handle for the parent_control_handler() Task.
#define LOG_STRERROR_FILE(kind, syscall, filename)
static void shutdown_pch(void *cls)
This handler is called on shutdown to remove the pch.
static void open_dev_null(int target_fd, int flags)
Open '/dev/null' and make the result the given file descriptor.
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.
static struct GNUNET_SCHEDULER_Task * spch
Handle for the shutdown_pch() Task.
#define LOG_STRERROR(kind, syscall)
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.
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Handle used to access files (and pipes).
Handle used to manage a pipe.
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.
struct GNUNET_DISK_FileHandle * control_pipe
Pipe we use to signal the process.
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.
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.