#include <ul_list.h>
#include <errno.h>
#include <semaphore.h>
+#include <stdbool.h>
+#include <error.h>
/* TODO: Handle the case where there are more canping slaves running
* on one CAN bus. */
int option_timeout = 4;
int option_open_once = 0;
int option_synch_start = 0;
+bool option_background = false;
/* Lists */
typedef struct threads {
pongmsg.length = option_length;
for (i=0; i < option_length; i++) pongmsg.data[i] = i;
+ /* Signal that I'm ready */
+ sem_post(&ready_sem);
+
while (!IS_FINISH_FLAG()) {
/* Receive a ping message */
pingmsg.flags=0;
pthread_create(&td->tid, NULL, slave_thread, (void *)td);
dbg(2, "Slave thread: %p\n", (void *)td->tid);
}
+
+ /* Wait for all threads beeing ready */
+ for (i = 0; i < slaves; i++) sem_wait(&ready_sem);
}
#ifdef WITH_RTPRIO
printf("Usage: canping -m <master threads> [other options]\n"
" canping -s <slave threads> [other options]\n\n"
"Other options:\n"
+ " -b go to background (fork) after initialization, prints child PID\n"
" -c count how many messages each master sends\n"
" -d dev device (e.g. /dev/can1)\n"
" -h print this help\n"
int c;
opterr = 0;
- while ((c = getopt (argc, argv, "c:d:hi:l:m:os:t:vw:yrR:")) != -1)
+ while ((c = getopt (argc, argv, "bc:d:hi:l:m:os:t:vw:yrR:")) != -1)
switch (c)
{
+ case 'b':
+ option_background = true;
+ break;
case 'c':
option_count = atoi(optarg);
break;
}
}
- if (option_masters) start_masters(option_masters, option_first_id);
- if (option_slaves) start_slaves(option_slaves, option_first_id);
+ sem_t *child_ready;
+ int fork_ret = 0;
+ if ((child_ready = sem_open("canping", O_CREAT)) == NULL)
+ error(1, errno, "sem_open");
+ if (option_background) {
+ /* Go to background when everything is ready */
+ fork_ret = fork();
+ if (fork_ret < 0)
+ error(1, errno, "Cannot go to background");
+ if (fork_ret == 0) {
+ int devnull = open("/dev/null", O_WRONLY);
+ dup2(devnull, 1);
+ }
+ }
+ fprintf(stderr, "Common\n");
+ if (fork_ret == 0) {
+ /* Child */
+ fprintf(stderr, "Child starting childs\n");
+ if (option_masters) start_masters(option_masters, option_first_id);
+ if (option_slaves) start_slaves(option_slaves, option_first_id);
+ sem_post(child_ready);
+ fprintf(stderr, "Child ready\n");
+ } else {
+ /* Parent */
+ fflush(stderr);
+ sem_wait(child_ready);
+ printf("%d\n", fork_ret);
+ exit(0);
+ }
+
wait_for_threads();
if (option_open_once) {