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, ...) GNUNET_log(kind, __VA_ARGS__)
53 
57 #define LOG_DEBUG(...) LOG(GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
58 
59 
63 #define PIPE_CONTROL GNUNET_NO
64 
65 
69 struct WriteContext {
73  void *data;
74 
78  size_t length;
79 
83  size_t pos;
84 };
85 
86 
91 
96 
101 
106 
110 static struct GNUNET_OS_Process *testbed;
111 
116 
121 
126 
131 
135 static int done_reading;
136 
140 static int status;
141 
142 
148 static void
149 shutdown_task(void *cls)
150 {
151  LOG_DEBUG("Shutting down\n");
152  if (NULL != testbed)
153  {
154  LOG_DEBUG("Killing testbed\n");
156  }
157  if (NULL != read_task_id)
158  {
159  GNUNET_SCHEDULER_cancel(read_task_id);
160  read_task_id = NULL;
161  }
162  if (NULL != write_task_id)
163  {
164  struct WriteContext *wc;
165 
166  wc = GNUNET_SCHEDULER_cancel(write_task_id);
167  write_task_id = NULL;
168  GNUNET_free(wc->data);
169  GNUNET_free(wc);
170  }
171  if (NULL != child_death_task_id)
172  {
173  GNUNET_SCHEDULER_cancel(child_death_task_id);
174  child_death_task_id = NULL;
175  }
176  if (NULL != stdin_fd)
177  (void)GNUNET_DISK_file_close(stdin_fd);
178  if (NULL != stdout_fd)
179  (void)GNUNET_DISK_file_close(stdout_fd);
180  GNUNET_MST_destroy(tokenizer);
181  tokenizer = NULL;
182  if (NULL != testbed)
183  {
185  GNUNET_OS_process_destroy(testbed);
186  testbed = NULL;
187  }
188  if (NULL != test_system)
189  {
191  test_system = NULL;
192  }
193 }
194 
195 
201 static void
202 write_task(void *cls)
203 {
204  struct WriteContext *wc = cls;
205  ssize_t bytes_wrote;
206 
207  GNUNET_assert(NULL != wc);
208  write_task_id = NULL;
209  bytes_wrote = GNUNET_DISK_file_write(stdout_fd,
210  wc->data + wc->pos,
211  wc->length - wc->pos);
212  if (GNUNET_SYSERR == bytes_wrote)
213  {
214  LOG(GNUNET_ERROR_TYPE_WARNING, "Cannot reply back configuration\n");
215  GNUNET_free(wc->data);
216  GNUNET_free(wc);
217  return;
218  }
219  wc->pos += bytes_wrote;
220  if (wc->pos == wc->length)
221  {
222  GNUNET_free(wc->data);
223  GNUNET_free(wc);
224  return;
225  }
227  stdout_fd,
228  &write_task,
229  wc);
230 }
231 
232 
239 static void
241 {
242  const struct GNUNET_DISK_FileHandle *pr;
243  char c[16];
245  unsigned long code;
246  int ret;
247 
249  child_death_task_id = NULL;
250  /* consume the signal */
251  GNUNET_break(0 < GNUNET_DISK_file_read(pr, &c, sizeof(c)));
252  LOG_DEBUG("Got SIGCHLD\n");
253  if (NULL == testbed)
254  {
255  GNUNET_break(0);
256  return;
257  }
259  (ret = GNUNET_OS_process_status(testbed, &type, &code)));
260  if (GNUNET_NO != ret)
261  {
262  GNUNET_OS_process_destroy(testbed);
263  testbed = NULL;
264  /* Send SIGTERM to our process group */
265  if (0 != kill(0, GNUNET_TERM_SIG))
266  {
268  GNUNET_SCHEDULER_shutdown(); /* Couldn't send the signal, we shutdown frowning */
269  }
270  return;
271  }
272  LOG_DEBUG("Child hasn't died. Resuming to monitor its status\n");
273  child_death_task_id =
275  pr,
277  NULL);
278 }
279 
280 
293 static int
294 tokenizer_cb(void *cls, const struct GNUNET_MessageHeader *message)
295 {
296  const struct GNUNET_TESTBED_HelperInit *msg;
297  struct GNUNET_TESTBED_HelperReply *reply;
299  struct WriteContext *wc;
300  char *binary;
301  char *trusted_ip;
302  char *hostname;
303  char *config;
304  char *xconfig;
305  char *evstr;
306  //char *str;
307  size_t config_size;
308  uLongf ul_config_size;
309  size_t xconfig_size;
310  uint16_t trusted_ip_size;
311  uint16_t hostname_size;
312  uint16_t msize;
313 
314  msize = ntohs(message->size);
315  if ((sizeof(struct GNUNET_TESTBED_HelperInit) >= msize) ||
316  (GNUNET_MESSAGE_TYPE_TESTBED_HELPER_INIT != ntohs(message->type)))
317  {
318  LOG(GNUNET_ERROR_TYPE_WARNING, "Received unexpected message -- exiting\n");
319  goto error;
320  }
321  msg = (const struct GNUNET_TESTBED_HelperInit *)message;
322  trusted_ip_size = ntohs(msg->trusted_ip_size);
323  trusted_ip = (char *)&msg[1];
324  if ('\0' != trusted_ip[trusted_ip_size])
325  {
326  LOG(GNUNET_ERROR_TYPE_WARNING, "Trusted IP cannot be empty -- exiting\n");
327  goto error;
328  }
329  hostname_size = ntohs(msg->hostname_size);
330  if ((sizeof(struct GNUNET_TESTBED_HelperInit) + trusted_ip_size + 1 +
331  hostname_size) >= msize)
332  {
333  GNUNET_break(0);
334  LOG(GNUNET_ERROR_TYPE_WARNING, "Received unexpected message -- exiting\n");
335  goto error;
336  }
337  ul_config_size = (uLongf)ntohs(msg->config_size);
338  config = GNUNET_malloc(ul_config_size);
339  xconfig_size = msize - (trusted_ip_size + 1 + hostname_size +
340  sizeof(struct GNUNET_TESTBED_HelperInit));
341  int ret = uncompress((Bytef *)config,
342  &ul_config_size,
343  (const Bytef *)(trusted_ip + trusted_ip_size + 1 +
344  hostname_size),
345  (uLongf)xconfig_size);
346  if (Z_OK != ret)
347  {
348  switch (ret)
349  {
350  case Z_MEM_ERROR:
351  LOG(GNUNET_ERROR_TYPE_ERROR, "Not enough memory for decompression\n");
352  break;
353 
354  case Z_BUF_ERROR:
355  LOG(GNUNET_ERROR_TYPE_ERROR, "Output buffer too small\n");
356  break;
357 
358  case Z_DATA_ERROR:
359  LOG(GNUNET_ERROR_TYPE_ERROR, "Data corrupted/incomplete\n");
360  break;
361 
362  default:
363  GNUNET_break(0);
364  }
366  "Error while uncompressing config -- exiting\n");
367  GNUNET_free(config);
368  goto error;
369  }
371  if (GNUNET_OK !=
372  GNUNET_CONFIGURATION_deserialize(cfg, config, ul_config_size, NULL))
373  {
374  LOG(GNUNET_ERROR_TYPE_ERROR, "Unable to deserialize config -- exiting\n");
375  GNUNET_free(config);
376  goto error;
377  }
378  GNUNET_free(config);
379  hostname = NULL;
380  if (0 != hostname_size)
381  {
382  hostname = GNUNET_malloc(hostname_size + 1);
383  GNUNET_strlcpy(hostname,
384  ((char *)&msg[1]) + trusted_ip_size + 1,
385  hostname_size + 1);
386  }
387  /* unset GNUNET_TESTING_PREFIX if present as it is more relevant for testbed */
388  evstr = getenv(GNUNET_TESTING_PREFIX);
389  if (NULL != evstr)
390  {
391  /* unsetting the variable will invalidate the pointer! */
392  evstr = GNUNET_strdup(evstr);
393  GNUNET_break(0 == unsetenv(GNUNET_TESTING_PREFIX));
394  }
395  test_system =
396  GNUNET_TESTING_system_create("testbed-helper", trusted_ip, hostname, NULL);
397  if (NULL != evstr)
398  {
399  char *evar;
400 
401  GNUNET_asprintf(&evar, GNUNET_TESTING_PREFIX "=%s", evstr);
402  GNUNET_assert(0 == putenv(evar)); /* consumes 'evar',
403  see putenv(): becomes part of envrionment! */
404  GNUNET_free(evstr);
405  evstr = NULL;
406  }
407  GNUNET_free_non_null(hostname);
408  hostname = NULL;
409  GNUNET_assert(NULL != test_system);
411  GNUNET_TESTING_configuration_create(test_system, cfg));
414  "PATHS",
415  "DEFAULTCONFIG",
416  &config));
417  if (GNUNET_OK != GNUNET_CONFIGURATION_write(cfg, config))
418  {
420  "Unable to write config file: %s -- exiting\n",
421  config);
423  GNUNET_free(config);
424  goto error;
425  }
426  LOG_DEBUG("Staring testbed with config: %s\n", config);
427  binary = GNUNET_OS_get_libexec_binary_path("gnunet-service-testbed");
428  {
429  char *evar;
430 
431  /* expose testbed configuration through env variable */
432  GNUNET_asprintf(&evar, "%s=%s", ENV_TESTBED_CONFIG, config);
433  GNUNET_assert(0 == putenv(evar)); /* consumes 'evar',
434  see putenv(): becomes part of envrionment! */
435  evstr = NULL;
436  }
438  GNUNET_OS_INHERIT_STD_ERR /*verbose? */,
439  NULL,
440  NULL,
441  NULL,
442  binary,
443  "gnunet-service-testbed",
444  "-c",
445  config,
446  NULL);
447  GNUNET_free(binary);
448  GNUNET_free(config);
449  if (NULL == testbed)
450  {
452  "Error starting gnunet-service-testbed -- exiting\n");
454  goto error;
455  }
457  config = GNUNET_CONFIGURATION_serialize(cfg, &config_size);
459  cfg = NULL;
460  xconfig_size =
461  GNUNET_TESTBED_compress_config_(config, config_size, &xconfig);
462  GNUNET_free(config);
463  wc = GNUNET_new(struct WriteContext);
464  wc->length = xconfig_size + sizeof(struct GNUNET_TESTBED_HelperReply);
465  reply = GNUNET_realloc(xconfig, wc->length);
466  memmove(&reply[1], reply, xconfig_size);
467  reply->header.type = htons(GNUNET_MESSAGE_TYPE_TESTBED_HELPER_REPLY);
468  reply->header.size = htons((uint16_t)wc->length);
469  reply->config_size = htons((uint16_t)config_size);
470  wc->data = reply;
472  stdout_fd,
473  &write_task,
474  wc);
475  child_death_task_id = GNUNET_SCHEDULER_add_read_file(
479  NULL);
480  return GNUNET_OK;
481 
482 error:
485  return GNUNET_SYSERR;
486 }
487 
488 
494 static void
495 read_task(void *cls)
496 {
498  ssize_t sread;
499 
500  read_task_id = NULL;
501  sread = GNUNET_DISK_file_read(stdin_fd, buf, sizeof(buf));
502  if ((GNUNET_SYSERR == sread) || (0 == sread))
503  {
504  LOG_DEBUG("STDIN closed\n");
506  return;
507  }
508  if (GNUNET_YES == done_reading)
509  {
510  /* didn't expect any more data! */
511  GNUNET_break_op(0);
513  return;
514  }
515  LOG_DEBUG("Read %u bytes\n", (unsigned int)sread);
516  /* FIXME: could introduce a GNUNET_MST_read2 to read
517  directly from 'stdin_fd' and save a memcpy() here */
518  if (GNUNET_OK !=
519  GNUNET_MST_from_buffer(tokenizer, buf, sread, GNUNET_NO, GNUNET_NO))
520  {
521  GNUNET_break(0);
523  return;
524  }
525  read_task_id /* No timeout while reading */
527  stdin_fd,
528  &read_task,
529  NULL);
530 }
531 
532 
541 static void
542 run(void *cls,
543  char *const *args,
544  const char *cfgfile,
545  const struct GNUNET_CONFIGURATION_Handle *cfg)
546 {
547  LOG_DEBUG("Starting testbed helper...\n");
548  tokenizer = GNUNET_MST_create(&tokenizer_cb, NULL);
549  stdin_fd = GNUNET_DISK_get_handle_from_native(stdin);
550  stdout_fd = GNUNET_DISK_get_handle_from_native(stdout);
552  stdin_fd,
553  &read_task,
554  NULL);
556 }
557 
558 
562 static void
564 {
565  static char c;
566  int old_errno; /* back-up errno */
567 
568  old_errno = errno;
569  GNUNET_break(
570  1 ==
573  &c,
574  sizeof(c)));
575  errno = old_errno;
576 }
577 
578 
586 int
587 main(int argc, char **argv)
588 {
589  struct GNUNET_SIGNAL_Context *shc_chld;
591  int ret;
592 
593  status = GNUNET_OK;
594  if (NULL ==
596  {
597  GNUNET_break(0);
598  return 1;
599  }
600  shc_chld =
602  ret = GNUNET_PROGRAM_run(argc,
603  argv,
604  "gnunet-helper-testbed",
605  "Helper for starting gnunet-service-testbed",
606  options,
607  &run,
608  NULL);
610  shc_chld = NULL;
611  GNUNET_DISK_pipe_close(sigpipe);
612  if (GNUNET_OK != ret)
613  return 1;
614  return (GNUNET_OK == status) ? 0 : 1;
615 }
616 
617 /* 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:90
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:1339
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:286
#define GNUNET_SIGCHLD
Definition: platform.h:42
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:729
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:963
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:1284
#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:687
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:78
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:1647
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:1615
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
void GNUNET_SIGNAL_handler_uninstall(struct GNUNET_SIGNAL_Context *ctx)
Uninstall a previously installed signal hander.
Definition: signal.c:75
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:517
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:1141
#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:1744
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:410
#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:817
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:84
#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:113
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:1518
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:530
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:50
#define GNUNET_MESSAGE_TYPE_TESTBED_HELPER_REPLY
The reply message from gnunet-testbed-helper.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
char * getenv()
Handle for a system on which GNUnet peers are executed; a system is used for reserving unique paths a...
Definition: testing.c:95
#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...
size_t GNUNET_TESTBED_compress_config_(const char *config, size_t size, char **xconfig)
Compresses given configuration using zlib compress.
Definition: testbed_api.c:1750
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:1706
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:1000
configuration data
Definition: configuration.c:83
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:131
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:367
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:77
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_native(FILE *fd)
Get a handle from a native FD.
Definition: disk.c:1391
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:242
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.
Definition: strings.c:219
Handle used to access files (and pipes).
Handle used to manage a pipe.
Definition: disk.c:68
#define ENV_TESTBED_CONFIG
The environmental variable which when available refers to the configuration file the local testbed co...
Definition: testbed.h:751
#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:224
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:956
Context for a single write on a chunk of memory.