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, filename)
41#define GNUNET_OS_CONTROL_PIPE "GNUNET_OS_CONTROL_PIPE"
107 if (
sizeof(sig) !=
ret)
119 GNUNET_assert ((NULL == pipe_fd) || (strlen (pipe_fd) <= 0));
121 "Got control code %d from parent via pipe %s\n",
148 if ((NULL == env_buf) || (strlen (env_buf) <= 0))
151 "Not installing a handler because $%s is empty\n",
157 pipe_fd = strtoull (env_buf, &env_buf_end, 16);
158 if ((0 != errno) || (env_buf == env_buf_end))
164 if (pipe_fd >= FD_SETSIZE)
167 "GNUNET_OS_CONTROL_PIPE `%s' contains garbage?\n",
175 if (NULL == control_pipe)
182 "Adding parent control handler pipe `%s' to the scheduler\n",
220 "Sending signal %d to pid: %u via pipe\n",
224 if (
sizeof(csig) ==
ret)
234#if (SIGTERM != GNUNET_TERM_SIG)
238 "Sending signal %d to pid: %u via system call\n",
241 return kill (proc->
pid, sig);
244 "Sending signal %d to pid: %u via system call\n",
247 return kill (proc->
pid, sig);
282 fd = open (
"/dev/null", flags);
290 if (-1 == dup2 (fd, target_fd))
330 int childpipe_read_fd;
351 int dup_childpipe_read_fd = -1;
354 if (NULL == childpipe)
361 if ((NULL == childpipe_read) || (NULL == childpipe_write) ||
363 &childpipe_read_fd)) ||
364 (-1 == (dup_childpipe_read_fd = dup (childpipe_read_fd))))
366 if (NULL != childpipe_read)
368 if (NULL != childpipe_write)
370 if (0 <= dup_childpipe_read_fd)
374 childpipe_read_fd = dup_childpipe_read_fd;
379 childpipe_write = NULL;
380 childpipe_read_fd = -1;
382 if (NULL != pipe_stdin)
395 if (NULL != pipe_stdout)
408 if (NULL != pipe_stderr)
426 while (-1 != (k = lsocks[i++]))
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"
438 #pragma clang diagnostic pop
439 #pragma GCC diagnostic pop
448 if (NULL != childpipe_write)
450 if (0 <= childpipe_read_fd)
468 if (0 <= childpipe_read_fd)
475 snprintf (fdbuf, 100,
"%x", childpipe_read_fd);
480 if (NULL != pipe_stdin)
483 if (-1 == dup2 (fd_stdin_read, 0))
492 if (NULL != pipe_stdout)
495 if (-1 == dup2 (fd_stdout_write, 1))
504 if (NULL != pipe_stderr)
507 if (-1 == dup2 (fd_stderr_write, 2))
521 while (-1 != lscp[i])
524 while (-1 != lscp[j])
545 flags = fcntl (tgt, F_GETFD);
547 flags &= ~FD_CLOEXEC;
549 (void) fcntl (tgt, F_SETFD, flags);
554 setenv (
"LISTEN_FDS", fds, 1);
599 while (NULL != va_arg (ap,
char *))
605 while (NULL != (argv[argc] = va_arg (ap,
char *)))
666 unsigned int argv_size;
686 while (
'\0' != *rpos)
695 if ((
' ' == *rpos) && (0 == quote_on))
704 if ((NULL == last) && (
'\0' != *rpos))
712 while (NULL != (
arg = (va_arg (ap,
const char *))));
734 if ((
' ' == *pos) && (0 == quote_on))
744 if ((NULL == last) && (
'\0' != *pos))
754 while (NULL != (
arg = (va_arg (ap,
const char *))));
756 argv[argv_size] = NULL;
758 for (i = 0; i < argv_size; i++)
760 len = strlen (argv[i]);
761 if ((argv[i][0] ==
'"') && (argv[i][len - 1] ==
'"'))
763 memmove (&argv[i][0], &argv[i][1], len - 2);
764 argv[i][len - 2] =
'\0';
767 binary_path = argv[0];
772 while (argv_size > 0)
823 *code = WEXITSTATUS (
status);
825 else if (WIFSIGNALED (
status))
828 *code = WTERMSIG (
status);
830 else if (WIFSTOPPED (
status))
833 *code = WSTOPSIG (
status);
836 else if (WIFCONTINUED (
status))
876 while ((
pid != (
ret = waitpid (
pid, NULL, 0))) && (EINTR == errno))
943 if (NULL != cmd->
proc)
982 sizeof(cmd->
buf) - cmd->
off);
985 if ((cmd->
off > 0) && (cmd->
off <
sizeof(cmd->
buf)))
987 cmd->
buf[cmd->
off] =
'\0';
1003 end = memchr (cmd->
buf,
'\n', cmd->
off);
1029 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
#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.