Exemplo n.º 1
0
bool    _POSIX_signals_Check_signal(
  POSIX_API_Control  *api,
  int                 signo,
  bool                is_global
)
{
  siginfo_t                   siginfo_struct;
  sigset_t                    saved_signals_blocked;

  if ( ! _POSIX_signals_Clear_signals( api, signo, &siginfo_struct,
                                       is_global, true ) )
    return false;

  /*
   *  Since we made a union of these, only one test is necessary but this is
   *  safer.
   */
  #if defined(RTEMS_DEBUG)
    assert( _POSIX_signals_Vectors[ signo ].sa_handler ||
            _POSIX_signals_Vectors[ signo ].sa_sigaction );
  #endif

  /*
   *  Just to prevent sending a signal which is currently being ignored.
   */
  if ( _POSIX_signals_Vectors[ signo ].sa_handler == SIG_IGN )
    return false;

  /*
   *  Block the signals requested in sa_mask
   */
  saved_signals_blocked = api->signals_blocked;
  api->signals_blocked |= _POSIX_signals_Vectors[ signo ].sa_mask;

  /*
   *  Here, the signal handler function executes
   */
  switch ( _POSIX_signals_Vectors[ signo ].sa_flags ) {
    case SA_SIGINFO:
      (*_POSIX_signals_Vectors[ signo ].sa_sigaction)(
        signo,
        &siginfo_struct,
        NULL        /* context is undefined per 1003.1b-1993, p. 66 */
      );
      break;
    default:
      (*_POSIX_signals_Vectors[ signo ].sa_handler)( signo );
      break;
  }

  /*
   *  Restore the previous set of blocked signals
   */
  api->signals_blocked = saved_signals_blocked;

  return true;
}
Exemplo n.º 2
0
Arquivo: init.c Projeto: goetzpf/rtems
void *POSIX_Init(
    void *argument
)
{
    struct sigaction    act;
    siginfo_t           info;
    bool                bc;

    TEST_BEGIN();

    act.sa_handler = NULL;
    act.sa_sigaction = Signal_handler;
    act.sa_flags   = SA_SIGINFO;
    sigaction( SIGNAL_ONE, &act, NULL );
    sigaction( SIGNAL_TWO, &act, NULL );

    printf(
        "Init - _POSIX_signals_Clear_signals when signals pending but\n"
        "Init -    not queued on SA_SIGINFO configured signal.\n"
    );

    /* cheat and put signal directly in */
    _POSIX_signals_Pending |= signo_to_mask( SIGUSR1 );

    bc = _POSIX_signals_Clear_signals(
             _Thread_Get_executing()->API_Extensions[ THREAD_API_POSIX ],
             SIGNAL_ONE,
             &info,
             true,              /* is_global */
             false,             /* check_blocked */
             true               /* do_signals_acquire_release */
         );
    rtems_test_assert( bc );

    TEST_END();
    rtems_test_exit(0);

    return NULL; /* just so the compiler thinks we returned something */
}
int sigtimedwait(
  const sigset_t         *set,
  siginfo_t              *info,
  const struct timespec  *timeout
)
{
  Thread_Control    *the_thread;
  POSIX_API_Control *api;
  Watchdog_Interval  interval;
  siginfo_t          signal_information;
  siginfo_t         *the_info;
  int                signo;
  ISR_Level          level;

  /*
   *  Error check parameters before disabling interrupts.
   */
  if ( !set )
    rtems_set_errno_and_return_minus_one( EINVAL );

  /*  NOTE: This is very specifically a RELATIVE not ABSOLUTE time
   *        in the Open Group specification.
   */

  interval = 0;
  if ( timeout ) {

    if ( !_Timespec_Is_valid( timeout ) )
      rtems_set_errno_and_return_minus_one( EINVAL );

    interval = _Timespec_To_ticks( timeout );

    if ( !interval )
      rtems_set_errno_and_return_minus_one( EINVAL );
  }

  /*
   *  Initialize local variables.
   */

  the_info = ( info ) ? info : &signal_information;

  the_thread = _Thread_Executing;

  api = the_thread->API_Extensions[ THREAD_API_POSIX ];

  /*
   *  What if they are already pending?
   */

  /* API signals pending? */

  _ISR_Disable( level );
  if ( *set & api->signals_pending ) {
    /* XXX real info later */
    the_info->si_signo = _POSIX_signals_Get_highest( api->signals_pending );
    _POSIX_signals_Clear_signals(
      api,
      the_info->si_signo,
      the_info,
      false,
      false
    );
    _ISR_Enable( level );

    the_info->si_code = SI_USER;
    the_info->si_value.sival_int = 0;
    return the_info->si_signo;
  }

  /* Process pending signals? */

  if ( *set & _POSIX_signals_Pending ) {
    signo = _POSIX_signals_Get_highest( _POSIX_signals_Pending );
    _POSIX_signals_Clear_signals( api, signo, the_info, true, false );
    _ISR_Enable( level );

    the_info->si_signo = signo;
    the_info->si_code = SI_USER;
    the_info->si_value.sival_int = 0;
    return signo;
  }

  the_info->si_signo = -1;

  _Thread_Disable_dispatch();
    the_thread->Wait.queue           = &_POSIX_signals_Wait_queue;
    the_thread->Wait.return_code     = EINTR;
    the_thread->Wait.option          = *set;
    the_thread->Wait.return_argument = the_info;
    _Thread_queue_Enter_critical_section( &_POSIX_signals_Wait_queue );
    _ISR_Enable( level );
    _Thread_queue_Enqueue( &_POSIX_signals_Wait_queue, interval );
  _Thread_Enable_dispatch();

  /*
   * When the thread is set free by a signal, it is need to eliminate
   * the signal.
   */

  _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info, false, false );
  errno = _Thread_Executing->Wait.return_code;
  return the_info->si_signo;
}
Exemplo n.º 4
0
bool    _POSIX_signals_Check_signal(
  POSIX_API_Control  *api,
  int                 signo,
  bool                is_global
)
{
  siginfo_t                   siginfo_struct;
  sigset_t                    saved_signals_blocked;
  Thread_Wait_information     stored_thread_wait_information;

  if ( ! _POSIX_signals_Clear_signals( api, signo, &siginfo_struct,
                                       is_global, true ) )
    return false;

  /*
   *  Since we made a union of these, only one test is necessary but this is
   *  safer.
   */
  #if defined(RTEMS_DEBUG)
    assert( _POSIX_signals_Vectors[ signo ].sa_handler ||
            _POSIX_signals_Vectors[ signo ].sa_sigaction );
  #endif

  /*
   *  Just to prevent sending a signal which is currently being ignored.
   */
  if ( _POSIX_signals_Vectors[ signo ].sa_handler == SIG_IGN )
    return false;

  /*
   *  Block the signals requested in sa_mask
   */
  saved_signals_blocked = api->signals_blocked;
  api->signals_blocked |= _POSIX_signals_Vectors[ signo ].sa_mask;

  /*
   *  We have to save the blocking information of the current wait queue
   *  because the signal handler may subsequently go on and put the thread
   *  on a wait queue, for its own purposes.
   */
  memcpy( &stored_thread_wait_information, &_Thread_Executing->Wait,
          sizeof( Thread_Wait_information ));

  /*
   *  Here, the signal handler function executes
   */
  switch ( _POSIX_signals_Vectors[ signo ].sa_flags ) {
    case SA_SIGINFO:
      (*_POSIX_signals_Vectors[ signo ].sa_sigaction)(
        signo,
        &siginfo_struct,
        NULL        /* context is undefined per 1003.1b-1993, p. 66 */
      );
      break;
    default:
      (*_POSIX_signals_Vectors[ signo ].sa_handler)( signo );
      break;
  }

  /*
   *  Restore the blocking information
   */
  memcpy( &_Thread_Executing->Wait, &stored_thread_wait_information,
          sizeof( Thread_Wait_information ));

  /*
   *  Restore the previous set of blocked signals
   */
  api->signals_blocked = saved_signals_blocked;

  return true;
}