GNUnet 0.27.0
 
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
46
51
52
58static void
59shutdown_pch (void *cls)
60{
61 struct GNUNET_DISK_FileHandle *control_pipe = cls;
62
64 pch = NULL;
65 GNUNET_DISK_file_close (control_pipe);
66 control_pipe = NULL;
67}
68
69
75static void
77{
78 struct GNUNET_DISK_FileHandle *control_pipe = cls;
79 char sig;
80 char *pipe_fd;
81 ssize_t ret;
82
83 pch = NULL;
84 ret = GNUNET_DISK_file_read (control_pipe, &sig, sizeof(sig));
85 if (sizeof(sig) != ret)
86 {
87 if (-1 == ret)
88 LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "GNUNET_DISK_file_read");
89 LOG (GNUNET_ERROR_TYPE_DEBUG, "Closing control pipe\n");
90 GNUNET_DISK_file_close (control_pipe);
91 control_pipe = NULL;
93 spch = NULL;
94 return;
95 }
97 GNUNET_assert ((NULL == pipe_fd) || (strlen (pipe_fd) <= 0));
99 "Got control code %d from parent via pipe %s\n",
100 sig,
101 pipe_fd);
103 control_pipe,
105 control_pipe);
106 GNUNET_SIGNAL_raise ((int) sig);
107}
108
109
110void
112{
113 const char *env_buf;
114 char *env_buf_end;
115 struct GNUNET_DISK_FileHandle *control_pipe;
116 uint64_t pipe_fd;
117
118 (void) cls;
119 if (NULL != pch)
120 {
121 /* already done, we've been called twice... */
122 GNUNET_break (0);
123 return;
124 }
125 env_buf = getenv (GNUNET_OS_CONTROL_PIPE);
126 if ((NULL == env_buf) || (strlen (env_buf) <= 0))
127 {
129 "Not installing a handler because $%s is empty\n",
131 setenv (GNUNET_OS_CONTROL_PIPE, "", 1);
132 return;
133 }
134 errno = 0;
135 pipe_fd = strtoull (env_buf, &env_buf_end, 16);
136 if ((0 != errno) || (env_buf == env_buf_end))
137 {
138 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "strtoull", env_buf);
139 setenv (GNUNET_OS_CONTROL_PIPE, "", 1);
140 return;
141 }
142 if (pipe_fd >= FD_SETSIZE)
143 {
145 "GNUNET_OS_CONTROL_PIPE `%s' contains garbage?\n",
146 env_buf);
147 setenv (GNUNET_OS_CONTROL_PIPE, "", 1);
148 return;
149 }
150
151 control_pipe = GNUNET_DISK_get_handle_from_int_fd ((int) pipe_fd);
152
153 if (NULL == control_pipe)
154 {
156 setenv (GNUNET_OS_CONTROL_PIPE, "", 1);
157 return;
158 }
160 "Adding parent control handler pipe `%s' to the scheduler\n",
161 env_buf);
163 control_pipe,
165 control_pipe);
167 setenv (GNUNET_OS_CONTROL_PIPE, "", 1);
168}
169
170
221
222
223void
225{
226 if (NULL != cmd->proc)
227 {
228 GNUNET_assert (NULL != cmd->rtask);
230 }
233 SIGKILL));
236 true,
237 NULL,
238 NULL));
241 GNUNET_free (cmd);
242}
243
244
250static void
251cmd_read (void *cls)
252{
253 struct GNUNET_OS_CommandHandle *cmd = cls;
254 const struct GNUNET_SCHEDULER_TaskContext *tc;
256 char *end;
257 ssize_t ret;
258
259 cmd->rtask = NULL;
261 if (GNUNET_YES !=
263 cmd->r))
264 {
265 /* timeout */
266 proc = cmd->proc;
267 cmd->proc = NULL;
268 proc (cmd->proc_cls, NULL);
269 return;
270 }
272 &cmd->buf[cmd->off],
273 sizeof(cmd->buf) - cmd->off);
274 if (ret <= 0)
275 {
276 if ((cmd->off > 0) && (cmd->off < sizeof(cmd->buf)))
277 {
278 cmd->buf[cmd->off] = '\0';
279 cmd->proc (cmd->proc_cls, cmd->buf);
280 }
281 proc = cmd->proc;
282 cmd->proc = NULL;
283 proc (cmd->proc_cls, NULL);
284 return;
285 }
286 end = memchr (&cmd->buf[cmd->off], '\n', ret);
287 cmd->off += ret;
288 while (NULL != end)
289 {
290 *end = '\0';
291 cmd->proc (cmd->proc_cls, cmd->buf);
292 memmove (cmd->buf, end + 1, cmd->off - (end + 1 - cmd->buf));
293 cmd->off -= (end + 1 - cmd->buf);
294 end = memchr (cmd->buf, '\n', cmd->off);
295 }
296 cmd->rtask =
298 cmd->timeout),
299 cmd->r,
300 &cmd_read,
301 cmd);
302}
303
304
307 void *proc_cls,
309 const char *binary,
310 ...)
311{
313 struct GNUNET_Process *eip;
314 struct GNUNET_DISK_PipeHandle *opipe;
315 va_list ap;
316
318 if (NULL == opipe)
319 return NULL;
320 va_start (ap, binary);
321 /* redirect stdout, don't inherit stderr/stdin */
325 eip,
327 STDOUT_FILENO)));
328 if (GNUNET_OK !=
330 binary,
331 ap))
332 {
334 va_end (ap);
336 return NULL;
337 }
338 va_end (ap);
341 cmd = GNUNET_new (struct GNUNET_OS_CommandHandle);
343 cmd->eip = eip;
344 cmd->opipe = opipe;
345 cmd->proc = proc;
346 cmd->proc_cls = proc_cls;
347 cmd->r = GNUNET_DISK_pipe_handle (opipe,
350 cmd->r,
351 &cmd_read, cmd);
352 return cmd;
353}
354
355
356/* end of os_priority.c */
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
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:1703
struct GNUNET_DISK_PipeHandle * GNUNET_DISK_pipe(enum GNUNET_DISK_PipeFlags pf)
Creates an interprocess channel.
Definition disk.c:1524
enum GNUNET_GenericReturnValue GNUNET_DISK_pipe_close(struct GNUNET_DISK_PipeHandle *p)
Closes an interprocess channel.
Definition disk.c:1671
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:1410
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:1618
@ 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_OK
@ GNUNET_YES
#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.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(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:1126
void(* GNUNET_OS_LineProcessor)(void *cls, const char *line)
Type of a function to process a line of output.
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...
enum GNUNET_GenericReturnValue GNUNET_process_wait(struct GNUNET_Process *proc, bool blocking, enum GNUNET_OS_ProcessStatusType *type, unsigned long *code)
Wait for a process to terminate.
enum GNUNET_GenericReturnValue GNUNET_process_run_command_ap(struct GNUNET_Process *p, const char *filename, va_list va)
Set the command and start a process.
Definition os_process.c:866
void GNUNET_process_destroy(struct GNUNET_Process *proc)
Cleans up process structure contents (OS-dependent) and deallocates it.
Definition os_process.c:363
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.
#define GNUNET_process_set_options(proc,...)
Set the requested options for the process.
#define GNUNET_process_option_inherit_wpipe(wpipe, child_fd)
Have child process inherit a pipe for writing.
enum GNUNET_GenericReturnValue GNUNET_process_kill(struct GNUNET_Process *proc, int sig)
Sends a signal to the process.
Definition os_process.c:307
struct GNUNET_Process * GNUNET_process_create(enum GNUNET_OS_InheritStdioFlags std_inheritance)
Create a process handle.
Definition os_process.c:462
@ GNUNET_OS_INHERIT_STD_NONE
No standard streams should be inherited.
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:76
static struct GNUNET_SCHEDULER_Task * pch
Handle for the parent_control_handler() Task.
Definition os_priority.c:45
#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:59
static struct GNUNET_SCHEDULER_Task * spch
Handle for the shutdown_pch() Task.
Definition os_priority.c:50
#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 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_Process * eip
Process handle.
struct GNUNET_DISK_PipeHandle * opipe
Handle to the output pipe.
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.
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.