Changeset 82f490f in rtems


Ignore:
Timestamp:
Apr 12, 1999, 8:24:56 PM (21 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, master
Children:
6e27f588
Parents:
8cdb582
Message:

Patch from Ralf Corsepius <corsepiu@…> to correct the
--enable-tests problem a better way.

Files:
7 edited

Legend:

Unmodified
Added
Removed
  • aclocal.m4

    r8cdb582 r82f490f  
    877877# If the tests are enabled, then find all the test suite Makefiles
    878878AC_MSG_CHECKING([if the test suites are enabled? ])
    879 tests_enabled=no
    880879AC_ARG_ENABLE(tests,
    881880[  --enable-tests                       enable tests (default:disabled)],
    882881  [case "${enableval}" in
    883     yes) AC_MSG_RESULT(yes) ;;
    884     no)  AC_MSG_RESULT(no) ; tests_enabled=no ;;
     882    yes) tests_enabled=yes ;;
     883    no)  tests_enabled=no ;;
    885884    *)   AC_MSG_ERROR(bad value ${enableval} for tests option) ;;
    886   esac], AC_MSG_RESULT(no))
     885  esac], [tests_enabled=no])
     886AC_MSG_RESULT([$tests_enabled])
    887887])
    888888
  • aclocal/enable-tests.m4

    r8cdb582 r82f490f  
    55# If the tests are enabled, then find all the test suite Makefiles
    66AC_MSG_CHECKING([if the test suites are enabled? ])
    7 tests_enabled=no
    87AC_ARG_ENABLE(tests,
    98[  --enable-tests                       enable tests (default:disabled)],
    109  [case "${enableval}" in
    11     yes) AC_MSG_RESULT(yes) ;;
    12     no)  AC_MSG_RESULT(no) ; tests_enabled=no ;;
     10    yes) tests_enabled=yes ;;
     11    no)  tests_enabled=no ;;
    1312    *)   AC_MSG_ERROR(bad value ${enableval} for tests option) ;;
    14   esac], AC_MSG_RESULT(no))
     13  esac], [tests_enabled=no])
     14AC_MSG_RESULT([$tests_enabled])
    1515])
  • c/src/exec/posix/src/psignal.c

    r8cdb582 r82f490f  
    1818#include <rtems/posix/pthread.h>
    1919#include <rtems/posix/time.h>
     20#include <stdio.h>
     21
     22
     23/*
     24 *  Currently 32 signals numbered 1-32 are defined
     25 */
     26
     27#define SIGNAL_EMPTY_MASK  0x00000000
     28#define SIGNAL_ALL_MASK    0xffffffff
     29
     30#define signo_to_mask( _sig ) (1 << ((_sig) - 1))
     31
     32#define is_valid_signo( _sig ) \
     33  ((_sig) >= 1 && (_sig) <= 32 )
    2034
    2135/*** PROCESS WIDE STUFF ****/
     
    2337sigset_t  _POSIX_signals_Pending;
    2438
    25 struct sigaction _POSIX_signals_Vectors[ SIG_ARRAY_MAX ];
    26 
    27 Watchdog_Control _POSIX_signals_Alarm_timer;
    28 
    29 Thread_queue_Control _POSIX_signals_Wait_queue;
    30 
    31 Chain_Control _POSIX_signals_Inactive_siginfo;
    32 Chain_Control _POSIX_signals_Siginfo[ SIG_ARRAY_MAX ];
    33 
     39void _POSIX_signals_Abormal_termination_handler( int signo )
     40{
     41  exit( 1 );
     42}
     43
     44#define _POSIX_signals_Stop_handler NULL
     45#define _POSIX_signals_Continue_handler NULL
     46
     47#define SIGACTION_TERMINATE \
     48  { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Abormal_termination_handler} }
     49#define SIGACTION_IGNORE \
     50  { 0, SIGNAL_ALL_MASK, {SIG_IGN} }
     51#define SIGACTION_STOP \
     52  { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Stop_handler} }
     53#define SIGACTION_CONTINUE \
     54  { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Continue_handler} }
     55
     56#define SIG_ARRAY_MAX  (SIGRTMAX + 1)
    3457struct sigaction _POSIX_signals_Default_vectors[ SIG_ARRAY_MAX ] = {
    3558  /* NO SIGNAL 0 */  SIGACTION_IGNORE,
     
    5275  /* SIGUSR1  16 */  SIGACTION_TERMINATE,
    5376  /* SIGUSR2  17 */  SIGACTION_TERMINATE,
    54   /* SIGRTMIN 18 */  SIGACTION_TERMINATE,
    55   /* SIGRT    19 */  SIGACTION_TERMINATE,
    56   /* SIGRT    20 */  SIGACTION_TERMINATE,
    57   /* SIGRT    21 */  SIGACTION_TERMINATE,
    58   /* SIGRT    22 */  SIGACTION_TERMINATE,
    59   /* SIGRT    23 */  SIGACTION_TERMINATE,
    60   /* SIGRT    24 */  SIGACTION_TERMINATE,
    61   /* SIGRT    25 */  SIGACTION_TERMINATE,
    62   /* SIGRT    26 */  SIGACTION_TERMINATE,
    63   /* SIGRT    27 */  SIGACTION_TERMINATE,
    64   /* SIGRT    28 */  SIGACTION_TERMINATE,
    65   /* SIGRT    29 */  SIGACTION_TERMINATE,
    66   /* SIGRT    30 */  SIGACTION_TERMINATE,
    67   /* SIGRT    31 */  SIGACTION_TERMINATE,
    68   /* SIGRTMAX 32 */  SIGACTION_TERMINATE
     77  /* SIGRTMIN 18 */  SIGACTION_IGNORE,
     78  /* SIGRT    19 */  SIGACTION_IGNORE,
     79  /* SIGRT    20 */  SIGACTION_IGNORE,
     80  /* SIGRT    21 */  SIGACTION_IGNORE,
     81  /* SIGRT    22 */  SIGACTION_IGNORE,
     82  /* SIGRT    23 */  SIGACTION_IGNORE,
     83  /* SIGRT    24 */  SIGACTION_IGNORE,
     84  /* SIGRT    25 */  SIGACTION_IGNORE,
     85  /* SIGRT    26 */  SIGACTION_IGNORE,
     86  /* SIGRT    27 */  SIGACTION_IGNORE,
     87  /* SIGRT    28 */  SIGACTION_IGNORE,
     88  /* SIGRT    29 */  SIGACTION_IGNORE,
     89  /* SIGRT    30 */  SIGACTION_IGNORE,
     90  /* SIGRT    31 */  SIGACTION_IGNORE,
     91  /* SIGRTMAX 32 */  SIGACTION_IGNORE
    6992};
    7093
     94struct sigaction _POSIX_signals_Vectors[ SIG_ARRAY_MAX ];
     95
     96Watchdog_Control _POSIX_signals_Alarm_timer;
     97
     98Thread_queue_Control _POSIX_signals_Wait_queue;
     99
     100Chain_Control _POSIX_signals_Inactive_siginfo;
     101Chain_Control _POSIX_signals_Siginfo[ SIG_ARRAY_MAX ];
     102
    71103/*PAGE
    72104 *
    73  *  _POSIX_signals_Abnormal_termination_handler
    74  *
    75  */
    76 
    77 void _POSIX_signals_Abnormal_termination_handler( int signo )
    78 {
    79   exit( 1 );
    80 }
     105 *  XXX - move these
     106 */
     107
     108#define _States_Is_interruptible_signal( _states ) \
     109  ( ((_states) & \
     110    (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL)) == \
     111      (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL))
    81112
    82113/*PAGE
     
    179210  _ISR_Disable( level );
    180211    _POSIX_signals_Pending &= ~mask;
    181     if ( !_POSIX_signals_Pending && _Thread_Do_post_task_switch_extension )
     212    if ( !_POSIX_signals_Pending )
    182213      _Thread_Do_post_task_switch_extension--;
    183214  _ISR_Enable( level );
     
    290321  api->signals_blocked |= _POSIX_signals_Vectors[ signo ].sa_mask;
    291322
     323  /* Here, the signal handler function executes */
     324
    292325  switch ( _POSIX_signals_Vectors[ signo ].sa_flags ) {
    293326    case SA_SIGINFO:
    294       /* assert( is_global ); -- not right after timers added */
    295 
     327/*
     328 *
     329 *     assert( is_global );
     330 */
    296331      (*_POSIX_signals_Vectors[ signo ].sa_sigaction)(
    297332        signo,
     
    456491  );
    457492}
     493
     494/*
     495 *  3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
     496 */
     497
     498int sigemptyset(
     499  sigset_t   *set
     500)
     501{
     502  if ( !set )
     503    set_errno_and_return_minus_one( EINVAL );
     504
     505  *set = 0;
     506  return 0;
     507}
     508
     509/*
     510 *  3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
     511 */
     512
     513int sigfillset(
     514  sigset_t   *set
     515)
     516{
     517  if ( !set )
     518    set_errno_and_return_minus_one( EINVAL );
     519
     520  *set = SIGNAL_ALL_MASK;
     521  return 0;
     522}
     523
     524/*
     525 *  3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
     526 */
     527
     528int sigaddset(
     529  sigset_t   *set,
     530  int         signo
     531)
     532{
     533  if ( !set )
     534    set_errno_and_return_minus_one( EINVAL );
     535
     536  if ( !signo )
     537    return 0;
     538
     539  if ( !is_valid_signo(signo) )
     540    set_errno_and_return_minus_one( EINVAL );
     541
     542  *set |= signo_to_mask(signo);
     543  return 0;
     544}
     545
     546/*
     547 *  3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
     548 */
     549
     550int sigdelset(
     551  sigset_t   *set,
     552  int         signo
     553)
     554{
     555  if ( !set )
     556    set_errno_and_return_minus_one( EINVAL );
     557 
     558  if ( !signo )
     559    return 0;
     560
     561  if ( !is_valid_signo(signo) )
     562    set_errno_and_return_minus_one( EINVAL );
     563 
     564  *set &= ~signo_to_mask(signo);
     565  return 0;
     566}
     567
     568/*
     569 *  3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
     570 */
     571
     572int sigismember(
     573  const sigset_t   *set,
     574  int               signo
     575)
     576{
     577  if ( !set )
     578    set_errno_and_return_minus_one( EINVAL );
     579 
     580  if ( !signo )
     581    return 0;
     582
     583  if ( !is_valid_signo(signo) )
     584    set_errno_and_return_minus_one( EINVAL );
     585 
     586  if ( *set & signo_to_mask(signo) )
     587    return 1;
     588
     589  return 0;
     590}
     591
     592/*
     593 *  3.3.4 Examine and Change Signal Action, P1003.1b-1993, p. 70
     594 */
     595
     596/* ***************************************************************************
     597 * The signal handler is notified to the timers manager when the
     598 * timer is set. So, the timers manager knows the signal handler.
     599 * ***************************************************************************/
     600
     601int sigaction(
     602  int                     sig,
     603  const struct sigaction *act,
     604  struct sigaction       *oact
     605)
     606{
     607  ISR_Level     level;
     608
     609 
     610  if ( oact )
     611    *oact = _POSIX_signals_Vectors[ sig ];
     612
     613  if ( !sig )
     614    return 0;
     615
     616  if ( !is_valid_signo(sig) )
     617    set_errno_and_return_minus_one( EINVAL );
     618 
     619  /*
     620   *  Some signals cannot be ignored (P1003.1b-1993, pp. 70-72 and references.
     621   *
     622   *  NOTE: Solaris documentation claims to "silently enforce" this which
     623   *        contradicts the POSIX specification.
     624   */
     625
     626  if ( sig == SIGKILL )
     627    set_errno_and_return_minus_one( EINVAL );
     628 
     629  /*
     630   *  Evaluate the new action structure and set the global signal vector
     631   *  appropriately.
     632   */
     633
     634  if ( act ) {
     635
     636    /*
     637     *  Unless the user is installing the default signal actions, then
     638     *  we can just copy the provided sigaction structure into the vectors.
     639     */
     640
     641    _ISR_Disable( level );
     642      if ( act->sa_handler == SIG_DFL ) {
     643        _POSIX_signals_Vectors[ sig ] = _POSIX_signals_Default_vectors[ sig ];
     644      } else {
     645         _POSIX_signals_Clear_process_signals( signo_to_mask(sig) );
     646         _POSIX_signals_Vectors[ sig ] = *act;
     647      }
     648    _ISR_Enable( level );
     649  }
     650
     651  /*
     652   *  No need to evaluate or dispatch because:
     653   *
     654   *    + If we were ignoring the signal before, none could be pending
     655   *      now (signals not posted when SIG_IGN).
     656   *    + If we are now ignoring a signal that was previously pending,
     657   *      we clear the pending signal indicator.
     658   */
     659
     660  return 0;
     661}
     662
     663/*
     664 *  3.3.5 Examine and Change Blocked Signals, P1003.1b-1993, p. 73
     665 *
     666 *  NOTE: P1003.1c/D10, p. 37 adds pthread_sigmask().
     667 *
     668 */
     669
     670int sigprocmask(
     671  int               how,
     672  const sigset_t   *set,
     673  sigset_t         *oset
     674)
     675{
     676  /*
     677   *  P1003.1c/Draft 10, p. 38 maps sigprocmask to pthread_sigmask.
     678   */
     679
     680  return pthread_sigmask( how, set, oset );
     681}
     682
     683/*
     684 *  3.3.5 Examine and Change Blocked Signals, P1003.1b-1993, p. 73
     685 *
     686 *  NOTE: P1003.1c/D10, p. 37 adds pthread_sigmask().
     687 */
     688
     689int pthread_sigmask(
     690  int               how,
     691  const sigset_t   *set,
     692  sigset_t         *oset
     693)
     694{
     695  POSIX_API_Control  *api;
     696
     697  if ( !set && !oset )
     698    set_errno_and_return_minus_one( EINVAL );
     699
     700  api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
     701
     702  if ( oset )
     703    *oset = api->signals_blocked;
     704 
     705  if ( !set )
     706    return 0;
     707
     708  switch ( how ) {
     709    case SIG_BLOCK:
     710      api->signals_blocked |= *set;
     711      break;
     712    case SIG_UNBLOCK:
     713      api->signals_blocked &= ~*set;
     714      break;
     715    case SIG_SETMASK:
     716      api->signals_blocked = *set;
     717      break;
     718    default:
     719      set_errno_and_return_minus_one( EINVAL );
     720  }
     721
     722  /* XXX are there critical section problems here? */
     723
     724  /* XXX evaluate the new set */
     725
     726  if ( ~api->signals_blocked &
     727       (api->signals_pending | _POSIX_signals_Pending) ) {
     728    _Thread_Executing->do_post_task_switch_extension = TRUE;
     729    _Thread_Dispatch();
     730  }
     731
     732  return 0;
     733}
     734
     735/*
     736 *  3.3.6 Examine Pending Signals, P1003.1b-1993, p. 75
     737 */
     738
     739int sigpending(
     740  sigset_t  *set
     741)
     742{
     743  POSIX_API_Control  *api;
     744 
     745  if ( !set )
     746    set_errno_and_return_minus_one( EINVAL );
     747 
     748  api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
     749 
     750  *set = api->signals_pending | _POSIX_signals_Pending;
     751 
     752  return 0;
     753}
     754
     755/*
     756 *  3.3.7 Wait for a Signal, P1003.1b-1993, p. 75
     757 */
     758
     759int sigsuspend(
     760  const sigset_t  *sigmask
     761)
     762{
     763  sigset_t            saved_signals_blocked;
     764  sigset_t            all_signals;
     765  int                 status;
     766  POSIX_API_Control  *api;
     767
     768  api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
     769
     770  status = sigprocmask( SIG_BLOCK, sigmask, &saved_signals_blocked );
     771 
     772  (void) sigfillset( &all_signals );
     773
     774  status = sigtimedwait( &all_signals, NULL, NULL );
     775
     776  (void) sigprocmask( SIG_SETMASK, &saved_signals_blocked, NULL );
     777
     778  return status;
     779}
     780
     781/*
     782 *  3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76
     783 *
     784 *  NOTE: P1003.1c/D10, p. 39 adds sigwait().
     785 */
     786
     787int sigwaitinfo(
     788  const sigset_t  *set,
     789  siginfo_t       *info
     790)
     791{
     792  return sigtimedwait( set, info, NULL );
     793}
     794
     795/*
     796 *  3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76
     797 *
     798 *  NOTE: P1003.1c/D10, p. 39 adds sigwait().
     799 */
     800
     801int _POSIX_signals_Get_highest(
     802  sigset_t   set
     803)
     804{
     805  int signo;
     806 
     807  for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) {
     808    if ( set & signo_to_mask( signo ) )
     809      return signo;
     810  }
     811 
     812/* XXX - add __SIGFIRSTNOTRT or something like that to newlib siginfo.h */
     813
     814  for ( signo = SIGHUP ; signo <= __SIGLASTNOTRT ; signo++ ) {
     815    if ( set & signo_to_mask( signo ) )
     816      return signo;
     817  }
     818
     819  return 0;
     820}
     821
     822int sigtimedwait(
     823  const sigset_t         *set,
     824  siginfo_t              *info,
     825  const struct timespec  *timeout
     826)
     827{
     828  Thread_Control    *the_thread;
     829  POSIX_API_Control *api;
     830  Watchdog_Interval  interval;
     831  siginfo_t          signal_information;
     832  siginfo_t         *the_info;
     833  int                signo;
     834 
     835  the_info = ( info ) ? info : &signal_information;
     836
     837  the_thread = _Thread_Executing;
     838
     839  api = the_thread->API_Extensions[ THREAD_API_POSIX ];
     840
     841  /*
     842   *  What if they are already pending?
     843   */
     844
     845  /* API signals pending? */
     846
     847  if ( *set & api->signals_pending ) {
     848    /* XXX real info later */
     849    the_info->si_signo = _POSIX_signals_Get_highest( api->signals_pending );
     850    _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info,
     851                                  FALSE, FALSE );
     852    the_info->si_code = SI_USER;
     853    the_info->si_value.sival_int = 0;
     854    return the_info->si_signo;
     855  }
     856
     857  /* Process pending signals? */
     858
     859  if ( *set & _POSIX_signals_Pending) {
     860    signo = _POSIX_signals_Get_highest( _POSIX_signals_Pending );
     861    _POSIX_signals_Clear_signals( api, signo, the_info, TRUE, FALSE );
     862
     863    if ( !info ) {
     864      the_info->si_signo = signo;
     865      the_info->si_code = SI_USER;
     866      the_info->si_value.sival_int = 0;
     867    }
     868  }
     869
     870  interval = 0;
     871  if ( timeout ) {
     872
     873    if (timeout->tv_nsec < 0 || timeout->tv_nsec >= TOD_NANOSECONDS_PER_SECOND)
     874      set_errno_and_return_minus_one( EINVAL );
     875
     876    interval = _POSIX_Timespec_to_interval( timeout );
     877  }
     878
     879  the_info->si_signo = -1;
     880
     881  _Thread_Disable_dispatch();
     882    the_thread->Wait.queue           = &_POSIX_signals_Wait_queue;
     883    the_thread->Wait.return_code     = EINTR;
     884    the_thread->Wait.option          = *set;
     885    the_thread->Wait.return_argument = (void *) the_info;
     886    _Thread_queue_Enter_critical_section( &_POSIX_signals_Wait_queue );
     887    _Thread_queue_Enqueue( &_POSIX_signals_Wait_queue, interval );
     888  _Thread_Enable_dispatch();
     889
     890  /*
     891   * When the thread set free by a signal, it is needed to eliminate
     892   * that signal
     893   */
     894
     895  _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info,
     896                                FALSE, FALSE );
     897
     898  errno = _Thread_Executing->Wait.return_code;
     899  return the_info->si_signo;
     900}
     901
     902/*
     903 *  3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76
     904 *
     905 *  NOTE: P1003.1c/D10, p. 39 adds sigwait().
     906 */
     907
     908int sigwait(
     909  const sigset_t  *set,
     910  int             *sig
     911)
     912{
     913  int status;
     914
     915  status = sigtimedwait( set, NULL, NULL );
     916
     917  if ( status != -1 ) {
     918    if ( sig )
     919      *sig = status;
     920    return 0;
     921  }
     922
     923  return errno;
     924}
     925
     926/*PAGE
     927 *
     928 *  3.3.2 Send a Signal to a Process, P1003.1b-1993, p. 68
     929 *
     930 *  NOTE: Behavior of kill() depends on _POSIX_SAVED_IDS.
     931 */
     932
     933#define _POSIX_signals_Is_interested( _api, _mask ) \
     934  ( ~(_api)->signals_blocked & (_mask) )
     935         
     936int killinfo(
     937  pid_t               pid,
     938  int                 sig,
     939  const union sigval *value
     940)
     941{
     942  sigset_t                     mask;
     943  POSIX_API_Control           *api;
     944  unsigned32                   the_class;
     945  unsigned32                   index;
     946  unsigned32                   maximum;
     947  Objects_Information         *the_info;
     948  Objects_Control            **object_table;
     949  Thread_Control              *the_thread;
     950  Thread_Control              *interested_thread;
     951  Priority_Control             interested_priority;
     952  Chain_Control               *the_chain;
     953  Chain_Node                  *the_node;
     954  siginfo_t                    siginfo_struct;
     955  siginfo_t                   *siginfo;
     956  POSIX_signals_Siginfo_node  *psiginfo;
     957 
     958
     959
     960  /*
     961   *  Only supported for the "calling process" (i.e. this node).
     962   */
     963 
     964  if( pid != getpid() )
     965    set_errno_and_return_minus_one( ESRCH );
     966
     967  /*
     968   *  Validate the signal passed if not 0.
     969   */
     970 
     971  if ( sig && !is_valid_signo(sig) )
     972  {
     973    set_errno_and_return_minus_one( EINVAL );
     974  }
     975
     976  /*
     977   *  If the signal is being ignored, then we are out of here.
     978   */
     979
     980  if ( !sig || _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN )
     981  {
     982    return 0;
     983  }
     984
     985  /*
     986   *  P1003.1c/Draft 10, p. 33 says that certain signals should always
     987   *  be directed to the executing thread such as those caused by hardware
     988   *  faults.
     989   */
     990
     991  switch ( sig ) {
     992    case SIGFPE:
     993    case SIGILL:
     994    case SIGSEGV:
     995      return pthread_kill( pthread_self(), sig );
     996    default:
     997      break;
     998  }
     999
     1000  mask = signo_to_mask( sig );
     1001
     1002  /*
     1003   *  Build up a siginfo structure
     1004   */
     1005
     1006  siginfo = &siginfo_struct;
     1007  siginfo->si_signo = sig;
     1008  siginfo->si_code = SI_USER;
     1009  if ( !value ) {
     1010    siginfo->si_value.sival_int = 0;
     1011  } else {
     1012    siginfo->si_value = *value;
     1013  }
     1014
     1015  _Thread_Disable_dispatch();
     1016
     1017  /*
     1018   *  Is the currently executing thread interested?  If so then it will
     1019   *  get it an execute it as soon as the dispatcher executes.
     1020   */
     1021
     1022  the_thread = _Thread_Executing;
     1023
     1024  api = the_thread->API_Extensions[ THREAD_API_POSIX ];
     1025  if ( _POSIX_signals_Is_interested( api, mask ) ) {
     1026    goto process_it;
     1027  }
     1028
     1029  /*
     1030   *  Is an interested thread waiting for this signal (sigwait())?
     1031   */
     1032
     1033  /* XXX violation of visibility -- need to define thread queue support */
     1034
     1035  for( index=0 ;
     1036       index < TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS ;
     1037       index++ ) {
     1038
     1039    the_chain = &_POSIX_signals_Wait_queue.Queues.Priority[ index ];
     1040 
     1041    for ( the_node = the_chain->first ;
     1042          !_Chain_Is_tail( the_chain, the_node ) ;
     1043          the_node = the_node->next ) {
     1044
     1045      the_thread = (Thread_Control *)the_node;
     1046      api = the_thread->API_Extensions[ THREAD_API_POSIX ];
     1047
     1048      if ((the_thread->Wait.option & mask) || (~api->signals_blocked & mask)) {
     1049        goto process_it;
     1050      }
     1051
     1052    }
     1053  }
     1054
     1055  /*
     1056   *  Is any other thread interested?  The highest priority interested
     1057   *  thread is selected.  In the event of a tie, then the following
     1058   *  additional criteria is used:
     1059   *
     1060   *    + ready thread over blocked
     1061   *    + blocked on call interruptible by signal (can return EINTR)
     1062   *    + blocked on call not interruptible by signal
     1063   *
     1064   *  This looks at every thread in the system regardless of the creating API.
     1065   *
     1066   *  NOTES:
     1067   *
     1068   *    + rtems internal threads do not receive signals.
     1069   */
     1070
     1071  interested_thread = NULL;
     1072  interested_priority = PRIORITY_MAXIMUM + 1;
     1073
     1074  for ( the_class = OBJECTS_CLASSES_FIRST_THREAD_CLASS;
     1075        the_class <= OBJECTS_CLASSES_LAST_THREAD_CLASS;
     1076        the_class++ ) {
     1077
     1078    if ( the_class == OBJECTS_INTERNAL_THREADS )
     1079      continue;
     1080
     1081    the_info = _Objects_Information_table[ the_class ];
     1082
     1083    if ( !the_info )                        /* manager not installed */
     1084      continue;
     1085
     1086    maximum = the_info->maximum;
     1087    object_table = the_info->local_table;
     1088
     1089    assert( object_table );                 /* always at least 1 entry */
     1090
     1091    for ( index = 1 ; index <= maximum ; index++ ) {
     1092      the_thread = (Thread_Control *) object_table[ index ];
     1093
     1094      if ( !the_thread )
     1095        continue;
     1096
     1097      /*
     1098       *  If this thread is of lower priority than the interested thread,
     1099       *  go on to the next thread.
     1100       */
     1101
     1102      if ( the_thread->current_priority > interested_priority )
     1103        continue;
     1104
     1105      /*
     1106       *  If this thread is not interested, then go on to the next thread.
     1107       */
     1108
     1109      api = the_thread->API_Extensions[ THREAD_API_POSIX ];
     1110
     1111      if ( !api || !_POSIX_signals_Is_interested( api, mask ) )
     1112        continue;
     1113
     1114      /*
     1115       *  Now we know the thread under connsideration is interested.
     1116       *  If the thread under consideration is of higher priority, then
     1117       *  it becomes the interested thread.
     1118       */
     1119
     1120      if ( the_thread->current_priority < interested_priority ) {
     1121        interested_thread   = the_thread;
     1122        interested_priority = the_thread->current_priority;
     1123        continue;
     1124      }
     1125
     1126      /*
     1127       *  Now the thread and the interested thread have the same priority.
     1128       *  If the interested thread is ready, then we don't need to send it
     1129       *  to a blocked thread.
     1130       */
     1131
     1132      if ( _States_Is_ready( interested_thread->current_state ) )
     1133        continue;
     1134
     1135      /*
     1136       *  Now the interested thread is blocked.
     1137       *  If the thread we are considering is not, the it becomes the
     1138       *  interested thread.
     1139       */
     1140
     1141      if ( _States_Is_ready( the_thread->current_state ) ) {
     1142        interested_thread   = the_thread;
     1143        interested_priority = the_thread->current_priority;
     1144        continue;
     1145      }
     1146
     1147      /*
     1148       *  Now we know both threads are blocked.
     1149       *  If the interested thread is interruptible, then just use it.
     1150       */
     1151
     1152      /* XXX need a new states macro */
     1153      if ( interested_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL )
     1154        continue;
     1155
     1156      /*
     1157       *  Now both threads are blocked and the interested thread is not
     1158       *  interruptible.
     1159       *  If the thread under consideration is interruptible by a signal,
     1160       *  then it becomes the interested thread.
     1161       */
     1162
     1163      /* XXX need a new states macro */
     1164      if ( the_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL ) {
     1165        interested_thread   = the_thread;
     1166        interested_priority = the_thread->current_priority;
     1167      }
     1168    }
     1169  }
     1170
     1171  if ( interested_thread ) {
     1172    the_thread = interested_thread;
     1173    goto process_it;
     1174  }
     1175
     1176  /*
     1177   *  OK so no threads were interested right now.  It will be left on the
     1178   *  global pending until a thread receives it.  The global set of threads
     1179   *  can change interest in this signal in one of the following ways:
     1180   *
     1181   *    + a thread is created with the signal unblocked,
     1182   *    + pthread_sigmask() unblocks the signal,
     1183   *    + sigprocmask() unblocks the signal, OR
     1184   *    + sigaction() which changes the handler to SIG_IGN.
     1185   */
     1186
     1187  the_thread = NULL;
     1188  goto post_process_signal;
     1189
     1190  /*
     1191   *  We found a thread which was interested, so now we mark that this
     1192   *  thread needs to do the post context switch extension so it can
     1193   *  evaluate the signals pending.
     1194   */
     1195
     1196process_it:
     1197 
     1198  the_thread->do_post_task_switch_extension = TRUE;
     1199
     1200  /*
     1201   *  Returns TRUE if the signal was synchronously given to a thread
     1202   *  blocked waiting for the signal.
     1203   */
     1204
     1205  if ( _POSIX_signals_Unblock_thread( the_thread, sig, siginfo ) ) {
     1206    _Thread_Enable_dispatch();
     1207    return 0;
     1208  }
     1209
     1210post_process_signal:
     1211
     1212  /*
     1213   *  We may have woken up a thread but we definitely need to post the
     1214   *  signal to the process wide information set.
     1215   */
     1216
     1217  _POSIX_signals_Set_process_signals( mask );
     1218
     1219  if ( _POSIX_signals_Vectors[ sig ].sa_flags == SA_SIGINFO ) {
     1220
     1221    psiginfo = (POSIX_signals_Siginfo_node *)
     1222               _Chain_Get( &_POSIX_signals_Inactive_siginfo );
     1223    if ( !psiginfo )
     1224    {
     1225      set_errno_and_return_minus_one( EAGAIN );
     1226    }
     1227
     1228    psiginfo->Info = *siginfo;
     1229
     1230    _Chain_Append( &_POSIX_signals_Siginfo[ sig ], &psiginfo->Node );
     1231  }
     1232
     1233  _Thread_Enable_dispatch();
     1234  return 0;
     1235}
     1236
     1237/*
     1238 *  3.3.9 Queue a Signal to a Process, P1003.1b-1993, p. 78
     1239 */
     1240
     1241int sigqueue(
     1242  pid_t               pid,
     1243  int                 signo,
     1244  const union sigval  value
     1245)
     1246{
     1247  return killinfo( pid, signo, &value );
     1248}
     1249
     1250/*
     1251 *  3.3.10 Send a Signal to a Thread, P1003.1c/D10, p. 43
     1252 */
     1253
     1254int pthread_kill(
     1255  pthread_t   thread,
     1256  int         sig
     1257)
     1258{
     1259  POSIX_API_Control  *api;
     1260  Thread_Control     *the_thread;
     1261  Objects_Locations  location;
     1262
     1263  if ( sig && !is_valid_signo(sig) )
     1264    set_errno_and_return_minus_one( EINVAL );
     1265/*
     1266  if ( _POSIX_signals_Vectors[ sig ].sa_flags == SA_SIGINFO )
     1267    set_errno_and_return_minus_one( ENOSYS );
     1268*/
     1269  /*
     1270   *  RTEMS does not support sending  a siginfo signal to a specific thread.
     1271   */
     1272
     1273  the_thread = _POSIX_Threads_Get( thread, &location );
     1274  switch ( location ) {
     1275    case OBJECTS_ERROR:
     1276    case OBJECTS_REMOTE:
     1277      set_errno_and_return_minus_one( ESRCH );
     1278    case OBJECTS_LOCAL:
     1279      /*
     1280       *  If sig == 0 then just validate arguments
     1281       */
     1282
     1283      api = the_thread->API_Extensions[ THREAD_API_POSIX ];
     1284
     1285      if ( sig ) {
     1286
     1287        if ( _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN ) {
     1288          _Thread_Enable_dispatch();
     1289          return 0;
     1290        }
     1291
     1292        /* XXX critical section */
     1293
     1294        api->signals_pending |= signo_to_mask( sig );
     1295
     1296        (void) _POSIX_signals_Unblock_thread( the_thread, sig, NULL );
     1297
     1298        the_thread->do_post_task_switch_extension = TRUE;
     1299
     1300        if ( _ISR_Is_in_progress() && _Thread_Is_executing( the_thread ) )
     1301          _ISR_Signals_to_thread_executing = TRUE;
     1302      }
     1303      _Thread_Enable_dispatch();
     1304      return 0;
     1305  }
     1306
     1307  return POSIX_BOTTOM_REACHED();
     1308}
     1309
     1310/*
     1311 *  3.4.1 Schedule Alarm, P1003.1b-1993, p. 79
     1312 */
     1313
     1314Watchdog_Control _POSIX_signals_Alarm_timer;
     1315
     1316unsigned int alarm(
     1317  unsigned int seconds
     1318)
     1319{
     1320  unsigned int      remaining = 0;
     1321  Watchdog_Control *the_timer;
     1322
     1323  the_timer = &_POSIX_signals_Alarm_timer;
     1324
     1325  switch ( _Watchdog_Remove( the_timer ) ) {
     1326    case WATCHDOG_INACTIVE:
     1327    case WATCHDOG_BEING_INSERTED:
     1328      break;
     1329 
     1330    case WATCHDOG_ACTIVE:
     1331    case WATCHDOG_REMOVE_IT:
     1332      remaining = the_timer->initial -
     1333                  (the_timer->stop_time - the_timer->start_time);
     1334      break;
     1335  }
     1336
     1337  _Watchdog_Insert_seconds( the_timer, seconds );
     1338
     1339  return remaining;
     1340}
     1341
     1342/*
     1343 *  3.4.2 Suspend Process Execution, P1003.1b-1993, p. 81
     1344 */
     1345
     1346int pause( void )
     1347{
     1348  sigset_t  all_signals;
     1349  int       status;
     1350 
     1351  (void) sigfillset( &all_signals );
     1352 
     1353  status = sigtimedwait( &all_signals, NULL, NULL );
     1354 
     1355  return status;
     1356}
  • c/src/exec/posix/src/ptimer.c

    r8cdb582 r82f490f  
    190190    */
    191191
     192   timer_max = max_timers;
     193
    192194   for (index=0; index<max_timers; index++)
    193195     TIMER_INITIALIZE_S( index );
  • configure

    r8cdb582 r82f490f  
    36653665echo $ac_n "checking if the test suites are enabled? ""... $ac_c" 1>&6
    36663666echo "configure:3667: checking if the test suites are enabled? " >&5
    3667 tests_enabled=no
    36683667# Check whether --enable-tests or --disable-tests was given.
    36693668if test "${enable_tests+set}" = set; then
    36703669  enableval="$enable_tests"
    36713670  case "${enableval}" in
    3672     yes) echo "$ac_t""yes" 1>&6 ;;
    3673     no)  echo "$ac_t""no" 1>&6 ; tests_enabled=no ;;
     3671    yes) tests_enabled=yes ;;
     3672    no)  tests_enabled=no ;;
    36743673    *)   { echo "configure: error: bad value ${enableval} for tests option" 1>&2; exit 1; } ;;
    36753674  esac
    36763675else
    3677   echo "$ac_t""no" 1>&6
    3678 fi
    3679 
     3676  tests_enabled=no
     3677fi
     3678
     3679echo "$ac_t""$tests_enabled" 1>&6
    36803680
    36813681
  • cpukit/posix/src/psignal.c

    r8cdb582 r82f490f  
    1818#include <rtems/posix/pthread.h>
    1919#include <rtems/posix/time.h>
     20#include <stdio.h>
     21
     22
     23/*
     24 *  Currently 32 signals numbered 1-32 are defined
     25 */
     26
     27#define SIGNAL_EMPTY_MASK  0x00000000
     28#define SIGNAL_ALL_MASK    0xffffffff
     29
     30#define signo_to_mask( _sig ) (1 << ((_sig) - 1))
     31
     32#define is_valid_signo( _sig ) \
     33  ((_sig) >= 1 && (_sig) <= 32 )
    2034
    2135/*** PROCESS WIDE STUFF ****/
     
    2337sigset_t  _POSIX_signals_Pending;
    2438
    25 struct sigaction _POSIX_signals_Vectors[ SIG_ARRAY_MAX ];
    26 
    27 Watchdog_Control _POSIX_signals_Alarm_timer;
    28 
    29 Thread_queue_Control _POSIX_signals_Wait_queue;
    30 
    31 Chain_Control _POSIX_signals_Inactive_siginfo;
    32 Chain_Control _POSIX_signals_Siginfo[ SIG_ARRAY_MAX ];
    33 
     39void _POSIX_signals_Abormal_termination_handler( int signo )
     40{
     41  exit( 1 );
     42}
     43
     44#define _POSIX_signals_Stop_handler NULL
     45#define _POSIX_signals_Continue_handler NULL
     46
     47#define SIGACTION_TERMINATE \
     48  { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Abormal_termination_handler} }
     49#define SIGACTION_IGNORE \
     50  { 0, SIGNAL_ALL_MASK, {SIG_IGN} }
     51#define SIGACTION_STOP \
     52  { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Stop_handler} }
     53#define SIGACTION_CONTINUE \
     54  { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Continue_handler} }
     55
     56#define SIG_ARRAY_MAX  (SIGRTMAX + 1)
    3457struct sigaction _POSIX_signals_Default_vectors[ SIG_ARRAY_MAX ] = {
    3558  /* NO SIGNAL 0 */  SIGACTION_IGNORE,
     
    5275  /* SIGUSR1  16 */  SIGACTION_TERMINATE,
    5376  /* SIGUSR2  17 */  SIGACTION_TERMINATE,
    54   /* SIGRTMIN 18 */  SIGACTION_TERMINATE,
    55   /* SIGRT    19 */  SIGACTION_TERMINATE,
    56   /* SIGRT    20 */  SIGACTION_TERMINATE,
    57   /* SIGRT    21 */  SIGACTION_TERMINATE,
    58   /* SIGRT    22 */  SIGACTION_TERMINATE,
    59   /* SIGRT    23 */  SIGACTION_TERMINATE,
    60   /* SIGRT    24 */  SIGACTION_TERMINATE,
    61   /* SIGRT    25 */  SIGACTION_TERMINATE,
    62   /* SIGRT    26 */  SIGACTION_TERMINATE,
    63   /* SIGRT    27 */  SIGACTION_TERMINATE,
    64   /* SIGRT    28 */  SIGACTION_TERMINATE,
    65   /* SIGRT    29 */  SIGACTION_TERMINATE,
    66   /* SIGRT    30 */  SIGACTION_TERMINATE,
    67   /* SIGRT    31 */  SIGACTION_TERMINATE,
    68   /* SIGRTMAX 32 */  SIGACTION_TERMINATE
     77  /* SIGRTMIN 18 */  SIGACTION_IGNORE,
     78  /* SIGRT    19 */  SIGACTION_IGNORE,
     79  /* SIGRT    20 */  SIGACTION_IGNORE,
     80  /* SIGRT    21 */  SIGACTION_IGNORE,
     81  /* SIGRT    22 */  SIGACTION_IGNORE,
     82  /* SIGRT    23 */  SIGACTION_IGNORE,
     83  /* SIGRT    24 */  SIGACTION_IGNORE,
     84  /* SIGRT    25 */  SIGACTION_IGNORE,
     85  /* SIGRT    26 */  SIGACTION_IGNORE,
     86  /* SIGRT    27 */  SIGACTION_IGNORE,
     87  /* SIGRT    28 */  SIGACTION_IGNORE,
     88  /* SIGRT    29 */  SIGACTION_IGNORE,
     89  /* SIGRT    30 */  SIGACTION_IGNORE,
     90  /* SIGRT    31 */  SIGACTION_IGNORE,
     91  /* SIGRTMAX 32 */  SIGACTION_IGNORE
    6992};
    7093
     94struct sigaction _POSIX_signals_Vectors[ SIG_ARRAY_MAX ];
     95
     96Watchdog_Control _POSIX_signals_Alarm_timer;
     97
     98Thread_queue_Control _POSIX_signals_Wait_queue;
     99
     100Chain_Control _POSIX_signals_Inactive_siginfo;
     101Chain_Control _POSIX_signals_Siginfo[ SIG_ARRAY_MAX ];
     102
    71103/*PAGE
    72104 *
    73  *  _POSIX_signals_Abnormal_termination_handler
    74  *
    75  */
    76 
    77 void _POSIX_signals_Abnormal_termination_handler( int signo )
    78 {
    79   exit( 1 );
    80 }
     105 *  XXX - move these
     106 */
     107
     108#define _States_Is_interruptible_signal( _states ) \
     109  ( ((_states) & \
     110    (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL)) == \
     111      (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL))
    81112
    82113/*PAGE
     
    179210  _ISR_Disable( level );
    180211    _POSIX_signals_Pending &= ~mask;
    181     if ( !_POSIX_signals_Pending && _Thread_Do_post_task_switch_extension )
     212    if ( !_POSIX_signals_Pending )
    182213      _Thread_Do_post_task_switch_extension--;
    183214  _ISR_Enable( level );
     
    290321  api->signals_blocked |= _POSIX_signals_Vectors[ signo ].sa_mask;
    291322
     323  /* Here, the signal handler function executes */
     324
    292325  switch ( _POSIX_signals_Vectors[ signo ].sa_flags ) {
    293326    case SA_SIGINFO:
    294       /* assert( is_global ); -- not right after timers added */
    295 
     327/*
     328 *
     329 *     assert( is_global );
     330 */
    296331      (*_POSIX_signals_Vectors[ signo ].sa_sigaction)(
    297332        signo,
     
    456491  );
    457492}
     493
     494/*
     495 *  3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
     496 */
     497
     498int sigemptyset(
     499  sigset_t   *set
     500)
     501{
     502  if ( !set )
     503    set_errno_and_return_minus_one( EINVAL );
     504
     505  *set = 0;
     506  return 0;
     507}
     508
     509/*
     510 *  3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
     511 */
     512
     513int sigfillset(
     514  sigset_t   *set
     515)
     516{
     517  if ( !set )
     518    set_errno_and_return_minus_one( EINVAL );
     519
     520  *set = SIGNAL_ALL_MASK;
     521  return 0;
     522}
     523
     524/*
     525 *  3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
     526 */
     527
     528int sigaddset(
     529  sigset_t   *set,
     530  int         signo
     531)
     532{
     533  if ( !set )
     534    set_errno_and_return_minus_one( EINVAL );
     535
     536  if ( !signo )
     537    return 0;
     538
     539  if ( !is_valid_signo(signo) )
     540    set_errno_and_return_minus_one( EINVAL );
     541
     542  *set |= signo_to_mask(signo);
     543  return 0;
     544}
     545
     546/*
     547 *  3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
     548 */
     549
     550int sigdelset(
     551  sigset_t   *set,
     552  int         signo
     553)
     554{
     555  if ( !set )
     556    set_errno_and_return_minus_one( EINVAL );
     557 
     558  if ( !signo )
     559    return 0;
     560
     561  if ( !is_valid_signo(signo) )
     562    set_errno_and_return_minus_one( EINVAL );
     563 
     564  *set &= ~signo_to_mask(signo);
     565  return 0;
     566}
     567
     568/*
     569 *  3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
     570 */
     571
     572int sigismember(
     573  const sigset_t   *set,
     574  int               signo
     575)
     576{
     577  if ( !set )
     578    set_errno_and_return_minus_one( EINVAL );
     579 
     580  if ( !signo )
     581    return 0;
     582
     583  if ( !is_valid_signo(signo) )
     584    set_errno_and_return_minus_one( EINVAL );
     585 
     586  if ( *set & signo_to_mask(signo) )
     587    return 1;
     588
     589  return 0;
     590}
     591
     592/*
     593 *  3.3.4 Examine and Change Signal Action, P1003.1b-1993, p. 70
     594 */
     595
     596/* ***************************************************************************
     597 * The signal handler is notified to the timers manager when the
     598 * timer is set. So, the timers manager knows the signal handler.
     599 * ***************************************************************************/
     600
     601int sigaction(
     602  int                     sig,
     603  const struct sigaction *act,
     604  struct sigaction       *oact
     605)
     606{
     607  ISR_Level     level;
     608
     609 
     610  if ( oact )
     611    *oact = _POSIX_signals_Vectors[ sig ];
     612
     613  if ( !sig )
     614    return 0;
     615
     616  if ( !is_valid_signo(sig) )
     617    set_errno_and_return_minus_one( EINVAL );
     618 
     619  /*
     620   *  Some signals cannot be ignored (P1003.1b-1993, pp. 70-72 and references.
     621   *
     622   *  NOTE: Solaris documentation claims to "silently enforce" this which
     623   *        contradicts the POSIX specification.
     624   */
     625
     626  if ( sig == SIGKILL )
     627    set_errno_and_return_minus_one( EINVAL );
     628 
     629  /*
     630   *  Evaluate the new action structure and set the global signal vector
     631   *  appropriately.
     632   */
     633
     634  if ( act ) {
     635
     636    /*
     637     *  Unless the user is installing the default signal actions, then
     638     *  we can just copy the provided sigaction structure into the vectors.
     639     */
     640
     641    _ISR_Disable( level );
     642      if ( act->sa_handler == SIG_DFL ) {
     643        _POSIX_signals_Vectors[ sig ] = _POSIX_signals_Default_vectors[ sig ];
     644      } else {
     645         _POSIX_signals_Clear_process_signals( signo_to_mask(sig) );
     646         _POSIX_signals_Vectors[ sig ] = *act;
     647      }
     648    _ISR_Enable( level );
     649  }
     650
     651  /*
     652   *  No need to evaluate or dispatch because:
     653   *
     654   *    + If we were ignoring the signal before, none could be pending
     655   *      now (signals not posted when SIG_IGN).
     656   *    + If we are now ignoring a signal that was previously pending,
     657   *      we clear the pending signal indicator.
     658   */
     659
     660  return 0;
     661}
     662
     663/*
     664 *  3.3.5 Examine and Change Blocked Signals, P1003.1b-1993, p. 73
     665 *
     666 *  NOTE: P1003.1c/D10, p. 37 adds pthread_sigmask().
     667 *
     668 */
     669
     670int sigprocmask(
     671  int               how,
     672  const sigset_t   *set,
     673  sigset_t         *oset
     674)
     675{
     676  /*
     677   *  P1003.1c/Draft 10, p. 38 maps sigprocmask to pthread_sigmask.
     678   */
     679
     680  return pthread_sigmask( how, set, oset );
     681}
     682
     683/*
     684 *  3.3.5 Examine and Change Blocked Signals, P1003.1b-1993, p. 73
     685 *
     686 *  NOTE: P1003.1c/D10, p. 37 adds pthread_sigmask().
     687 */
     688
     689int pthread_sigmask(
     690  int               how,
     691  const sigset_t   *set,
     692  sigset_t         *oset
     693)
     694{
     695  POSIX_API_Control  *api;
     696
     697  if ( !set && !oset )
     698    set_errno_and_return_minus_one( EINVAL );
     699
     700  api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
     701
     702  if ( oset )
     703    *oset = api->signals_blocked;
     704 
     705  if ( !set )
     706    return 0;
     707
     708  switch ( how ) {
     709    case SIG_BLOCK:
     710      api->signals_blocked |= *set;
     711      break;
     712    case SIG_UNBLOCK:
     713      api->signals_blocked &= ~*set;
     714      break;
     715    case SIG_SETMASK:
     716      api->signals_blocked = *set;
     717      break;
     718    default:
     719      set_errno_and_return_minus_one( EINVAL );
     720  }
     721
     722  /* XXX are there critical section problems here? */
     723
     724  /* XXX evaluate the new set */
     725
     726  if ( ~api->signals_blocked &
     727       (api->signals_pending | _POSIX_signals_Pending) ) {
     728    _Thread_Executing->do_post_task_switch_extension = TRUE;
     729    _Thread_Dispatch();
     730  }
     731
     732  return 0;
     733}
     734
     735/*
     736 *  3.3.6 Examine Pending Signals, P1003.1b-1993, p. 75
     737 */
     738
     739int sigpending(
     740  sigset_t  *set
     741)
     742{
     743  POSIX_API_Control  *api;
     744 
     745  if ( !set )
     746    set_errno_and_return_minus_one( EINVAL );
     747 
     748  api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
     749 
     750  *set = api->signals_pending | _POSIX_signals_Pending;
     751 
     752  return 0;
     753}
     754
     755/*
     756 *  3.3.7 Wait for a Signal, P1003.1b-1993, p. 75
     757 */
     758
     759int sigsuspend(
     760  const sigset_t  *sigmask
     761)
     762{
     763  sigset_t            saved_signals_blocked;
     764  sigset_t            all_signals;
     765  int                 status;
     766  POSIX_API_Control  *api;
     767
     768  api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
     769
     770  status = sigprocmask( SIG_BLOCK, sigmask, &saved_signals_blocked );
     771 
     772  (void) sigfillset( &all_signals );
     773
     774  status = sigtimedwait( &all_signals, NULL, NULL );
     775
     776  (void) sigprocmask( SIG_SETMASK, &saved_signals_blocked, NULL );
     777
     778  return status;
     779}
     780
     781/*
     782 *  3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76
     783 *
     784 *  NOTE: P1003.1c/D10, p. 39 adds sigwait().
     785 */
     786
     787int sigwaitinfo(
     788  const sigset_t  *set,
     789  siginfo_t       *info
     790)
     791{
     792  return sigtimedwait( set, info, NULL );
     793}
     794
     795/*
     796 *  3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76
     797 *
     798 *  NOTE: P1003.1c/D10, p. 39 adds sigwait().
     799 */
     800
     801int _POSIX_signals_Get_highest(
     802  sigset_t   set
     803)
     804{
     805  int signo;
     806 
     807  for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) {
     808    if ( set & signo_to_mask( signo ) )
     809      return signo;
     810  }
     811 
     812/* XXX - add __SIGFIRSTNOTRT or something like that to newlib siginfo.h */
     813
     814  for ( signo = SIGHUP ; signo <= __SIGLASTNOTRT ; signo++ ) {
     815    if ( set & signo_to_mask( signo ) )
     816      return signo;
     817  }
     818
     819  return 0;
     820}
     821
     822int sigtimedwait(
     823  const sigset_t         *set,
     824  siginfo_t              *info,
     825  const struct timespec  *timeout
     826)
     827{
     828  Thread_Control    *the_thread;
     829  POSIX_API_Control *api;
     830  Watchdog_Interval  interval;
     831  siginfo_t          signal_information;
     832  siginfo_t         *the_info;
     833  int                signo;
     834 
     835  the_info = ( info ) ? info : &signal_information;
     836
     837  the_thread = _Thread_Executing;
     838
     839  api = the_thread->API_Extensions[ THREAD_API_POSIX ];
     840
     841  /*
     842   *  What if they are already pending?
     843   */
     844
     845  /* API signals pending? */
     846
     847  if ( *set & api->signals_pending ) {
     848    /* XXX real info later */
     849    the_info->si_signo = _POSIX_signals_Get_highest( api->signals_pending );
     850    _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info,
     851                                  FALSE, FALSE );
     852    the_info->si_code = SI_USER;
     853    the_info->si_value.sival_int = 0;
     854    return the_info->si_signo;
     855  }
     856
     857  /* Process pending signals? */
     858
     859  if ( *set & _POSIX_signals_Pending) {
     860    signo = _POSIX_signals_Get_highest( _POSIX_signals_Pending );
     861    _POSIX_signals_Clear_signals( api, signo, the_info, TRUE, FALSE );
     862
     863    if ( !info ) {
     864      the_info->si_signo = signo;
     865      the_info->si_code = SI_USER;
     866      the_info->si_value.sival_int = 0;
     867    }
     868  }
     869
     870  interval = 0;
     871  if ( timeout ) {
     872
     873    if (timeout->tv_nsec < 0 || timeout->tv_nsec >= TOD_NANOSECONDS_PER_SECOND)
     874      set_errno_and_return_minus_one( EINVAL );
     875
     876    interval = _POSIX_Timespec_to_interval( timeout );
     877  }
     878
     879  the_info->si_signo = -1;
     880
     881  _Thread_Disable_dispatch();
     882    the_thread->Wait.queue           = &_POSIX_signals_Wait_queue;
     883    the_thread->Wait.return_code     = EINTR;
     884    the_thread->Wait.option          = *set;
     885    the_thread->Wait.return_argument = (void *) the_info;
     886    _Thread_queue_Enter_critical_section( &_POSIX_signals_Wait_queue );
     887    _Thread_queue_Enqueue( &_POSIX_signals_Wait_queue, interval );
     888  _Thread_Enable_dispatch();
     889
     890  /*
     891   * When the thread set free by a signal, it is needed to eliminate
     892   * that signal
     893   */
     894
     895  _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info,
     896                                FALSE, FALSE );
     897
     898  errno = _Thread_Executing->Wait.return_code;
     899  return the_info->si_signo;
     900}
     901
     902/*
     903 *  3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76
     904 *
     905 *  NOTE: P1003.1c/D10, p. 39 adds sigwait().
     906 */
     907
     908int sigwait(
     909  const sigset_t  *set,
     910  int             *sig
     911)
     912{
     913  int status;
     914
     915  status = sigtimedwait( set, NULL, NULL );
     916
     917  if ( status != -1 ) {
     918    if ( sig )
     919      *sig = status;
     920    return 0;
     921  }
     922
     923  return errno;
     924}
     925
     926/*PAGE
     927 *
     928 *  3.3.2 Send a Signal to a Process, P1003.1b-1993, p. 68
     929 *
     930 *  NOTE: Behavior of kill() depends on _POSIX_SAVED_IDS.
     931 */
     932
     933#define _POSIX_signals_Is_interested( _api, _mask ) \
     934  ( ~(_api)->signals_blocked & (_mask) )
     935         
     936int killinfo(
     937  pid_t               pid,
     938  int                 sig,
     939  const union sigval *value
     940)
     941{
     942  sigset_t                     mask;
     943  POSIX_API_Control           *api;
     944  unsigned32                   the_class;
     945  unsigned32                   index;
     946  unsigned32                   maximum;
     947  Objects_Information         *the_info;
     948  Objects_Control            **object_table;
     949  Thread_Control              *the_thread;
     950  Thread_Control              *interested_thread;
     951  Priority_Control             interested_priority;
     952  Chain_Control               *the_chain;
     953  Chain_Node                  *the_node;
     954  siginfo_t                    siginfo_struct;
     955  siginfo_t                   *siginfo;
     956  POSIX_signals_Siginfo_node  *psiginfo;
     957 
     958
     959
     960  /*
     961   *  Only supported for the "calling process" (i.e. this node).
     962   */
     963 
     964  if( pid != getpid() )
     965    set_errno_and_return_minus_one( ESRCH );
     966
     967  /*
     968   *  Validate the signal passed if not 0.
     969   */
     970 
     971  if ( sig && !is_valid_signo(sig) )
     972  {
     973    set_errno_and_return_minus_one( EINVAL );
     974  }
     975
     976  /*
     977   *  If the signal is being ignored, then we are out of here.
     978   */
     979
     980  if ( !sig || _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN )
     981  {
     982    return 0;
     983  }
     984
     985  /*
     986   *  P1003.1c/Draft 10, p. 33 says that certain signals should always
     987   *  be directed to the executing thread such as those caused by hardware
     988   *  faults.
     989   */
     990
     991  switch ( sig ) {
     992    case SIGFPE:
     993    case SIGILL:
     994    case SIGSEGV:
     995      return pthread_kill( pthread_self(), sig );
     996    default:
     997      break;
     998  }
     999
     1000  mask = signo_to_mask( sig );
     1001
     1002  /*
     1003   *  Build up a siginfo structure
     1004   */
     1005
     1006  siginfo = &siginfo_struct;
     1007  siginfo->si_signo = sig;
     1008  siginfo->si_code = SI_USER;
     1009  if ( !value ) {
     1010    siginfo->si_value.sival_int = 0;
     1011  } else {
     1012    siginfo->si_value = *value;
     1013  }
     1014
     1015  _Thread_Disable_dispatch();
     1016
     1017  /*
     1018   *  Is the currently executing thread interested?  If so then it will
     1019   *  get it an execute it as soon as the dispatcher executes.
     1020   */
     1021
     1022  the_thread = _Thread_Executing;
     1023
     1024  api = the_thread->API_Extensions[ THREAD_API_POSIX ];
     1025  if ( _POSIX_signals_Is_interested( api, mask ) ) {
     1026    goto process_it;
     1027  }
     1028
     1029  /*
     1030   *  Is an interested thread waiting for this signal (sigwait())?
     1031   */
     1032
     1033  /* XXX violation of visibility -- need to define thread queue support */
     1034
     1035  for( index=0 ;
     1036       index < TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS ;
     1037       index++ ) {
     1038
     1039    the_chain = &_POSIX_signals_Wait_queue.Queues.Priority[ index ];
     1040 
     1041    for ( the_node = the_chain->first ;
     1042          !_Chain_Is_tail( the_chain, the_node ) ;
     1043          the_node = the_node->next ) {
     1044
     1045      the_thread = (Thread_Control *)the_node;
     1046      api = the_thread->API_Extensions[ THREAD_API_POSIX ];
     1047
     1048      if ((the_thread->Wait.option & mask) || (~api->signals_blocked & mask)) {
     1049        goto process_it;
     1050      }
     1051
     1052    }
     1053  }
     1054
     1055  /*
     1056   *  Is any other thread interested?  The highest priority interested
     1057   *  thread is selected.  In the event of a tie, then the following
     1058   *  additional criteria is used:
     1059   *
     1060   *    + ready thread over blocked
     1061   *    + blocked on call interruptible by signal (can return EINTR)
     1062   *    + blocked on call not interruptible by signal
     1063   *
     1064   *  This looks at every thread in the system regardless of the creating API.
     1065   *
     1066   *  NOTES:
     1067   *
     1068   *    + rtems internal threads do not receive signals.
     1069   */
     1070
     1071  interested_thread = NULL;
     1072  interested_priority = PRIORITY_MAXIMUM + 1;
     1073
     1074  for ( the_class = OBJECTS_CLASSES_FIRST_THREAD_CLASS;
     1075        the_class <= OBJECTS_CLASSES_LAST_THREAD_CLASS;
     1076        the_class++ ) {
     1077
     1078    if ( the_class == OBJECTS_INTERNAL_THREADS )
     1079      continue;
     1080
     1081    the_info = _Objects_Information_table[ the_class ];
     1082
     1083    if ( !the_info )                        /* manager not installed */
     1084      continue;
     1085
     1086    maximum = the_info->maximum;
     1087    object_table = the_info->local_table;
     1088
     1089    assert( object_table );                 /* always at least 1 entry */
     1090
     1091    for ( index = 1 ; index <= maximum ; index++ ) {
     1092      the_thread = (Thread_Control *) object_table[ index ];
     1093
     1094      if ( !the_thread )
     1095        continue;
     1096
     1097      /*
     1098       *  If this thread is of lower priority than the interested thread,
     1099       *  go on to the next thread.
     1100       */
     1101
     1102      if ( the_thread->current_priority > interested_priority )
     1103        continue;
     1104
     1105      /*
     1106       *  If this thread is not interested, then go on to the next thread.
     1107       */
     1108
     1109      api = the_thread->API_Extensions[ THREAD_API_POSIX ];
     1110
     1111      if ( !api || !_POSIX_signals_Is_interested( api, mask ) )
     1112        continue;
     1113
     1114      /*
     1115       *  Now we know the thread under connsideration is interested.
     1116       *  If the thread under consideration is of higher priority, then
     1117       *  it becomes the interested thread.
     1118       */
     1119
     1120      if ( the_thread->current_priority < interested_priority ) {
     1121        interested_thread   = the_thread;
     1122        interested_priority = the_thread->current_priority;
     1123        continue;
     1124      }
     1125
     1126      /*
     1127       *  Now the thread and the interested thread have the same priority.
     1128       *  If the interested thread is ready, then we don't need to send it
     1129       *  to a blocked thread.
     1130       */
     1131
     1132      if ( _States_Is_ready( interested_thread->current_state ) )
     1133        continue;
     1134
     1135      /*
     1136       *  Now the interested thread is blocked.
     1137       *  If the thread we are considering is not, the it becomes the
     1138       *  interested thread.
     1139       */
     1140
     1141      if ( _States_Is_ready( the_thread->current_state ) ) {
     1142        interested_thread   = the_thread;
     1143        interested_priority = the_thread->current_priority;
     1144        continue;
     1145      }
     1146
     1147      /*
     1148       *  Now we know both threads are blocked.
     1149       *  If the interested thread is interruptible, then just use it.
     1150       */
     1151
     1152      /* XXX need a new states macro */
     1153      if ( interested_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL )
     1154        continue;
     1155
     1156      /*
     1157       *  Now both threads are blocked and the interested thread is not
     1158       *  interruptible.
     1159       *  If the thread under consideration is interruptible by a signal,
     1160       *  then it becomes the interested thread.
     1161       */
     1162
     1163      /* XXX need a new states macro */
     1164      if ( the_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL ) {
     1165        interested_thread   = the_thread;
     1166        interested_priority = the_thread->current_priority;
     1167      }
     1168    }
     1169  }
     1170
     1171  if ( interested_thread ) {
     1172    the_thread = interested_thread;
     1173    goto process_it;
     1174  }
     1175
     1176  /*
     1177   *  OK so no threads were interested right now.  It will be left on the
     1178   *  global pending until a thread receives it.  The global set of threads
     1179   *  can change interest in this signal in one of the following ways:
     1180   *
     1181   *    + a thread is created with the signal unblocked,
     1182   *    + pthread_sigmask() unblocks the signal,
     1183   *    + sigprocmask() unblocks the signal, OR
     1184   *    + sigaction() which changes the handler to SIG_IGN.
     1185   */
     1186
     1187  the_thread = NULL;
     1188  goto post_process_signal;
     1189
     1190  /*
     1191   *  We found a thread which was interested, so now we mark that this
     1192   *  thread needs to do the post context switch extension so it can
     1193   *  evaluate the signals pending.
     1194   */
     1195
     1196process_it:
     1197 
     1198  the_thread->do_post_task_switch_extension = TRUE;
     1199
     1200  /*
     1201   *  Returns TRUE if the signal was synchronously given to a thread
     1202   *  blocked waiting for the signal.
     1203   */
     1204
     1205  if ( _POSIX_signals_Unblock_thread( the_thread, sig, siginfo ) ) {
     1206    _Thread_Enable_dispatch();
     1207    return 0;
     1208  }
     1209
     1210post_process_signal:
     1211
     1212  /*
     1213   *  We may have woken up a thread but we definitely need to post the
     1214   *  signal to the process wide information set.
     1215   */
     1216
     1217  _POSIX_signals_Set_process_signals( mask );
     1218
     1219  if ( _POSIX_signals_Vectors[ sig ].sa_flags == SA_SIGINFO ) {
     1220
     1221    psiginfo = (POSIX_signals_Siginfo_node *)
     1222               _Chain_Get( &_POSIX_signals_Inactive_siginfo );
     1223    if ( !psiginfo )
     1224    {
     1225      set_errno_and_return_minus_one( EAGAIN );
     1226    }
     1227
     1228    psiginfo->Info = *siginfo;
     1229
     1230    _Chain_Append( &_POSIX_signals_Siginfo[ sig ], &psiginfo->Node );
     1231  }
     1232
     1233  _Thread_Enable_dispatch();
     1234  return 0;
     1235}
     1236
     1237/*
     1238 *  3.3.9 Queue a Signal to a Process, P1003.1b-1993, p. 78
     1239 */
     1240
     1241int sigqueue(
     1242  pid_t               pid,
     1243  int                 signo,
     1244  const union sigval  value
     1245)
     1246{
     1247  return killinfo( pid, signo, &value );
     1248}
     1249
     1250/*
     1251 *  3.3.10 Send a Signal to a Thread, P1003.1c/D10, p. 43
     1252 */
     1253
     1254int pthread_kill(
     1255  pthread_t   thread,
     1256  int         sig
     1257)
     1258{
     1259  POSIX_API_Control  *api;
     1260  Thread_Control     *the_thread;
     1261  Objects_Locations  location;
     1262
     1263  if ( sig && !is_valid_signo(sig) )
     1264    set_errno_and_return_minus_one( EINVAL );
     1265/*
     1266  if ( _POSIX_signals_Vectors[ sig ].sa_flags == SA_SIGINFO )
     1267    set_errno_and_return_minus_one( ENOSYS );
     1268*/
     1269  /*
     1270   *  RTEMS does not support sending  a siginfo signal to a specific thread.
     1271   */
     1272
     1273  the_thread = _POSIX_Threads_Get( thread, &location );
     1274  switch ( location ) {
     1275    case OBJECTS_ERROR:
     1276    case OBJECTS_REMOTE:
     1277      set_errno_and_return_minus_one( ESRCH );
     1278    case OBJECTS_LOCAL:
     1279      /*
     1280       *  If sig == 0 then just validate arguments
     1281       */
     1282
     1283      api = the_thread->API_Extensions[ THREAD_API_POSIX ];
     1284
     1285      if ( sig ) {
     1286
     1287        if ( _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN ) {
     1288          _Thread_Enable_dispatch();
     1289          return 0;
     1290        }
     1291
     1292        /* XXX critical section */
     1293
     1294        api->signals_pending |= signo_to_mask( sig );
     1295
     1296        (void) _POSIX_signals_Unblock_thread( the_thread, sig, NULL );
     1297
     1298        the_thread->do_post_task_switch_extension = TRUE;
     1299
     1300        if ( _ISR_Is_in_progress() && _Thread_Is_executing( the_thread ) )
     1301          _ISR_Signals_to_thread_executing = TRUE;
     1302      }
     1303      _Thread_Enable_dispatch();
     1304      return 0;
     1305  }
     1306
     1307  return POSIX_BOTTOM_REACHED();
     1308}
     1309
     1310/*
     1311 *  3.4.1 Schedule Alarm, P1003.1b-1993, p. 79
     1312 */
     1313
     1314Watchdog_Control _POSIX_signals_Alarm_timer;
     1315
     1316unsigned int alarm(
     1317  unsigned int seconds
     1318)
     1319{
     1320  unsigned int      remaining = 0;
     1321  Watchdog_Control *the_timer;
     1322
     1323  the_timer = &_POSIX_signals_Alarm_timer;
     1324
     1325  switch ( _Watchdog_Remove( the_timer ) ) {
     1326    case WATCHDOG_INACTIVE:
     1327    case WATCHDOG_BEING_INSERTED:
     1328      break;
     1329 
     1330    case WATCHDOG_ACTIVE:
     1331    case WATCHDOG_REMOVE_IT:
     1332      remaining = the_timer->initial -
     1333                  (the_timer->stop_time - the_timer->start_time);
     1334      break;
     1335  }
     1336
     1337  _Watchdog_Insert_seconds( the_timer, seconds );
     1338
     1339  return remaining;
     1340}
     1341
     1342/*
     1343 *  3.4.2 Suspend Process Execution, P1003.1b-1993, p. 81
     1344 */
     1345
     1346int pause( void )
     1347{
     1348  sigset_t  all_signals;
     1349  int       status;
     1350 
     1351  (void) sigfillset( &all_signals );
     1352 
     1353  status = sigtimedwait( &all_signals, NULL, NULL );
     1354 
     1355  return status;
     1356}
  • cpukit/posix/src/ptimer.c

    r8cdb582 r82f490f  
    190190    */
    191191
     192   timer_max = max_timers;
     193
    192194   for (index=0; index<max_timers; index++)
    193195     TIMER_INITIALIZE_S( index );
Note: See TracChangeset for help on using the changeset viewer.