GNUnet  0.10.x
gnunet-helper-testbed.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2008--2013, 2016 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 
41 #include "platform.h"
42 #include "gnunet_util_lib.h"
43 #include "gnunet_testing_lib.h"
44 #include "gnunet_testbed_service.h"
45 #include "testbed_helper.h"
46 #include "testbed_api.h"
47 #include <zlib.h>
48 
52 #define LOG(kind, ...) \
53  GNUNET_log (kind, __VA_ARGS__)
54 
58 #define LOG_DEBUG(...) \
59  LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
60 
61 
65 #if WINDOWS
66 #define PIPE_CONTROL GNUNET_YES
67 #else
68 #define PIPE_CONTROL GNUNET_NO
69 #endif
70 
71 
76 {
80  void *data;
81 
85  size_t length;
86 
90  size_t pos;
91 };
92 
93 
98 
103 
108 
113 
117 static struct GNUNET_OS_Process *testbed;
118 
123 
128 
133 
138 
142 static int done_reading;
143 
147 static int status;
148 
149 
155 static void
156 shutdown_task (void *cls)
157 {
158  LOG_DEBUG ("Shutting down\n");
159  if (NULL != testbed)
160  {
161  LOG_DEBUG ("Killing testbed\n");
163  }
164  if (NULL != read_task_id)
165  {
166  GNUNET_SCHEDULER_cancel (read_task_id);
167  read_task_id = NULL;
168  }
169  if (NULL != write_task_id)
170  {
171  struct WriteContext *wc;
172 
173  wc = GNUNET_SCHEDULER_cancel (write_task_id);
174  write_task_id = NULL;
175  GNUNET_free (wc->data);
176  GNUNET_free (wc);
177  }
178  if (NULL != child_death_task_id)
179  {
180  GNUNET_SCHEDULER_cancel (child_death_task_id);
181  child_death_task_id = NULL;
182  }
183  if (NULL != stdin_fd)
184  (void) GNUNET_DISK_file_close (stdin_fd);
185  if (NULL != stdout_fd)
186  (void) GNUNET_DISK_file_close (stdout_fd);
187  GNUNET_MST_destroy (tokenizer);
188  tokenizer = NULL;
189  if (NULL != testbed)
190  {
192  GNUNET_OS_process_destroy (testbed);
193  testbed = NULL;
194  }
195  if (NULL != test_system)
196  {
198  test_system = NULL;
199  }
200 }
201 
202 
208 static void
209 write_task (void *cls)
210 {
211  struct WriteContext *wc = cls;
212  ssize_t bytes_wrote;
213 
214  GNUNET_assert (NULL != wc);
215  write_task_id = NULL;
216  bytes_wrote =
217  GNUNET_DISK_file_write (stdout_fd, wc->data + wc->pos,
218  wc->length - wc->pos);
219  if (GNUNET_SYSERR == bytes_wrote)
220  {
222  "Cannot reply back configuration\n");
223  GNUNET_free (wc->data);
224  GNUNET_free (wc);
225  return;
226  }
227  wc->pos += bytes_wrote;
228  if (wc->pos == wc->length)
229  {
230  GNUNET_free (wc->data);
231  GNUNET_free (wc);
232  return;
233  }
234  write_task_id =
236  stdout_fd,
237  &write_task, wc);
238 }
239 
240 
247 static void
248 child_death_task (void *cls)
249 {
250  const struct GNUNET_DISK_FileHandle *pr;
251  char c[16];
253  unsigned long code;
254  int ret;
255 
257  child_death_task_id = NULL;
258  /* consume the signal */
259  GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof (c)));
260  LOG_DEBUG ("Got SIGCHLD\n");
261  if (NULL == testbed)
262  {
263  GNUNET_break (0);
264  return;
265  }
267  (ret = GNUNET_OS_process_status (testbed, &type, &code)));
268  if (GNUNET_NO != ret)
269  {
270  GNUNET_OS_process_destroy (testbed);
271  testbed = NULL;
272  /* Send SIGTERM to our process group */
273  if (0 != PLIBC_KILL (0, GNUNET_TERM_SIG))
274  {
276  GNUNET_SCHEDULER_shutdown (); /* Couldn't send the signal, we shutdown frowning */
277  }
278  return;
279  }
280  LOG_DEBUG ("Child hasn't died. Resuming to monitor its status\n");
281  child_death_task_id =
283  pr, &child_death_task, NULL);
284 }
285 
286 
299 static int
300 tokenizer_cb (void *cls,
301  const struct GNUNET_MessageHeader *message)
302 {
303  const struct GNUNET_TESTBED_HelperInit *msg;
304  struct GNUNET_TESTBED_HelperReply *reply;
306  struct WriteContext *wc;
307  char *binary;
308  char *trusted_ip;
309  char *hostname;
310  char *config;
311  char *xconfig;
312  char *evstr;
313  //char *str;
314  size_t config_size;
315  uLongf ul_config_size;
316  size_t xconfig_size;
317  uint16_t trusted_ip_size;
318  uint16_t hostname_size;
319  uint16_t msize;
320 
321  msize = ntohs (message->size);
322  if ((sizeof (struct GNUNET_TESTBED_HelperInit) >= msize) ||
323  (GNUNET_MESSAGE_TYPE_TESTBED_HELPER_INIT != ntohs (message->type)))
324  {
326  "Received unexpected message -- exiting\n");
327  goto error;
328  }
329  msg = (const struct GNUNET_TESTBED_HelperInit *) message;
330  trusted_ip_size = ntohs (msg->trusted_ip_size);
331  trusted_ip = (char *) &msg[1];
332  if ('\0' != trusted_ip[trusted_ip_size])
333  {
334  LOG (GNUNET_ERROR_TYPE_WARNING, "Trusted IP cannot be empty -- exiting\n");
335  goto error;
336  }
337  hostname_size = ntohs (msg->hostname_size);
338  if ((sizeof (struct GNUNET_TESTBED_HelperInit) + trusted_ip_size + 1 +
339  hostname_size) >= msize)
340  {
341  GNUNET_break (0);
342  LOG (GNUNET_ERROR_TYPE_WARNING, "Received unexpected message -- exiting\n");
343  goto error;
344  }
345  ul_config_size = (uLongf) ntohs (msg->config_size);
346  config = GNUNET_malloc (ul_config_size);
347  xconfig_size =
348  ntohs (message->size) - (trusted_ip_size + 1 +
349  sizeof (struct GNUNET_TESTBED_HelperInit));
350  if (Z_OK !=
351  uncompress ((Bytef *) config, &ul_config_size,
352  (const Bytef *) (trusted_ip + trusted_ip_size + 1 +
353  hostname_size), (uLongf) xconfig_size))
354  {
356  "Error while uncompressing config -- exiting\n");
357  GNUNET_free (config);
358  goto error;
359  }
361  if (GNUNET_OK !=
363  config,
364  ul_config_size,
365  NULL))
366  {
368  "Unable to deserialize config -- exiting\n");
369  GNUNET_free (config);
370  goto error;
371  }
372  GNUNET_free (config);
373  hostname = NULL;
374  if (0 != hostname_size)
375  {
376  hostname = GNUNET_malloc (hostname_size + 1);
377  GNUNET_strlcpy (hostname,
378  ((char *) &msg[1]) + trusted_ip_size + 1,
379  hostname_size + 1);
380  }
381  /* unset GNUNET_TESTING_PREFIX if present as it is more relevant for testbed */
382  evstr = getenv (GNUNET_TESTING_PREFIX);
383  if (NULL != evstr)
384  {
385  /* unsetting the variable will invalidate the pointer! */
386  evstr = GNUNET_strdup (evstr);
387 #ifdef WINDOWS
388  GNUNET_break (0 != SetEnvironmentVariable (GNUNET_TESTING_PREFIX, NULL));
389 #else
390  GNUNET_break (0 == unsetenv (GNUNET_TESTING_PREFIX));
391 #endif
392  }
393  test_system =
394  GNUNET_TESTING_system_create ("testbed-helper", trusted_ip, hostname,
395  NULL);
396  if (NULL != evstr)
397  {
398 #ifdef WINDOWS
399  GNUNET_assert (0 != SetEnvironmentVariable (GNUNET_TESTING_PREFIX,
400  evstr));
401 #else
402  char *evar;
403 
404  GNUNET_asprintf (&evar,
405  GNUNET_TESTING_PREFIX "=%s",
406  evstr);
407  GNUNET_assert (0 == putenv (evar)); /* consumes 'evar',
408  see putenv(): becomes part of envrionment! */
409 #endif
410  GNUNET_free (evstr);
411  evstr = NULL;
412  }
413  GNUNET_free_non_null (hostname);
414  hostname = NULL;
415  GNUNET_assert (NULL != test_system);
417  GNUNET_TESTING_configuration_create (test_system, cfg));
420  "DEFAULTCONFIG",
421  &config));
422  if (GNUNET_OK != GNUNET_CONFIGURATION_write (cfg, config))
423  {
425  "Unable to write config file: %s -- exiting\n", config);
427  GNUNET_free (config);
428  goto error;
429  }
430  LOG_DEBUG ("Staring testbed with config: %s\n", config);
431  binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-testbed");
432  {
433  char *evar;
434 
435  /* expose testbed configuration through env variable */
436  GNUNET_asprintf (&evar,
437  "%s=%s",
439  config);
440  GNUNET_assert (0 == putenv (evar)); /* consumes 'evar',
441  see putenv(): becomes part of envrionment! */
442  evstr = NULL;
443  }
444  testbed =
446  GNUNET_OS_INHERIT_STD_ERR /*verbose? */ ,
447  NULL, NULL, NULL,
448  binary,
449  "gnunet-service-testbed",
450  "-c", config,
451  NULL);
452  GNUNET_free (binary);
453  GNUNET_free (config);
454  if (NULL == testbed)
455  {
457  "Error starting gnunet-service-testbed -- exiting\n");
459  goto error;
460  }
462  config = GNUNET_CONFIGURATION_serialize (cfg, &config_size);
464  cfg = NULL;
465  xconfig_size =
466  GNUNET_TESTBED_compress_config_ (config, config_size, &xconfig);
467  GNUNET_free (config);
468  wc = GNUNET_new (struct WriteContext);
469  wc->length = xconfig_size + sizeof (struct GNUNET_TESTBED_HelperReply);
470  reply = GNUNET_realloc (xconfig, wc->length);
471  memmove (&reply[1], reply, xconfig_size);
473  reply->header.size = htons ((uint16_t) wc->length);
474  reply->config_size = htons ((uint16_t) config_size);
475  wc->data = reply;
476  write_task_id =
478  stdout_fd,
479  &write_task, wc);
480  child_death_task_id =
482  GNUNET_DISK_pipe_handle (sigpipe,
484  &child_death_task, NULL);
485  return GNUNET_OK;
486 
487 error:
490  return GNUNET_SYSERR;
491 }
492 
493 
499 static void
500 read_task (void *cls)
501 {
503  ssize_t sread;
504 
505  read_task_id = NULL;
506  sread = GNUNET_DISK_file_read (stdin_fd,
507  buf,
508  sizeof (buf));
509  if ( (GNUNET_SYSERR == sread) ||
510  (0 == sread) )
511  {
512  LOG_DEBUG ("STDIN closed\n");
514  return;
515  }
516  if (GNUNET_YES == done_reading)
517  {
518  /* didn't expect any more data! */
519  GNUNET_break_op (0);
521  return;
522  }
523  LOG_DEBUG ("Read %u bytes\n",
524  (unsigned int) sread);
525  /* FIXME: could introduce a GNUNET_MST_read2 to read
526  directly from 'stdin_fd' and save a memcpy() here */
527  if (GNUNET_OK !=
528  GNUNET_MST_from_buffer (tokenizer,
529  buf,
530  sread,
531  GNUNET_NO,
532  GNUNET_NO))
533  {
534  GNUNET_break (0);
536  return;
537  }
538  read_task_id /* No timeout while reading */
540  stdin_fd,
541  &read_task,
542  NULL);
543 }
544 
545 
554 static void
555 run (void *cls,
556  char *const *args,
557  const char *cfgfile,
558  const struct GNUNET_CONFIGURATION_Handle *cfg)
559 {
560  LOG_DEBUG ("Starting testbed helper...\n");
561  tokenizer = GNUNET_MST_create (&tokenizer_cb, NULL);
562  stdin_fd = GNUNET_DISK_get_handle_from_native (stdin);
563  stdout_fd = GNUNET_DISK_get_handle_from_native (stdout);
564  read_task_id =
566  stdin_fd,
567  &read_task, NULL);
569  NULL);
570 }
571 
572 
576 static void
578 {
579  static char c;
580  int old_errno; /* back-up errno */
581 
582  old_errno = errno;
583  GNUNET_break (1 ==
585  (sigpipe, GNUNET_DISK_PIPE_END_WRITE),
586  &c, sizeof (c)));
587  errno = old_errno;
588 }
589 
590 
598 int
599 main (int argc,
600  char **argv)
601 {
602  struct GNUNET_SIGNAL_Context *shc_chld;
603  struct GNUNET_GETOPT_CommandLineOption options[] = {
605  };
606  int ret;
607 
608  status = GNUNET_OK;
609  if (NULL == (sigpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO,
610  GNUNET_NO, GNUNET_NO)))
611  {
612  GNUNET_break (0);
613  return 1;
614  }
617  ret = GNUNET_PROGRAM_run (argc, argv,
618  "gnunet-helper-testbed",
619  "Helper for starting gnunet-service-testbed",
620  options,
621  &run,
622  NULL);
624  shc_chld = NULL;
625  GNUNET_DISK_pipe_close (sigpipe);
626  if (GNUNET_OK != ret)
627  return 1;
628  return (GNUNET_OK == status) ? 0 : 1;
629 }
630 
631 /* end of gnunet-helper-testbed.c */
When this flag is set, the child process will inherit stderr of the parent.
Definition: gnunet_os_lib.h:92
size_t pos
The current position from where the write operation should begin.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static struct GNUNET_OS_Process * testbed
The process handle to the testbed service.
int GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1817
int GNUNET_CONFIGURATION_write(struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
Write configuration file.
void GNUNET_OS_process_destroy(struct GNUNET_OS_Process *proc)
Cleans up process structure contents (OS-dependent) and deallocates it.
Definition: os_priority.c:364
#define GNUNET_SIGCHLD
Definition: platform.h:46
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:881
int GNUNET_OS_process_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:1719
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, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1293
#define LOG(kind,...)
Generic logging shortcut.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_OS_Process * GNUNET_OS_start_process(int pipe_control, 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:1400
int main(int argc, char **argv)
Main function.
#define GNUNET_TESTING_PREFIX
The environmental variable, if set, that dictates where testing should place generated peer configura...
#define GNUNET_NO
Definition: gnunet_common.h:81
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_write_file(struct GNUNET_TIME_Relative delay, const struct GNUNET_DISK_FileHandle *wfd, 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:1675
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:1643
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
void GNUNET_SIGNAL_handler_uninstall(struct GNUNET_SIGNAL_Context *ctx)
Uninstall a previously installed signal hander.
Definition: signal.c:99
static struct GNUNET_DISK_FileHandle * stdout_fd
Disk handle for stdout.
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Definition of a command line option.
static struct GNUNET_DISK_FileHandle * stdin_fd
Disk handle from stdin.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_create(void)
Create a new configuration object.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
Initialization message for gnunet-helper-testbed to start testbed service.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:524
static int ret
Final status code.
Definition: gnunet-arm.c:89
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
int GNUNET_TESTING_configuration_create(struct GNUNET_TESTING_System *system, struct GNUNET_CONFIGURATION_Handle *cfg)
Create a new configuration using the given configuration as a template; ports and paths will be modif...
Definition: testing.c:1113
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
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:2641
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
static int status
Result to return in case we fail.
static int tokenizer_cb(void *cls, const struct GNUNET_MessageHeader *message)
Functions with this signature are called whenever a complete message is received by the tokenizer...
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition: mst.c:413
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_realloc(ptr, size)
Wrapper around realloc.
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:1049
GNUNET_OS_ProcessStatusType
Process status types.
Handle to a message stream tokenizer.
Definition: mst.c:43
static void write_task(void *cls)
Task to write to the standard out.
void GNUNET_CONFIGURATION_destroy(struct GNUNET_CONFIGURATION_Handle *cfg)
Destroy configuration object.
static char buf[2048]
static const struct GNUNET_CONFIGURATION_Handle * config
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Definition: mst.c:87
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
The writing-end of a pipe.
The reading-end of a pipe.
int GNUNET_MST_from_buffer(struct GNUNET_MessageStreamTokenizer *mst, const char *buf, size_t size, int purge, int one_shot)
Add incoming data to the receive buffer and call the callback for all complete messages.
Definition: mst.c:116
static struct GNUNET_TESTING_System * test_system
Handle to the testing system.
static void shutdown_task(void *cls)
Task to shut down cleanly.
uint16_t hostname_size
The hostname size excluding the NULL termination character - strlen (hostname); cannot be zero...
Reply message from helper process.
struct GNUNET_DISK_PipeHandle * GNUNET_DISK_pipe(int blocking_read, int blocking_write, int inherit_read, int inherit_write)
Creates an interprocess channel.
Definition: disk.c:2289
static struct GNUNET_SCHEDULER_Task * write_task_id
Task identifier for the write task.
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
#define GNUNET_MESSAGE_TYPE_TESTBED_HELPER_INIT
The initialization message towards gnunet-testbed-helper.
#define LOG_DEBUG(...)
Debug logging shorthand.
struct GNUNET_TESTING_System * GNUNET_TESTING_system_create(const char *testdir, const char *trusted_ip, const char *hostname, const struct GNUNET_TESTING_SharedService *shared_services)
Create a system handle.
Definition: testing.c:449
void GNUNET_TESTING_system_destroy(struct GNUNET_TESTING_System *system, int remove_paths)
Free system resources.
Definition: testing.c:527
struct GNUNET_SIGNAL_Context * GNUNET_SIGNAL_handler_install(int signal, GNUNET_SIGNAL_Handler handler)
Install a signal handler that will be run if the given signal is received.
Definition: signal.c:59
#define GNUNET_MESSAGE_TYPE_TESTBED_HELPER_REPLY
The reply message from gnunet-testbed-helper.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_TESTBED_HELPER_REPLY.
char * getenv()
Handle for a system on which GNUnet peers are executed; a system is used for reserving unique paths a...
Definition: testing.c:102
#define PIPE_CONTROL
We need pipe control only on WINDOWS.
static struct GNUNET_SCHEDULER_Task * read_task_id
Task identifier for the read task.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
#define PLIBC_KILL(p, s)
Definition: plibc.h:659
size_t GNUNET_TESTBED_compress_config_(const char *config, size_t size, char **xconfig)
Compresses given configuration using zlib compress.
Definition: testbed_api.c:1761
Interface for functions internally exported from testbed_api.c.
char * GNUNET_CONFIGURATION_serialize(const struct GNUNET_CONFIGURATION_Handle *cfg, size_t *size)
Serializes the given configuration.
int GNUNET_DISK_pipe_close(struct GNUNET_DISK_PipeHandle *p)
Closes an interprocess channel.
Definition: disk.c:2603
static char * hostname
Our hostname; we give this to all the peers we start.
static struct GNUNET_DISK_PipeHandle * sigpipe
Pipe used to communicate shutdown via signal.
int GNUNET_OS_process_wait(struct GNUNET_OS_Process *proc)
Wait for a process to terminate.
Definition: os_priority.c:1762
configuration data
Definition: configuration.c:85
uint16_t trusted_ip_size
The controller hostname size excluding the NULL termination character - strlen (hostname); cannot be ...
Entry in list of pending tasks.
Definition: scheduler.c:134
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
Main function that will be run.
struct GNUNET_MessageStreamTokenizer * tokenizer
Our message stream tokenizer.
int GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
char * GNUNET_OS_get_libexec_binary_path(const char *progname)
Given the name of a gnunet-helper, gnunet-service or gnunet-daemon binary, try to prefix it with the ...
static void child_death_task(void *cls)
Task triggered whenever we receive a SIGCHLD (child process died).
int GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration, parse options).
Definition: program.c:361
static void sighandler_child_death()
Signal handler called for SIGCHLD.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
Header for all communications.
#define GNUNET_YES
Definition: gnunet_common.h:80
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_native(FILE *fd)
Get a handle from a native FD.
Definition: disk.c:1970
Message formats for communication between testbed api and gnunet-helper-testbed process.
int GNUNET_CONFIGURATION_deserialize(struct GNUNET_CONFIGURATION_Handle *cfg, const char *mem, size_t size, const char *basedir)
De-serializes configuration.
size_t length
The length of the data.
static int done_reading
Are we done reading messages from stdin?
#define GNUNET_TERM_SIG
The termination signal.
Definition: platform.h:282
uint16_t config_size
The size of the uncompressed configuration.
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Handle used to access files (and pipes).
Handle used to manage a pipe.
Definition: disk.c:66
uint16_t config_size
Size of the uncompressed configuration.
#define ENV_TESTBED_CONFIG
The environmental variable which when available refers to the configuration file the local testbed co...
Definition: testbed.h:817
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
void * data
The data to write.
static void read_task(void *cls)
Task to read from stdin.
int GNUNET_OS_process_kill(struct GNUNET_OS_Process *proc, int sig)
Sends a signal to the process.
Definition: os_priority.c:251
static struct GNUNET_SCHEDULER_Task * child_death_task_id
Task to kill the child.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965
Context for a single write on a chunk of memory.