Beispiel #1
0
/**
 * Run the daemon and handle unix signals
 */
static void run()
{
	sigset_t set;

	/* handle SIGINT and SIGTERM in this handler */
	sigemptyset(&set);
	sigaddset(&set, SIGINT);
	sigaddset(&set, SIGTERM);
	sigprocmask(SIG_BLOCK, &set, NULL);

	while (TRUE)
	{
		int sig;

		sig = sigwaitinfo(&set, NULL);
		if (sig == -1)
		{
			if (errno == EINTR)
			{	/* ignore signals we didn't wait for */
				continue;
			}
			DBG1(DBG_DMN, "waiting for signal failed: %s", strerror(errno));
			return;
		}
		switch (sig)
		{
			case SIGINT:
			{
				DBG1(DBG_DMN, "signal of type SIGINT received. Shutting down");
				charon->bus->alert(charon->bus, ALERT_SHUTDOWN_SIGNAL, sig);
				return;
			}
			case SIGTERM:
			{
				DBG1(DBG_DMN, "signal of type SIGTERM received. Shutting down");
				charon->bus->alert(charon->bus, ALERT_SHUTDOWN_SIGNAL, sig);
				return;
			}
		}
	}
}
static void luasandbox_timer_stop_one(luasandbox_timer * lt, struct timespec * remaining)
{
	static struct timespec zero = {0, 0};
	struct itimerspec its;
	timer_gettime(lt->timer, &its);
	if (remaining) {
		*remaining = its.it_value;
	}

	its.it_value = zero;
	its.it_interval = zero;
	timer_settime(lt->timer, 0, &its, NULL);

	if (lt->cbdata.type == LUASANDBOX_TIMER_PROFILER) {
		// Invalidate the cbdata, delete the timer
		lt->cbdata.sandbox = NULL;
		timer_delete(lt->timer);
		// If the timer event handler is running, wait for it to finish
		// before returning to the caller, otherwise the timer event handler
		// may find itself with a dangling pointer in its local scope.
		while (sem_wait(&lt->cbdata.semaphore) && errno == EINTR);
		sem_destroy(&lt->cbdata.semaphore);
	} else {
		// Block the signal, delete the timer, flush pending signals, restore
		sigset_t sigset, oldset, pendset;
		siginfo_t info;
		sigemptyset(&sigset);
		sigaddset(&sigset, LUASANDBOX_SIGNAL);
		sigprocmask(SIG_BLOCK, &sigset, &oldset);
		timer_delete(lt->timer);
		while (1) {
			sigpending(&pendset);
			if (!sigismember(&pendset, LUASANDBOX_SIGNAL)) {
				break;
			}
			sigwaitinfo(&sigset, &info);
			luasandbox_timer_handle_signal(LUASANDBOX_SIGNAL, &info, NULL);
		}
		sigprocmask(SIG_SETMASK, &oldset, NULL);
	}
}
Beispiel #3
0
static int trv_joystick_wait(void)
{
  sigset_t set;
  struct siginfo value;
  int ret;

  /* Wait for a signal */

  (void)sigemptyset(&set);
  (void)sigaddset(&set, CONFIG_GRAPHICS_TRAVELER_JOYSTICK_SIGNO);
  ret = sigwaitinfo(&set, &value);
  if (ret < 0)
    {
      int errcode = errno;

      fprintf(stderr, "ERROR: sigwaitinfo() failed: %d\n", errcode);
      return -errcode;
    }

  return OK;
}
Beispiel #4
0
/**
 * This is a thread with priority kernel_prio that synchronously waits for
 * rtdal_pipeline signals (usign sigwaitinfo). All signals except thread-specific
 * ones (SIGSEGV,SIGILL,SIGBUS,SIGFPE) are blocked by all threads except this one.
 * Thread-specific signals are handled by ProcThreads which send a SIGRTMIN+1,
 * SIGRTMIN+2,SIGRTMIN+3,SIGRTMIN+4 (respectively) to this thread, which takes
 * actions accordingly.
 *
 * for signals SIGRTMIN to SIGRTMIN+4, cast the rtdal_pipeline object from this
 * si_value pointer and call rtdal_pipeline_recover_thread(pipeline,
 * pipeline->running_process, TRUE)
 */
void sigwait_loop(void) {

	int signum;
	sigset_t set;
	siginfo_t info;

	sigfillset(&set);
	sigdelset(&set,TASK_TERMINATION_SIGNAL);
	while(!sigwait_stops) {
		do {
			signum = sigwaitinfo(&set, &info);
		} while (signum == -1 && errno == EINTR);
		if (signum == -1) {
			poserror(errno, "sigwaitinfo");
			goto out;
		}
		hdebug("detected signal %d\n",signum);
		if (signum == KERNEL_SIG_THREAD_SPECIFIC) {
			printf("[rtdal]: Caught thread-specific signal\n");
#ifdef EXIT_ON_THREADSIG
			fflush(stdout);
			goto out;
#else
			sigwait_loop_process_thread_signal(&info);
#endif
		} else if (signum == SIGINT) {
			printf("Caught SIGINT, exiting\n");
			fflush(stdout);
			goto out;
		} else if (signum != SIGWINCH && signum != SIGCHLD) {
			printf("Got signal %d, exiting\n", signum);
			fflush(stdout);
			goto out;
		}
	}

out:
	kernel_exit();
}
Beispiel #5
0
static int lio_waitall(FAR struct aiocb *const *list, int nent)
{
	sigset_t set;
	int ret;

	/* Loop until all I/O completes */

	for (;;) {
		/* Check if all I/O has completed */

		ret = lio_checkio(list, nent);
		if (ret != -EINPROGRESS) {
			/* All I/O has completed.. We are finished.  */

			return ret;
		}

		/* Then wait for SIGPOLL -- indefinitely.
		 *
		 * NOTE: If completion of the I/O causes other signals to be generated
		 * first, then this will wake up and return EINTR instead of success.
		 */

		sigemptyset(&set);
		sigaddset(&set, SIGPOLL);

		ret = sigwaitinfo(&set, NULL);
		if (ret < 0) {
			/* The most likely reason that we would get here is because some
			 * unrelated signal has been received.
			 */

			int errcode = get_errno();
			fdbg("ERROR: sigwaitinfo failed: %d\n", errcode);
			DEBUGASSERT(errcode > 0);
			return -errcode;
		}
	}
}
Beispiel #6
0
void signal_check_functions(pthread_t tid, sigset_t *ss, union sigval sv)
{
    typedef void (*signal_cb_t)(int );

    (void)kill((pid_t)0, 0);
#if __XSI_VISIBLE
    (void)killpg((pid_t)0, 0);
#endif
#if !__APPLE__
    (void)psiginfo((const siginfo_t *)0, (const char *)0);
#endif
    (void)psignal(0, (const char*)0);
    (void)pthread_kill(tid, 0);
    (void)pthread_sigmask(0, (const sigset_t*)0, (sigset_t*)0);
    (void)raise(0);
    (void)sigaction(0, (const struct sigaction*)0, (struct sigaction*)0);
    (void)sigaddset(ss, 0);
#if __XSI_VISIBLE
    (void)sigaltstack((const stack_t*)0, (stack_t*)0);
#endif
    (void)sigdelset(ss, 0);
    (void)sigemptyset(ss);
    (void)sigfillset(ss);
    (void)sigismember(ss, 0);
    (void)signal(0, (signal_cb_t)0);
    (void)sigpending(ss);
    (void)sigprocmask(0, (const sigset_t*)0, (sigset_t*)0);
#if _POSIX_REALTIME_SIGNALS > 0
    (void)sigqueue((pid_t)0, 0, sv);
#endif
    (void)sigsuspend(ss);
#if _POSIX_REALTIME_SIGNALS > 0
    (void)sigtimedwait((const sigset_t*)0, (siginfo_t*)0, (const struct timespec*)0);
#endif
    (void)sigwait(ss, (int*)0);
#if _POSIX_REALTIME_SIGNALS > 0
    (void)sigwaitinfo(ss, (siginfo_t*)0);
#endif
}
/* Helper function to support starting threads for SIGEV_THREAD.  */
static void *timer_thread_main (void *arg)
{
  /* Wait for the SIGTIMER signal */
  sem_t *sem = (sem_t *)arg;
#ifdef ANDROID
  unsigned long sigset[2];
  memset(&sigset, 0, sizeof(sigset));
#else
  sigset_t sigset;
  sigemptyset(&sigset);
#endif
  sigaddset((sigset_t*)&sigset, SIGTIMER);

  th_timer_tid = gettid();
  sem_post(sem);

  /* Endless loop for waiting for signals. The loop is only ended when
     the thread is canceled.  */
  while (1) {
    siginfo_t si;
    int result;

#ifdef ANDROID
    result = __rt_sigtimedwait((sigset_t*)&sigset, &si, NULL, sizeof(sigset));
#else
    result = sigwaitinfo(&sigset, &si);
#endif
    if (result > 0)
      {
	if (si.si_code == SI_TIMER) {
	  timer *t;
	  t = static_cast<timer*>(si.si_value.sival_ptr);
	  t->alarm.signal();
	}
      }
  }
  return NULL;
}
Beispiel #8
0
Datei: 2-1.c Projekt: 1587/ltp
int main(void)
{
	int pid, rtsig;
	union sigval value;
	struct sigaction act;
	sigset_t selectset;

	act.sa_flags = SA_SIGINFO;
	act.sa_sigaction = myhandler;
	sigemptyset(&act.sa_mask);
	sigemptyset(&selectset);

	for (rtsig = SIGRTMAX; rtsig >= SIGRTMIN; rtsig--) {
		sigaddset(&act.sa_mask, rtsig);
		sighold(rtsig);
		sigaddset(&selectset, rtsig);
	}

	pid = getpid();
	value.sival_int = 5;	/* 5 is just an arbitrary value */

	for (rtsig = SIGRTMAX; rtsig >= SIGRTMIN; rtsig--) {
		sigaction(rtsig, &act, 0);
		if (sigqueue(pid, rtsig, value) != 0) {
			printf
			    ("Test UNRESOLVED: call to sigqueue did not return success\n");
			return PTS_UNRESOLVED;
		}
	}

	if (sigwaitinfo(&selectset, NULL) != SIGRTMIN) {
		printf
		    ("Test FAILED: sigwaitinfo() did not return the lowest of the multiple pending signals between SIGRTMIN and SIGRTMAX\n");
		return PTS_FAIL;
	}

	return PTS_PASS;
}
static void *
timer_notify_thread_func(void *arg)
{
  sigset_t set;
  siginfo_t info;
  my_timer_t *timer;
  pthread_barrier_t *barrier= arg;

  my_thread_init();

  sigemptyset(&set);
  sigaddset(&set, MY_TIMER_EVENT_SIGNO);
  sigaddset(&set, MY_TIMER_KILL_SIGNO);

  /* Get the thread ID of the current thread. */
  timer_notify_thread_id= (pid_t) syscall(SYS_gettid);

  /* Wake up parent thread, timer_notify_thread_id is available. */
  pthread_barrier_wait(barrier);

  while (1)
  {
    if (sigwaitinfo(&set, &info) < 0)
      continue;

    if (info.si_signo == MY_TIMER_EVENT_SIGNO)
    {
      timer= (my_timer_t*)info.si_value.sival_ptr;
      timer->notify_function(timer);
    }
    else if (info.si_signo == MY_TIMER_KILL_SIGNO)
      break;
  }

  my_thread_end();

  return NULL;
}
Beispiel #10
0
void* sigmgr_thread()
{
	sigset_t   waitset, oset;
	siginfo_t  info;
	int        rc;
	pthread_t  ppid = pthread_self();

	pthread_detach(ppid);

	sigemptyset(&waitset);
	sigaddset(&waitset, SIGRTMIN);
	sigaddset(&waitset, SIGUSR1);

	while (1)  {
		rc = sigwaitinfo(&waitset, &info);
		if (rc != -1) {
			printf("sigwaitinfo() fetch the signal - %d\n", rc);
			sig_handler(info.si_signo);
		} else {
			printf("sigwaitinfo() returned err: %d; %s\n", errno, strerror(errno));
		}
	}
}
TEST(signal, sigwaitinfo) {
  // Block SIGALRM.
  sigset_t just_SIGALRM;
  sigemptyset(&just_SIGALRM);
  sigaddset(&just_SIGALRM, SIGALRM);
  sigset_t original_set;
  ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, &original_set));

  // Raise SIGALRM.
  sigval_t sigval;
  sigval.sival_int = 1;
  ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval));

  // Get pending SIGALRM.
  siginfo_t info;
  errno = 0;
  ASSERT_EQ(SIGALRM, sigwaitinfo(&just_SIGALRM, &info));
  ASSERT_EQ(0, errno);
  ASSERT_EQ(SIGALRM, info.si_signo);
  ASSERT_EQ(1, info.si_value.sival_int);

  ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &original_set, NULL));
}
Beispiel #12
0
int ping_via_slots(const char *name, struct servants_list_item *servants)
{
	int sig = 0;
	pid_t pid = 0;
	int status = 0;
	int servants_finished = 0;
	sigset_t procmask;
	siginfo_t sinfo;
	struct servants_list_item *s;

	sigemptyset(&procmask);
	sigaddset(&procmask, SIGCHLD);
	sigprocmask(SIG_BLOCK, &procmask, NULL);

	for (s = servants; s; s = s->next) {
            if(sbd_is_disk(s)) {
                s->pid = assign_servant(s->devname, &slot_ping_wrapper, 0, (const void*)name);
            }
        }

	while (servants_finished < disk_count) {
		sig = sigwaitinfo(&procmask, &sinfo);
		if (sig == SIGCHLD) {
			while ((pid = wait(&status))) {
				if (pid == -1 && errno == ECHILD) {
					break;
				} else {
					s = lookup_servant_by_pid(pid);
					if (s && sbd_is_disk(s)) {
						servants_finished++;
					}
				}
			}
		}
	}
	return 0;
}
Beispiel #13
0
/*[sig_thread]*/
static void *sig_thread(void *arg)
{
	int signum;
	siginfo_t info;

	do {
		signum = sigwaitinfo((sigset_t *)arg, &info);
		if (signum == MYSIG_COUNT)
			printf("Got MYSIG_COUNT; value: %s\n",
			  (char *)info.si_value.sival_ptr);
		else if (signum == MYSIG_STOP) {
			printf("Got MYSIG_STOP; terminating thread\n");
			return (void *)true;
		}
		else
			printf("Got %d\n", signum);
	} while (signum != -1 || errno == EINTR);
	EC_FAIL

EC_CLEANUP_BGN
	EC_FLUSH("sig_thread")
	return (void *)false;
EC_CLEANUP_END
}
Beispiel #14
0
/**
 * 功能: 专职信号处理线程
 * 说明: 
 *      1.将别的线程阻塞起来的信号,全部加入到自己的监听掩码中来
 *      2.无限循环,阻塞起来,等待自己监听的信号到来
 * 注意:
 *      1. 对于共有信号的这种处理,是"同步"方式
 * 返回:成功:0; 失败:-x
 **/
static void* msd_signal_thread_cycle(void *arg)
{    
    sigset_t   waitset;    
    siginfo_t  info;    
    int        rc;
    msd_thread_signal_t *sig_worker = (msd_thread_signal_t *)arg;
    
    MSD_INFO_LOG("Worker[Signal] begin to work");
    
    /* 将别的线程阻塞的信号,全部加入自己的监听范围 */
    sigemptyset(&waitset);
    sigaddset(&waitset, SIGTERM);    
    sigaddset(&waitset, SIGQUIT);
    sigaddset(&waitset, SIGCHLD);
    sigaddset(&waitset, SIGPIPE);
    sigaddset(&waitset, SIGINT);
    sigaddset(&waitset, SIGHUP);

    /* 无线循环阻塞,等待信号到来 */
    while (1)  
    {       
        rc = sigwaitinfo(&waitset, &info);        
        if (rc != MSD_ERR) 
        {   
            /* 同步处理信号 */
            msd_public_signal_handler(info.si_signo, sig_worker);
        } 
        else 
        {            
            MSD_ERROR_LOG("Sigwaitinfo() returned err: %d; %s", errno, strerror(errno));       
        }    

     }
    //free(sig_worker);//msd_destroy_instance中会统一释放资源
    return (void *)NULL;
}
Beispiel #15
0
void runFailure1() {
    sigwaitinfo(anyset(), NULL);
}
Beispiel #16
0
void runFailure() {
    sigwaitinfo(NULL, anyinfo());
}
Beispiel #17
0
void runSuccess() {
    sigwaitinfo(anyset(), anyinfo());
}
Beispiel #18
0
static int my_sigwaitinfo(const sigset_t* set, siginfo_t* info, struct timespec* timeout)
{
	return sigwaitinfo(set, info);
}
Beispiel #19
0
int
main(void)
{
	int status;
	struct mq_attr attr;
	struct sigaction sa;
	sigset_t set;
	siginfo_t info;
	mqd_t mq;
	pid_t pid;

	PLAIN_REQUIRE_KERNEL_MODULE("mqueuefs", 0);

	mq_unlink(MQNAME);

	sigemptyset(&set);
	sigaddset(&set, SIGRTMIN);
	sigprocmask(SIG_BLOCK, &set, NULL);
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = SA_SIGINFO;
	sa.sa_sigaction = (void *) SIG_DFL;
	sigaction(SIGRTMIN, &sa, NULL);

	attr.mq_maxmsg  = 5;
	attr.mq_msgsize = 128;
	mq = mq_open(MQNAME, O_CREAT | O_RDWR | O_EXCL, 0666, &attr);
	if (mq == (mqd_t)-1)
		err(1, "mq_open()");
	status = mq_getattr(mq, &attr);
	if (status)
		err(1, "mq_getattr()");
	pid = fork();
	if (pid == 0) { /* child */
		int prio, j, i;
		char *buf;
		struct sigevent sigev;

		signal(SIGALRM, sighandler);

		sigev.sigev_notify = SIGEV_SIGNAL;
		sigev.sigev_signo = SIGRTMIN;
		sigev.sigev_value.sival_int = 2;

		mq_close(mq);
		mq = mq_open(MQNAME, O_RDWR | O_NONBLOCK);
		if (mq == (mqd_t)-1)
			err(1, "child: mq_open");
		buf = malloc(attr.mq_msgsize);
		for (j = 0; j < LOOPS; ++j) {
			alarm(3);
			status = mq_notify(mq, &sigev);
			if (status)
				err(1, "child: mq_notify");
			status = sigwaitinfo(&set, &info);
			if (status == -1)
				err(1, "child: sigwaitinfo");
			if (info.si_value.sival_int != 2)
				err(1, "child: sival_int");
			status = mq_receive(mq, buf, attr.mq_msgsize, &prio);
			if (status == -1)
				err(2, "child: mq_receive");
			for (i = 0; i < attr.mq_msgsize; ++i)
				if (buf[i] != i)
					err(3, "child: message data corrupted");
			if (prio != PRIO)
				err(4, "child: priority is incorrect: %d",
					 prio);
		}
		alarm(0);
		free(buf);
		mq_close(mq);
		return (0);
	} else if (pid == -1) {
		err(1, "fork()");
	} else {
		char *buf;
		int i, j;

		signal(SIGALRM, sighandler);
		buf = malloc(attr.mq_msgsize);
		for (j = 0; j < LOOPS; ++j) {
			for (i = 0; i < attr.mq_msgsize; ++i) {
				buf[i] = i;
			}
			alarm(3);
			status = mq_send(mq, buf, attr.mq_msgsize, PRIO);
			if (status) {
				kill(pid, SIGKILL);
				err(2, "mq_send()");
			}
		}
		alarm(3);
		wait(&status);
		alarm(0);
	}
	status = mq_close(mq);
	if (status)
		err(1, "mq_close");
	mq_unlink(MQNAME);
	return (0);
}
Beispiel #20
0
static void pcntl_sigwaitinfo(INTERNAL_FUNCTION_PARAMETERS, int timedwait) /* {{{ */
{
    zval            *user_set, **user_signo, *user_siginfo = NULL;
    long             tv_sec = 0, tv_nsec = 0;
    sigset_t         set;
    HashPosition     pos;
    int              signo;
    siginfo_t        siginfo;
    struct timespec  timeout;

    if (timedwait) {
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|zll", &user_set, &user_siginfo, &tv_sec, &tv_nsec) == FAILURE) {
            return;
        }
    } else {
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|z", &user_set, &user_siginfo) == FAILURE) {
            return;
        }
    }

    if (sigemptyset(&set) != 0) {
        PCNTL_G(last_error) = errno;
        php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
        RETURN_FALSE;
    }

    zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(user_set), &pos);
    while (zend_hash_get_current_data_ex(Z_ARRVAL_P(user_set), (void **)&user_signo, &pos) == SUCCESS)
    {
        if (Z_TYPE_PP(user_signo) != IS_LONG) {
            SEPARATE_ZVAL(user_signo);
            convert_to_long_ex(user_signo);
        }
        signo = Z_LVAL_PP(user_signo);
        if (sigaddset(&set, signo) != 0) {
            PCNTL_G(last_error) = errno;
            php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
            RETURN_FALSE;
        }
        zend_hash_move_forward_ex(Z_ARRVAL_P(user_set), &pos);
    }

    if (timedwait) {
        timeout.tv_sec  = (time_t) tv_sec;
        timeout.tv_nsec = tv_nsec;
        signo = sigtimedwait(&set, &siginfo, &timeout);
    } else {
        signo = sigwaitinfo(&set, &siginfo);
    }
    if (signo == -1 && errno != EAGAIN) {
        PCNTL_G(last_error) = errno;
        php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
    }

    /*
     * sigtimedwait and sigwaitinfo can return 0 on success on some
     * platforms, e.g. NetBSD
     */
    if (!signo && siginfo.si_signo) {
        signo = siginfo.si_signo;
    }

    if (signo > 0 && user_siginfo) {
        if (Z_TYPE_P(user_siginfo) != IS_ARRAY) {
            zval_dtor(user_siginfo);
            array_init(user_siginfo);
        } else {
            zend_hash_clean(Z_ARRVAL_P(user_siginfo));
        }
        add_assoc_long_ex(user_siginfo, "signo", sizeof("signo"), siginfo.si_signo);
        add_assoc_long_ex(user_siginfo, "errno", sizeof("errno"), siginfo.si_errno);
        add_assoc_long_ex(user_siginfo, "code",  sizeof("code"),  siginfo.si_code);
        switch(signo) {
#ifdef SIGCHLD
        case SIGCHLD:
            add_assoc_long_ex(user_siginfo,   "status", sizeof("status"), siginfo.si_status);
# ifdef si_utime
            add_assoc_double_ex(user_siginfo, "utime",  sizeof("utime"),  siginfo.si_utime);
# endif
# ifdef si_stime
            add_assoc_double_ex(user_siginfo, "stime",  sizeof("stime"),  siginfo.si_stime);
# endif
            add_assoc_long_ex(user_siginfo,   "pid",    sizeof("pid"),    siginfo.si_pid);
            add_assoc_long_ex(user_siginfo,   "uid",    sizeof("uid"),    siginfo.si_uid);
            break;
#endif
        case SIGILL:
        case SIGFPE:
        case SIGSEGV:
        case SIGBUS:
            add_assoc_double_ex(user_siginfo, "addr", sizeof("addr"), (long)siginfo.si_addr);
            break;
#ifdef SIGPOLL
        case SIGPOLL:
            add_assoc_long_ex(user_siginfo, "band", sizeof("band"), siginfo.si_band);
# ifdef si_fd
            add_assoc_long_ex(user_siginfo, "fd",   sizeof("fd"),   siginfo.si_fd);
# endif
            break;
#endif
            EMPTY_SWITCH_DEFAULT_CASE();
        }
    }

    RETURN_LONG(signo);
}
Beispiel #21
0
int
main(int argc, char **argv)
{
	(void)argc;
	(void)argv;
	int fd = hcall_init();

	uval laddr = mem_hold(4096);
	char *ptr = mmap(NULL, 4096,
			 PROT_READ | PROT_WRITE, MAP_SHARED,
			 fd, laddr);

	args.opcode = H_CREATE_MSGQ;
	args.args[0] = laddr;
	args.args[1] = 4096;
	args.args[2] = 0;

	hcall(&args);

	uval xirr = args.args[0];

	printf(UVAL_CHOOSE("hcall: %x (%lx) %x %x\n",
			   "hcall: %lx (%lx) %lx %lx\n"),
	       args.retval, xirr, args.args[1], args.args[2]);

	sigfillset(&msg_sig.sa_mask);
	sigaction(SIGRTMIN, &msg_sig, NULL);

	ora.oh_interrupt = xirr;
	ora.oh_signal = SIGRTMIN;
	ioctl(fd, OH_IRQ_REFLECT, &ora);

	struct msg_queue *mq = (struct msg_queue *)ptr;

	printf(UVAL_CHOOSE("msgq: %lx %lx %lx\n",
			   "msgq: %lx %lx %lx\n"),
	       mq->bufSize, mq->head, mq->tail);

	uval lpid;

	args.opcode = H_GET_LPID;
	hcall(&args);
	lpid = args.args[0];
	printf(UVAL_CHOOSE("self lpid: %lx\n", "self lpid: %lx\n"), lpid);

	while (1) {
		sigset_t set;

		sigemptyset(&set);
		sigaddset(&set, SIGRTMIN);

		siginfo_t info;
		int ret = sigwaitinfo(&set, &info);

		printf("sigwaitinfo: %d\n", ret);
		printf(UVAL_CHOOSE("msgq: %lx %lx %lx\n",
				   "msgq: %lx %lx %lx\n"),
		       mq->bufSize, mq->head, mq->tail);

		int tail = mq->tail % mq->bufSize;
		struct async_msg_s *msg = &mq->buffer[tail];

		printf(UVAL_CHOOSE("msg from: %lx\n", "msg from: %lx\n"),
		       msg->am_source);
		printf(UVAL_CHOOSE("msg raw data: %lx %lx %lx %lx\n",
				   "msg raw data: %lx %lx %lx %lx\n"),
		       msg->am_data.amu_data[0], msg->am_data.amu_data[1],
		       msg->am_data.amu_data[2], msg->am_data.amu_data[3]);

		++mq->tail;
	}

	close(fd);
	return 0;
}
Beispiel #22
0
/**
 * int main()
 *
 * Invokes the backend, waits until it has successfully detached from the I/O ports,
 * and then quits. 
 */
int main() {
  /** Block SIGUSR1, SIGCHLD until we can handle them. */
  sigset_t waitset;
  sigemptyset(&waitset);
  sigaddset(&waitset, SIGUSR1);
  sigaddset(&waitset, SIGCHLD);
  sigprocmask(SIG_BLOCK, &waitset, NULL);
  
  /** Install signal handlers for those signals. */
  struct sigaction actions;
  sigemptyset(&actions.sa_mask);
  actions.sa_flags = SA_SIGINFO;
  actions.sa_sigaction = dummy_signal_action;
  sigaction(SIGUSR1, &actions, NULL);
  sigaction(SIGCHLD, &actions, NULL);
  
  /** Fork the child */
  pid_t childpid = fork();
  if(childpid < 0) {
    perror("Could not fork() child:");
    return 1;
  }

  if(childpid == 0) {
    /* Detach session, setup file descriptors, spawn Racket process. */
    if(setsid() < 0) {
      perror("Could not detach session:");
      return 1;
    }

#ifndef NDEBUG
    putenv("PLTSTDERR=debug");
#endif

    // Prefer build directory if debug build.
    if(!IS_INSTALLED() && access(SEASHELL_DEBUG_MAIN, F_OK) != -1) {
      char * argv2[] = {SEASHELL_DEBUG_MAIN, "-s", NULL};
      execv(SEASHELL_DEBUG_MAIN, argv2);
      perror("Could not execv() the Seashell backend:");
      return 1;
    }
    // Main case if not in debug mode (fall through if)
    char * argv[] = {SEASHELL_MAIN, "-s", NULL};
    execv(SEASHELL_MAIN, argv);

    perror("Could not execv() the Seashell backend:");
    return 1;
  } else {
    /* Setup file descriptors, pass key and port, exit. */
    while (true) {
      siginfo_t info;
      int result = sigwaitinfo(&waitset, &info);

      if (result < 0) {
        if (errno == EINTR) {
          continue;
        } else {
          perror("sigwaitinfo failed with:");
          return 1;
        }
      } else {
        /** Wait for the process to quit (successfully) or detach. */
        if (info.si_signo == SIGCHLD) {
          int status = 0;
          result = waitpid(childpid, &status, WCONTINUED | WUNTRACED);

          if (result < 0) {
            perror("wait failed with:");
            return 1;
          } else if (WIFEXITED(status)) {
            return WEXITSTATUS(status);
          }
        } else if (info.si_signo == SIGUSR1) {
          return 0;
        }
      }
    }
  }
}
static ptid_t
nto_wait (ptid_t ptid,
	  struct target_waitstatus *ourstatus, int target_options)
{
  sigset_t set;
  siginfo_t info;
  procfs_status status;
  const int trace_mask = (_DEBUG_FLAG_TRACE_EXEC | _DEBUG_FLAG_TRACE_RD
			  | _DEBUG_FLAG_TRACE_WR | _DEBUG_FLAG_TRACE_MODIFY);

  TRACE ("%s\n", __func__);

  ourstatus->kind = TARGET_WAITKIND_SPURIOUS;

  sigemptyset (&set);
  sigaddset (&set, SIGUSR1);

  devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
  while (!(status.flags & _DEBUG_FLAG_ISTOP))
    {
      sigwaitinfo (&set, &info);
      devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status),
	      0);
    }
  nto_find_new_threads (&nto_inferior);

  if (status.flags & _DEBUG_FLAG_SSTEP)
    {
      TRACE ("SSTEP\n");
      ourstatus->kind = TARGET_WAITKIND_STOPPED;
      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
    }
  /* Was it a breakpoint?  */
  else if (status.flags & trace_mask)
    {
      TRACE ("STOPPED\n");
      ourstatus->kind = TARGET_WAITKIND_STOPPED;
      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
    }
  else if (status.flags & _DEBUG_FLAG_ISTOP)
    {
      TRACE ("ISTOP\n");
      switch (status.why)
	{
	case _DEBUG_WHY_SIGNALLED:
	  TRACE ("  SIGNALLED\n");
	  ourstatus->kind = TARGET_WAITKIND_STOPPED;
	  ourstatus->value.sig =
	    target_signal_from_host (status.info.si_signo);
	  nto_inferior.exit_signo = ourstatus->value.sig;
	  break;
	case _DEBUG_WHY_FAULTED:
	  TRACE ("  FAULTED\n");
	  ourstatus->kind = TARGET_WAITKIND_STOPPED;
	  if (status.info.si_signo == SIGTRAP)
	    {
	      ourstatus->value.sig = 0;
	      nto_inferior.exit_signo = 0;
	    }
	  else
	    {
	      ourstatus->value.sig =
		target_signal_from_host (status.info.si_signo);
	      nto_inferior.exit_signo = ourstatus->value.sig;
	    }
	  break;

	case _DEBUG_WHY_TERMINATED:
	  {
	    int waitval = 0;

	    TRACE ("  TERMINATED\n");
	    waitpid (ptid_get_pid (ptid), &waitval, WNOHANG);
	    if (nto_inferior.exit_signo)
	      {
		/* Abnormal death.  */
		ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
		ourstatus->value.sig = nto_inferior.exit_signo;
	      }
	    else
	      {
		/* Normal death.  */
		ourstatus->kind = TARGET_WAITKIND_EXITED;
		ourstatus->value.integer = WEXITSTATUS (waitval);
	      }
	    nto_inferior.exit_signo = 0;
	    break;
	  }

	case _DEBUG_WHY_REQUESTED:
	  TRACE ("REQUESTED\n");
	  /* We are assuming a requested stop is due to a SIGINT.  */
	  ourstatus->kind = TARGET_WAITKIND_STOPPED;
	  ourstatus->value.sig = TARGET_SIGNAL_INT;
	  nto_inferior.exit_signo = 0;
	  break;
	}
    }

  return ptid_build (status.pid, status.tid, 0);
}
Beispiel #24
0
void slow_timer_main()
{
	int n;
	ticks_t ret;
	struct timer_ln* tl;
	unsigned short i;
#ifdef USE_SIGWAIT
	int sig;
#endif

	in_slow_timer=1; /* mark this process as the slow timer */
	while(1){
#ifdef USE_SIGWAIT
		n=sigwait(&slow_timer_sset, &sig);
#else
		n=sigwaitinfo(&slow_timer_sset, 0);
#endif
		if (n==-1){
			if (errno==EINTR) continue; /* some other signal, ignore it */
			LM_ERR("sigwaitinfo failed: %s [%d]\n", strerror(errno), errno);
			sleep(1);
			/* try to continue */
		}
#ifdef USE_SIGWAIT
	if (sig!=SLOW_TIMER_SIG){
#ifdef __OS_darwin
		/* on darwin sigwait is buggy: it will cause extreme slow down
		 *  on signal delivery for the signals it doesn't wait on
		 *  (on darwin 8.8.0, g4 1.5Ghz I've measured a 36s delay!).
		 * To work arround this bug, we sigwait() on all the signals we
		 * are interested in ser and manually call the master signal handler
		 * if the signal!= slow timer signal -- andrei */
		sig_usr(sig);
#endif
		continue;
	}
#endif
		/* update the local cfg if needed */
		cfg_update();

		LOCK_SLOW_TIMER_LIST();
		while(*s_idx!=*t_idx){
			i= *s_idx%SLOW_LISTS_NO;
			while(slow_timer_lists[i].next!=
					(struct timer_ln*)&slow_timer_lists[i]){
				tl=slow_timer_lists[i].next;
				_timer_rm_list(tl);
				tl->next=tl->prev=0;
#ifdef TIMER_DEBUG
				tl->expires_no++;
#endif
				SET_RUNNING_SLOW(tl);
				UNLOCK_SLOW_TIMER_LIST();
					ret=tl->f(*ticks, tl, tl->data);
					/* reset the configuration group handles */
					cfg_reset_all();
					if (ret==0){
						/* one shot */
						UNSET_RUNNING_SLOW();
						LOCK_SLOW_TIMER_LIST();
					}else{
						/* not one shot, re-add it */
						LOCK_TIMER_LIST(); /* add it to the "main"  list */
							RESET_SLOW_LIST(tl);
							if (ret!=(ticks_t)-1) /* != periodic */
								tl->initial_timeout=ret;
							_timer_add(*ticks, tl);
						UNLOCK_TIMER_LIST();
						LOCK_SLOW_TIMER_LIST();
						UNSET_RUNNING_SLOW();
					}
			}
			(*s_idx)++;
		}
		UNLOCK_SLOW_TIMER_LIST();
	}

}
int
main(int argc, char *argv[])
{
    struct sigevent sev;
    mqd_t mqd;
    struct mq_attr attr;
    void *buffer;
    ssize_t numRead;
    sigset_t blockMask;
    siginfo_t si;

    if (argc != 2 || strcmp(argv[1], "--help") == 0)
        usageErr("%s mq-name\n", argv[0]);

    mqd = mq_open(argv[1], O_RDONLY | O_NONBLOCK);
    if (mqd == (mqd_t) -1)
        errExit("mq_open");

    /* Determine mq_msgsize for message queue, and allocate an input buffer
       of that size */

    if (mq_getattr(mqd, &attr) == -1)
        errExit("mq_getattr");
    buffer = malloc(attr.mq_msgsize);
    if (buffer == NULL)
        errExit("malloc");

    /* Block the signal that we'll accept using sigwaitinfo() */

    sigemptyset(&blockMask);
    sigaddset(&blockMask, NOTIFY_SIG);
    if (sigprocmask(SIG_BLOCK, &blockMask, NULL) == -1)
        errExit("sigprocmask");

    /* Set up message notification using the signal NOTIFY_SIG */

    sev.sigev_notify = SIGEV_SIGNAL;
    sev.sigev_signo = NOTIFY_SIG;
    sev.sigev_value.sival_ptr = &mqd;
                /* This allows us to obtain a pointer to 'mqd' in the
                   siginfo_t structure returned by sigwaitinfo() */

    if (mq_notify(mqd, &sev) == -1)
        errExit("mq_notify");

    for (;;) {

        /* Wait for a signal; when it is received, display associated
           information */

        if (sigwaitinfo(&blockMask, &si) == -1)
            errExit("sigwaitinfo");

        printf("Accepted signal:\n");
        printf("        si_signo   = %d\n", si.si_signo);
        printf("        si_pid     = %ld\n", (long) si.si_pid);
        printf("        si_uid     = %ld\n", (long) si.si_uid);
        printf("        si_code    = %d (%s)\n", si.si_code,
                (si.si_code == SI_MESGQ) ? "SI_MESGQ" : "???");
        printf("        *sival_ptr = %p\n\n", si.si_value.sival_ptr);

        /* Reestablish message notification */

        if (mq_notify(mqd, &sev) == -1)
            errExit("mq_notify");

        /* Although only one signal might have been queued (if NOTIFY_SIG
           is a standard signal) we might have received multiple messages,
           so use nonblocking mq_receive() calls inside a loop to read
           as many messages as possible. */

        while ((numRead = mq_receive(mqd, buffer, attr.mq_msgsize, NULL)) >= 0)
            printf("Read %ld bytes\n", (long) numRead);

        if (errno != EAGAIN)            /* Unexpected error */
            errExit("mq_receive");
    }
}
Beispiel #26
0
int waitid(idtype_t idtype, id_t id, siginfo_t *info, int options)
{
  FAR _TCB *rtcb = (FAR _TCB *)g_readytorun.head;
  sigset_t sigset;
  int err;
  int ret;

  /* MISSING LOGIC:   If WNOHANG is provided in the options, then this function
   * should returned immediately.  However, there is no mechanism available now
   * know if the thread has child:  The children remember their parents (if
   * CONFIG_SCHED_HAVE_PARENT) but the parents do not remember their children.
   */

  /* None of the options are supported except for WEXITED (which must be
   * provided.  Currently SIGCHILD always reports CLD_EXITED so we cannot
   * distinguish any other events.
   */

#ifdef CONFIG_DEBUG
  if (options != WEXITED)
    {
      set_errno(ENOSYS);
      return ERROR;
    }
#endif

  /* Create a signal set that contains only SIGCHLD */

  (void)sigemptyset(&sigset);
  (void)sigaddset(&sigset, SIGCHLD);

  /* Disable pre-emption so that nothing changes while the loop executes */

  sched_lock();

  /* Verify that this task actually has children and that the the requeste
   * TCB is actually a child of this task.
   */

  if (rtcb->nchildren == 0)
    {
      err = ECHILD;
      goto errout_with_errno;
    }
  else if (idtype == P_PID)
    {
     /* Get the TCB corresponding to this PID and make sure it is our child. */

      FAR _TCB *ctcb = sched_gettcb((pid_t)id);
      if (!ctcb || ctcb->parent != rtcb->pid)
        {
          err = ECHILD;
          goto errout_with_errno;
        }
    }

  /* Loop until the child that we are waiting for dies */

  for (;;)
    {
      /* Check if the task has already died. Signals are not queued in
       * NuttX.  So a possibility is that the child has died and we
       * missed the death of child signal (we got some other signal
       * instead).
       */

      if (rtcb->nchildren == 0 ||
          (idtype == P_PID && (ret = kill((pid_t)id, 0)) < 0))
        {
          /* We know that the child task was running okay we stared,
           * so we must have lost the signal.  What can we do?
           * Let's claim we were interrupted by a signal.
           */

          err = EINTR;
          goto errout_with_errno;
        }

      /* Wait for any death-of-child signal */

      ret = sigwaitinfo(&sigset, info);
      if (ret < 0)
        {
          goto errout;
        }

      /* Make there this was SIGCHLD */

      if (info->si_signo == SIGCHLD)
        {
          /* Yes.. Are we waiting for the death of a specific child? */

          if (idtype == P_PID)
            {
              /* Was this the death of the thread we were waiting for? */

              if (info->si_pid == (pid_t)id)
                {
                   /* Yes... return success */

                   break;
                }
            }

          /* Are we waiting for any child to change state? */

          else if (idtype == P_ALL)
            {
              /* Return success */

              break;
            }

          /* Other ID types are not supported */

          else /* if (idtype == P_PGID) */
            {
              set_errno(ENOSYS);
              goto errout;
            }
        }
    }

  sched_unlock();
  return OK;

errout_with_errno:
  set_errno(err);
errout:
  sched_unlock();
  return ERROR;
}
Beispiel #27
0
//следим за потомком
int TDaemon::MonitorProc()
{
    int      pid;
    int      status;
    int      need_start = 1;
    sigset_t sigset;
    siginfo_t siginfo;
    // настраиваем сигналы которые будем обрабатывать
    sigemptyset(&sigset);
    
    // сигнал остановки процесса пользователем
    sigaddset(&sigset, SIGQUIT);
    
    // сигнал для остановки процесса пользователем с терминала
    sigaddset(&sigset, SIGINT);
    
    // сигнал запроса завершения процесса
    sigaddset(&sigset, SIGTERM);
    
    // сигнал посылаемый при изменении статуса дочернего процесса
    sigaddset(&sigset, SIGCHLD); 
    
    // пользовательский сигнал который мы будем использовать для обновления конфига
    sigaddset(&sigset, SIGHUP); 
    sigprocmask(SIG_BLOCK, &sigset, NULL);

    // данная функция создаст файл с нашим PID'ом
    SetPidFile(PID_FILE.c_str());
    // бесконечный цикл работы
    for (;;)
    {
        // если необходимо создать потомка
        if (need_start)
        {
            // создаём потомка
            pid = fork();
        }
        
        need_start = 1;
        
        if (pid == -1) // если произошла ошибка
        {
            // запишем в лог сообщение об этом
            WriteLog("%s [MONITOR] Fork failed (%s)\n",getTime(), strerror(errno));
        }
        else if (!pid) // если мы потомок
        {
            // данный код выполняется в потомке
            // запустим функцию отвечающую за работу демона
            status = WorkProc();
            // завершим процесс
            exit(status);
        }
        else // если мы родитель
        {
            // данный код выполняется в родителе
            
            // ожидаем поступление сигнала
            sigwaitinfo(&sigset, &siginfo);
            // если пришел сигнал от потомка
            if (siginfo.si_signo == SIGCHLD)
            {
                // получаем статус завершение
                wait(&status);
                
                // преобразуем статус в нормальный вид
                status = WEXITSTATUS(status);

                 // если потомок завершил работу с кодом говорящем о том, что нет нужды дальше работать
                if (status == CHILD_NEED_TERMINATE)
                {
                    // запишем в лог сообщени об этом 
                    WriteLog("%s [MONITOR] Child stopped\n", getTime());
                    
                    // прервем цикл
                    break;
                }
                else if (status == CHILD_NEED_WORK) // если требуется перезапустить потомка
                {
                    // запишем в лог данное событие
                    WriteLog("%s [MONITOR] Child restart\n", getTime());
                }
            }
            else if (siginfo.si_signo == SIGHUP) // если пришел сигнал что необходимо перезагрузить конфиг
            {
                kill(pid, SIGHUP); // перешлем его потомку
                need_start = 0; // установим флаг что нам не надо запускать потомка заново
            }
            else // если пришел какой-либо другой ожидаемый сигнал
            {
                // запишем в лог информацию о пришедшем сигнале
                WriteLog("%s [MONITOR] Signal %s\n", getTime(), strsignal(siginfo.si_signo));
                
                // убьем потомка
                kill(pid, SIGTERM);
                status = 0;
                break;
            }
        }
    }

    // запишем в лог, что мы остановились
    WriteLog("%s [MONITOR] Stop\n", getTime());
    
    // удалим файл с PID'ом
    unlink(PID_FILE.c_str());
    
    return status;
}
main (int argc, char **argv)
{
  struct sigaction sa;
  timer_t my_alarm;
  struct sigevent sigspec;
  union sigval value;
  int status;
  sigset_t sigset;


  if (argc < 2) {
    printf("syntax : ex2 measure_time [sec]\n");
    exit(1);
  }

// Défini le moment en seconde où le timer terminera. 
// Pas d'intervalle définit donc il déclenche une seule fois.
  setting.it_value.tv_sec = atoi(argv[1]);
  setting.it_value.tv_nsec = 0;
  setting.it_interval.tv_sec = 0;
  setting.it_interval.tv_nsec = 0;
  
// action signal info et définition de la fonction fin comme action
// SIGINFO signifie que des signaux POSIX4 ŝont attendus
  sigemptyset(&sa.sa_mask);
  sa.sa_flags = SA_SIGINFO;
  sa.sa_sigaction = fin;

// Sigaction change sa pour le signal de timer
  if (sigaction(MYSIGALARM, &sa, NULL) < 0) {
    perror("sigaction MYSIGALARM");
    exit(1);
  }

// On définit ici quel type de signal est attendu
  sigspec.sigev_signo = MYSIGALARM;
  sigspec.sigev_notify = SIGEV_SIGNAL;
  sigspec.sigev_value.sival_int = 1;
  
// on crée notre timer, qui n'est pas encore déclenché ici. 
// Son pointeur est enregistré dans my_alarm.
// CLOCK_REALTIME est l'horloge système.
// sigspec est ici l'événement à envoyer quand le timer termine le décompte.
  if (timer_create(CLOCK_REALTIME, &sigspec, &my_alarm) != 0) {
    perror("timer_create");
    exit(1);
  }

// On lance le timer avec les paramètres définis précédemment
  if (timer_settime(my_alarm, 0, &setting, NULL) != 0) {
    perror("timer_settime");
    exit(1);
  }

// On vide sigset pour le préparer à recevoir sa nouvelle valeur
  sigemptyset(&sigset);
// On définit sigset avec la valeur SIGRTMAX, la borne max (donc de basse priorité!)
  sigaddset(&sigset, MYSIGALARM);
// On attend que le signal soit déclenché par le timer. Dès qu'il est intercepté,
// la fonction se termine
  status = sigwaitinfo(&sigset, NULL);
  printf("recu le signal # %d, handler_execute = %d status = %d\n", nb, handler_execute,status);
  if (status == -1) perror("sigsuspend");
  
}
Beispiel #29
0
void *s_signalListener( void *my_stack )
{
   static BOOL bFirst = TRUE;
   sigset_t passall;
   HB_STACK *pStack = (HB_STACK*) my_stack;
#if defined( HB_OS_BSD )
   int sig;
#else
   siginfo_t sinfo;
#endif

#ifdef HB_THREAD_TLS_KEYWORD
   hb_thread_stack = my_stack;
#else
   pthread_setspecific( hb_pkCurrentStack, my_stack );
#endif

   pStack->th_id = HB_CURRENT_THREAD();
   hb_threadLinkStack( pStack );
   HB_STACK_LOCK;

   // and now accepts all signals
   sigemptyset( &passall );

   // and wait for all signals
   sigaddset( &passall, SIGHUP );
   sigaddset( &passall, SIGQUIT );
   sigaddset( &passall, SIGILL );
   sigaddset( &passall, SIGABRT );
   sigaddset( &passall, SIGFPE );
   sigaddset( &passall, SIGSEGV );
   sigaddset( &passall, SIGTERM );
   sigaddset( &passall, SIGUSR1 );
   sigaddset( &passall, SIGUSR2 );
   sigaddset( &passall, SIGHUP );

   pthread_cleanup_push( hb_threadTerminator, my_stack );
   pthread_setcanceltype( PTHREAD_CANCEL_DEFERRED, NULL );
   pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, NULL );

   while ( 1 ) {
      // allow safe cancelation
      HB_STACK_UNLOCK;

      // reset signal handling; this is done here (so I don't
      // mangle with pthread_ calls, and I don't hold mutexes),
      // and just once (doing it twice would be useless).
      if ( bFirst ) {
         pthread_sigmask( SIG_SETMASK, &passall, NULL );
         bFirst = FALSE;
      }

      // This is also a cancelation point. When the main thread
      // is done, it will kill all the threads having a stack
      // including this one.
      // ATM we don't care very much about signal handling during
      // termination: no handler is set for them, so the DFL
      // action is taken (and that should be fine).
#if defined( HB_OS_BSD )
      sigwait( &passall, &sig );
#else
      sigwaitinfo( &passall, &sinfo );
#endif

      // lock stack before passing the ball to VM.
      HB_STACK_LOCK;
#if defined( HB_OS_BSD )
      s_signalHandler( sig, NULL, NULL );
#else
      s_signalHandler( sinfo.si_signo, &sinfo, NULL );
#endif
   }

   pthread_cleanup_pop( 1 );
   return 0;
}
Beispiel #30
0
/**
 * Run the daemon and handle unix signals
 */
static int run()
{
	sigset_t set;

	/* handle SIGINT, SIGHUP and SIGTERM in this handler */
	sigemptyset(&set);
	sigaddset(&set, SIGINT);
	sigaddset(&set, SIGHUP);
	sigaddset(&set, SIGTERM);
	sigaddset(&set, SIGUSR1);
	sigprocmask(SIG_BLOCK, &set, NULL);

	while (TRUE)
	{
		int sig;

		sig = sigwaitinfo(&set, NULL);
		if (sig == -1)
		{
			if (errno == EINTR)
			{	/* ignore signals we didn't wait for */
				continue;
			}
			DBG1(DBG_DMN, "waiting for signal failed: %s", strerror(errno));
			return 1;
		}
		switch (sig)
		{
			case SIGHUP:
			{
				DBG1(DBG_DMN, "signal of type SIGHUP received. Reloading "
					 "configuration");
				if (lib->settings->load_files(lib->settings, lib->conf, FALSE))
				{
					charon->load_loggers(charon, levels, TRUE);
					lib->plugins->reload(lib->plugins, NULL);
				}
				else
				{
					DBG1(DBG_DMN, "reloading config failed, keeping old");
				}
				break;
			}
			case SIGINT:
			{
				DBG1(DBG_DMN, "signal of type SIGINT received. Shutting down");
				charon->bus->alert(charon->bus, ALERT_SHUTDOWN_SIGNAL, sig);
				return 0;
			}
			case SIGTERM:
			{
				DBG1(DBG_DMN, "signal of type SIGTERM received. Shutting down");
				charon->bus->alert(charon->bus, ALERT_SHUTDOWN_SIGNAL, sig);
				return 0;
			}
			case SIGUSR1:
			{	/* an error occurred */
				charon->bus->alert(charon->bus, ALERT_SHUTDOWN_SIGNAL, sig);
				return 1;
			}
		}
	}
}