signals.c 3.58 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

Cedric Roux's avatar
Cedric Roux committed
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
#if HAVE_CONFIG_H
# include "config.h"
#endif

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <signal.h>
#include <time.h>
#include <errno.h>

#include "intertask_interface.h"
#include "timer.h"
#include "backtrace.h"
39
#include "assertions.h"
Cedric Roux's avatar
Cedric Roux committed
40 41

#include "signals.h"
42 43 44 45 46 47 48 49 50 51 52 53 54
#include "log.h"

#if defined (LOG_D) && defined (LOG_E)
# define SIG_DEBUG(x, args...)  LOG_D(EMU, x, ##args)
# define SIG_ERROR(x, args...)  LOG_E(EMU, x, ##args)
#endif

#ifndef SIG_DEBUG
# define SIG_DEBUG(x, args...)  do { fprintf(stdout, "[SIG][D]"x, ##args); } while(0)
#endif
#ifndef SIG_ERROR
# define SIG_ERROR(x, args...)  do { fprintf(stdout, "[SIG][E]"x, ##args); } while(0)
#endif
Cedric Roux's avatar
Cedric Roux committed
55

56
static sigset_t set;
Cedric Roux's avatar
Cedric Roux committed
57

58
int signal_mask(void)
Cedric Roux's avatar
Cedric Roux committed
59
{
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
  /* We set the signal mask to avoid threads other than the main thread
   * to receive the timer signal. Note that threads created will inherit this
   * configuration.
   */
  sigemptyset(&set);

  sigaddset (&set, SIGTIMER);
  sigaddset (&set, SIGUSR1);
  sigaddset (&set, SIGABRT);
  sigaddset (&set, SIGSEGV);
  sigaddset (&set, SIGINT);

  if (sigprocmask(SIG_BLOCK, &set, NULL) < 0) {
    perror ("sigprocmask");
    return -1;
  }

  return 0;
Cedric Roux's avatar
Cedric Roux committed
78 79
}

80
int signal_handle(int *end)
Cedric Roux's avatar
Cedric Roux committed
81
{
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
  int ret;
  siginfo_t info;

  sigemptyset(&set);

  sigaddset (&set, SIGTIMER);
  sigaddset (&set, SIGUSR1);
  sigaddset (&set, SIGABRT);
  sigaddset (&set, SIGSEGV);
  sigaddset (&set, SIGINT);

  if (sigprocmask(SIG_BLOCK, &set, NULL) < 0) {
    perror ("sigprocmask");
    return -1;
  }

  /* Block till a signal is received.
   * NOTE: The signals defined by set are required to be blocked at the time
   * of the call to sigwait() otherwise sigwait() is not successful.
   */
  if ((ret = sigwaitinfo(&set, &info)) == -1) {
    perror ("sigwait");
    return ret;
  }

107
  //printf("Received signal %d\n", info.si_signo);
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136

  /* Real-time signals are non constant and are therefore not suitable for
   * use in switch.
   */
  if (info.si_signo == SIGTIMER) {
    timer_handle_signal(&info);
  } else {
    /* Dispatch the signal to sub-handlers */
    switch(info.si_signo) {
    case SIGUSR1:
      SIG_DEBUG("Received SIGUSR1\n");
      *end = 1;
      break;

    case SIGSEGV:   /* Fall through */
    case SIGABRT:
      SIG_DEBUG("Received SIGABORT\n");
      backtrace_handle_signal(&info);
      break;

    case SIGINT:
      printf("Received SIGINT\n");
      itti_send_terminate_message(TASK_UNKNOWN);
      *end = 1;
      break;

    default:
      SIG_ERROR("Received unknown signal %d\n", info.si_signo);
      break;
Cedric Roux's avatar
Cedric Roux committed
137
    }
138
  }
Cedric Roux's avatar
Cedric Roux committed
139

140
  return 0;
Cedric Roux's avatar
Cedric Roux committed
141
}