Changeset 89b6397 in rtems


Ignore:
Timestamp:
Nov 1, 1999, 6:02:44 PM (20 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, master
Children:
c42e6c72
Parents:
c61218e8
Message:

Removed routines that had already been separated into their own files.

Files:
2 edited

Legend:

Unmodified
Added
Removed
  • c/src/exec/posix/src/psignal.c

    rc61218e8 r89b6397  
    479479  );
    480480}
    481 
    482 /*
    483  *  3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
    484  */
    485 
    486 int sigemptyset(
    487   sigset_t   *set
    488 )
    489 {
    490   if ( !set )
    491     set_errno_and_return_minus_one( EINVAL );
    492 
    493   *set = 0;
    494   return 0;
    495 }
    496 
    497 /*
    498  *  3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
    499  */
    500 
    501 int sigfillset(
    502   sigset_t   *set
    503 )
    504 {
    505   if ( !set )
    506     set_errno_and_return_minus_one( EINVAL );
    507 
    508   *set = SIGNAL_ALL_MASK;
    509   return 0;
    510 }
    511 
    512 /*
    513  *  3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
    514  */
    515 
    516 int sigaddset(
    517   sigset_t   *set,
    518   int         signo
    519 )
    520 {
    521   if ( !set )
    522     set_errno_and_return_minus_one( EINVAL );
    523 
    524   if ( !signo )
    525     return 0;
    526 
    527   if ( !is_valid_signo(signo) )
    528     set_errno_and_return_minus_one( EINVAL );
    529 
    530   *set |= signo_to_mask(signo);
    531   return 0;
    532 }
    533 
    534 /*
    535  *  3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
    536  */
    537 
    538 int sigdelset(
    539   sigset_t   *set,
    540   int         signo
    541 )
    542 {
    543   if ( !set )
    544     set_errno_and_return_minus_one( EINVAL );
    545  
    546   if ( !signo )
    547     return 0;
    548 
    549   if ( !is_valid_signo(signo) )
    550     set_errno_and_return_minus_one( EINVAL );
    551  
    552   *set &= ~signo_to_mask(signo);
    553   return 0;
    554 }
    555 
    556 /*
    557  *  3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
    558  */
    559 
    560 int sigismember(
    561   const sigset_t   *set,
    562   int               signo
    563 )
    564 {
    565   if ( !set )
    566     set_errno_and_return_minus_one( EINVAL );
    567  
    568   if ( !signo )
    569     return 0;
    570 
    571   if ( !is_valid_signo(signo) )
    572     set_errno_and_return_minus_one( EINVAL );
    573  
    574   if ( *set & signo_to_mask(signo) )
    575     return 1;
    576 
    577   return 0;
    578 }
    579 
    580 /*
    581  *  3.3.4 Examine and Change Signal Action, P1003.1b-1993, p. 70
    582  */
    583 
    584 /* ***************************************************************************
    585  * The signal handler is notified to the timers manager when the
    586  * timer is set. So, the timers manager knows the signal handler.
    587  * ***************************************************************************/
    588 
    589 int sigaction(
    590   int                     sig,
    591   const struct sigaction *act,
    592   struct sigaction       *oact
    593 )
    594 {
    595   ISR_Level     level;
    596 
    597  
    598   if ( oact )
    599     *oact = _POSIX_signals_Vectors[ sig ];
    600 
    601   if ( !sig )
    602     return 0;
    603 
    604   if ( !is_valid_signo(sig) )
    605     set_errno_and_return_minus_one( EINVAL );
    606  
    607   /*
    608    *  Some signals cannot be ignored (P1003.1b-1993, pp. 70-72 and references.
    609    *
    610    *  NOTE: Solaris documentation claims to "silently enforce" this which
    611    *        contradicts the POSIX specification.
    612    */
    613 
    614   if ( sig == SIGKILL )
    615     set_errno_and_return_minus_one( EINVAL );
    616  
    617   /*
    618    *  Evaluate the new action structure and set the global signal vector
    619    *  appropriately.
    620    */
    621 
    622   if ( act ) {
    623 
    624     /*
    625      *  Unless the user is installing the default signal actions, then
    626      *  we can just copy the provided sigaction structure into the vectors.
    627      */
    628 
    629     _ISR_Disable( level );
    630       if ( act->sa_handler == SIG_DFL ) {
    631         _POSIX_signals_Vectors[ sig ] = _POSIX_signals_Default_vectors[ sig ];
    632       } else {
    633          _POSIX_signals_Clear_process_signals( signo_to_mask(sig) );
    634          _POSIX_signals_Vectors[ sig ] = *act;
    635       }
    636     _ISR_Enable( level );
    637   }
    638 
    639   /*
    640    *  No need to evaluate or dispatch because:
    641    *
    642    *    + If we were ignoring the signal before, none could be pending
    643    *      now (signals not posted when SIG_IGN).
    644    *    + If we are now ignoring a signal that was previously pending,
    645    *      we clear the pending signal indicator.
    646    */
    647 
    648   return 0;
    649 }
    650 
    651 /*
    652  *  3.3.5 Examine and Change Blocked Signals, P1003.1b-1993, p. 73
    653  *
    654  *  NOTE: P1003.1c/D10, p. 37 adds pthread_sigmask().
    655  *
    656  */
    657 
    658 int sigprocmask(
    659   int               how,
    660   const sigset_t   *set,
    661   sigset_t         *oset
    662 )
    663 {
    664   /*
    665    *  P1003.1c/Draft 10, p. 38 maps sigprocmask to pthread_sigmask.
    666    */
    667 
    668   return pthread_sigmask( how, set, oset );
    669 }
    670 
    671 /*
    672  *  3.3.5 Examine and Change Blocked Signals, P1003.1b-1993, p. 73
    673  *
    674  *  NOTE: P1003.1c/D10, p. 37 adds pthread_sigmask().
    675  */
    676 
    677 int pthread_sigmask(
    678   int               how,
    679   const sigset_t   *set,
    680   sigset_t         *oset
    681 )
    682 {
    683   POSIX_API_Control  *api;
    684 
    685   if ( !set && !oset )
    686     set_errno_and_return_minus_one( EINVAL );
    687 
    688   api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
    689 
    690   if ( oset )
    691     *oset = api->signals_blocked;
    692  
    693   if ( !set )
    694     return 0;
    695 
    696   switch ( how ) {
    697     case SIG_BLOCK:
    698       api->signals_blocked |= *set;
    699       break;
    700     case SIG_UNBLOCK:
    701       api->signals_blocked &= ~*set;
    702       break;
    703     case SIG_SETMASK:
    704       api->signals_blocked = *set;
    705       break;
    706     default:
    707       set_errno_and_return_minus_one( EINVAL );
    708   }
    709 
    710   /* XXX are there critical section problems here? */
    711 
    712   /* XXX evaluate the new set */
    713 
    714   if ( ~api->signals_blocked &
    715        (api->signals_pending | _POSIX_signals_Pending) ) {
    716     _Thread_Executing->do_post_task_switch_extension = TRUE;
    717     _Thread_Dispatch();
    718   }
    719 
    720   return 0;
    721 }
    722 
    723 /*
    724  *  3.3.6 Examine Pending Signals, P1003.1b-1993, p. 75
    725  */
    726 
    727 int sigpending(
    728   sigset_t  *set
    729 )
    730 {
    731   POSIX_API_Control  *api;
    732  
    733   if ( !set )
    734     set_errno_and_return_minus_one( EINVAL );
    735  
    736   api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
    737  
    738   *set = api->signals_pending | _POSIX_signals_Pending;
    739  
    740   return 0;
    741 }
    742 
    743 /*
    744  *  3.3.7 Wait for a Signal, P1003.1b-1993, p. 75
    745  */
    746 
    747 int sigsuspend(
    748   const sigset_t  *sigmask
    749 )
    750 {
    751   sigset_t            saved_signals_blocked;
    752   sigset_t            all_signals;
    753   int                 status;
    754   POSIX_API_Control  *api;
    755 
    756   api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
    757 
    758   status = sigprocmask( SIG_BLOCK, sigmask, &saved_signals_blocked );
    759  
    760   (void) sigfillset( &all_signals );
    761 
    762   status = sigtimedwait( &all_signals, NULL, NULL );
    763 
    764   (void) sigprocmask( SIG_SETMASK, &saved_signals_blocked, NULL );
    765 
    766   return status;
    767 }
    768 
    769 /*
    770  *  3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76
    771  *
    772  *  NOTE: P1003.1c/D10, p. 39 adds sigwait().
    773  */
    774 
    775 int sigwaitinfo(
    776   const sigset_t  *set,
    777   siginfo_t       *info
    778 )
    779 {
    780   return sigtimedwait( set, info, NULL );
    781 }
    782 
    783 /*
    784  *  3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76
    785  *
    786  *  NOTE: P1003.1c/D10, p. 39 adds sigwait().
    787  */
    788 
    789 int _POSIX_signals_Get_highest(
    790   sigset_t   set
    791 )
    792 {
    793   int signo;
    794  
    795   for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) {
    796     if ( set & signo_to_mask( signo ) )
    797       return signo;
    798   }
    799  
    800 /* XXX - add __SIGFIRSTNOTRT or something like that to newlib siginfo.h */
    801 
    802   for ( signo = SIGHUP ; signo <= __SIGLASTNOTRT ; signo++ ) {
    803     if ( set & signo_to_mask( signo ) )
    804       return signo;
    805   }
    806 
    807   return 0;
    808 }
    809 
    810 int sigtimedwait(
    811   const sigset_t         *set,
    812   siginfo_t              *info,
    813   const struct timespec  *timeout
    814 )
    815 {
    816   Thread_Control    *the_thread;
    817   POSIX_API_Control *api;
    818   Watchdog_Interval  interval;
    819   siginfo_t          signal_information;
    820   siginfo_t         *the_info;
    821   int                signo;
    822  
    823   the_info = ( info ) ? info : &signal_information;
    824 
    825   the_thread = _Thread_Executing;
    826 
    827   api = the_thread->API_Extensions[ THREAD_API_POSIX ];
    828 
    829   /*
    830    *  What if they are already pending?
    831    */
    832 
    833   /* API signals pending? */
    834 
    835   if ( *set & api->signals_pending ) {
    836     /* XXX real info later */
    837     the_info->si_signo = _POSIX_signals_Get_highest( api->signals_pending );
    838     _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info,
    839                                   FALSE, FALSE );
    840     the_info->si_code = SI_USER;
    841     the_info->si_value.sival_int = 0;
    842     return the_info->si_signo;
    843   }
    844 
    845   /* Process pending signals? */
    846 
    847   if ( *set & _POSIX_signals_Pending) {
    848     signo = _POSIX_signals_Get_highest( _POSIX_signals_Pending );
    849     _POSIX_signals_Clear_signals( api, signo, the_info, TRUE, FALSE );
    850 
    851     if ( !info ) {
    852       the_info->si_signo = signo;
    853       the_info->si_code = SI_USER;
    854       the_info->si_value.sival_int = 0;
    855     }
    856   }
    857 
    858   interval = 0;
    859   if ( timeout ) {
    860 
    861     if (timeout->tv_nsec < 0 || timeout->tv_nsec >= TOD_NANOSECONDS_PER_SECOND)
    862       set_errno_and_return_minus_one( EINVAL );
    863 
    864     interval = _POSIX_Timespec_to_interval( timeout );
    865   }
    866 
    867   the_info->si_signo = -1;
    868 
    869   _Thread_Disable_dispatch();
    870     the_thread->Wait.queue           = &_POSIX_signals_Wait_queue;
    871     the_thread->Wait.return_code     = EINTR;
    872     the_thread->Wait.option          = *set;
    873     the_thread->Wait.return_argument = (void *) the_info;
    874     _Thread_queue_Enter_critical_section( &_POSIX_signals_Wait_queue );
    875     _Thread_queue_Enqueue( &_POSIX_signals_Wait_queue, interval );
    876   _Thread_Enable_dispatch();
    877 
    878   /*
    879    * When the thread set free by a signal, it is needed to eliminate
    880    * that signal
    881    */
    882 
    883   _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info,
    884                                 FALSE, FALSE );
    885 
    886   errno = _Thread_Executing->Wait.return_code;
    887   return the_info->si_signo;
    888 }
    889 
    890 /*
    891  *  3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76
    892  *
    893  *  NOTE: P1003.1c/D10, p. 39 adds sigwait().
    894  */
    895 
    896 int sigwait(
    897   const sigset_t  *set,
    898   int             *sig
    899 )
    900 {
    901   int status;
    902 
    903   status = sigtimedwait( set, NULL, NULL );
    904 
    905   if ( status != -1 ) {
    906     if ( sig )
    907       *sig = status;
    908     return 0;
    909   }
    910 
    911   return errno;
    912 }
    913 
    914 /*
    915  *  3.3.9 Queue a Signal to a Process, P1003.1b-1993, p. 78
    916  */
    917 
    918 int sigqueue(
    919   pid_t               pid,
    920   int                 signo,
    921   const union sigval  value
    922 )
    923 {
    924   return killinfo( pid, signo, &value );
    925 }
    926 
    927 /*
    928  *  3.3.10 Send a Signal to a Thread, P1003.1c/D10, p. 43
    929  */
    930 
    931 int pthread_kill(
    932   pthread_t   thread,
    933   int         sig
    934 )
    935 {
    936   POSIX_API_Control  *api;
    937   Thread_Control     *the_thread;
    938   Objects_Locations  location;
    939 
    940   if ( sig && !is_valid_signo(sig) )
    941     set_errno_and_return_minus_one( EINVAL );
    942 /*
    943   if ( _POSIX_signals_Vectors[ sig ].sa_flags == SA_SIGINFO )
    944     set_errno_and_return_minus_one( ENOSYS );
    945 */
    946   /*
    947    *  RTEMS does not support sending  a siginfo signal to a specific thread.
    948    */
    949 
    950   the_thread = _POSIX_Threads_Get( thread, &location );
    951   switch ( location ) {
    952     case OBJECTS_ERROR:
    953     case OBJECTS_REMOTE:
    954       set_errno_and_return_minus_one( ESRCH );
    955     case OBJECTS_LOCAL:
    956       /*
    957        *  If sig == 0 then just validate arguments
    958        */
    959 
    960       api = the_thread->API_Extensions[ THREAD_API_POSIX ];
    961 
    962       if ( sig ) {
    963 
    964         if ( _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN ) {
    965           _Thread_Enable_dispatch();
    966           return 0;
    967         }
    968 
    969         /* XXX critical section */
    970 
    971         api->signals_pending |= signo_to_mask( sig );
    972 
    973         (void) _POSIX_signals_Unblock_thread( the_thread, sig, NULL );
    974 
    975         the_thread->do_post_task_switch_extension = TRUE;
    976 
    977         if ( _ISR_Is_in_progress() && _Thread_Is_executing( the_thread ) )
    978           _ISR_Signals_to_thread_executing = TRUE;
    979       }
    980       _Thread_Enable_dispatch();
    981       return 0;
    982   }
    983 
    984   return POSIX_BOTTOM_REACHED();
    985 }
  • cpukit/posix/src/psignal.c

    rc61218e8 r89b6397  
    479479  );
    480480}
    481 
    482 /*
    483  *  3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
    484  */
    485 
    486 int sigemptyset(
    487   sigset_t   *set
    488 )
    489 {
    490   if ( !set )
    491     set_errno_and_return_minus_one( EINVAL );
    492 
    493   *set = 0;
    494   return 0;
    495 }
    496 
    497 /*
    498  *  3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
    499  */
    500 
    501 int sigfillset(
    502   sigset_t   *set
    503 )
    504 {
    505   if ( !set )
    506     set_errno_and_return_minus_one( EINVAL );
    507 
    508   *set = SIGNAL_ALL_MASK;
    509   return 0;
    510 }
    511 
    512 /*
    513  *  3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
    514  */
    515 
    516 int sigaddset(
    517   sigset_t   *set,
    518   int         signo
    519 )
    520 {
    521   if ( !set )
    522     set_errno_and_return_minus_one( EINVAL );
    523 
    524   if ( !signo )
    525     return 0;
    526 
    527   if ( !is_valid_signo(signo) )
    528     set_errno_and_return_minus_one( EINVAL );
    529 
    530   *set |= signo_to_mask(signo);
    531   return 0;
    532 }
    533 
    534 /*
    535  *  3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
    536  */
    537 
    538 int sigdelset(
    539   sigset_t   *set,
    540   int         signo
    541 )
    542 {
    543   if ( !set )
    544     set_errno_and_return_minus_one( EINVAL );
    545  
    546   if ( !signo )
    547     return 0;
    548 
    549   if ( !is_valid_signo(signo) )
    550     set_errno_and_return_minus_one( EINVAL );
    551  
    552   *set &= ~signo_to_mask(signo);
    553   return 0;
    554 }
    555 
    556 /*
    557  *  3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
    558  */
    559 
    560 int sigismember(
    561   const sigset_t   *set,
    562   int               signo
    563 )
    564 {
    565   if ( !set )
    566     set_errno_and_return_minus_one( EINVAL );
    567  
    568   if ( !signo )
    569     return 0;
    570 
    571   if ( !is_valid_signo(signo) )
    572     set_errno_and_return_minus_one( EINVAL );
    573  
    574   if ( *set & signo_to_mask(signo) )
    575     return 1;
    576 
    577   return 0;
    578 }
    579 
    580 /*
    581  *  3.3.4 Examine and Change Signal Action, P1003.1b-1993, p. 70
    582  */
    583 
    584 /* ***************************************************************************
    585  * The signal handler is notified to the timers manager when the
    586  * timer is set. So, the timers manager knows the signal handler.
    587  * ***************************************************************************/
    588 
    589 int sigaction(
    590   int                     sig,
    591   const struct sigaction *act,
    592   struct sigaction       *oact
    593 )
    594 {
    595   ISR_Level     level;
    596 
    597  
    598   if ( oact )
    599     *oact = _POSIX_signals_Vectors[ sig ];
    600 
    601   if ( !sig )
    602     return 0;
    603 
    604   if ( !is_valid_signo(sig) )
    605     set_errno_and_return_minus_one( EINVAL );
    606  
    607   /*
    608    *  Some signals cannot be ignored (P1003.1b-1993, pp. 70-72 and references.
    609    *
    610    *  NOTE: Solaris documentation claims to "silently enforce" this which
    611    *        contradicts the POSIX specification.
    612    */
    613 
    614   if ( sig == SIGKILL )
    615     set_errno_and_return_minus_one( EINVAL );
    616  
    617   /*
    618    *  Evaluate the new action structure and set the global signal vector
    619    *  appropriately.
    620    */
    621 
    622   if ( act ) {
    623 
    624     /*
    625      *  Unless the user is installing the default signal actions, then
    626      *  we can just copy the provided sigaction structure into the vectors.
    627      */
    628 
    629     _ISR_Disable( level );
    630       if ( act->sa_handler == SIG_DFL ) {
    631         _POSIX_signals_Vectors[ sig ] = _POSIX_signals_Default_vectors[ sig ];
    632       } else {
    633          _POSIX_signals_Clear_process_signals( signo_to_mask(sig) );
    634          _POSIX_signals_Vectors[ sig ] = *act;
    635       }
    636     _ISR_Enable( level );
    637   }
    638 
    639   /*
    640    *  No need to evaluate or dispatch because:
    641    *
    642    *    + If we were ignoring the signal before, none could be pending
    643    *      now (signals not posted when SIG_IGN).
    644    *    + If we are now ignoring a signal that was previously pending,
    645    *      we clear the pending signal indicator.
    646    */
    647 
    648   return 0;
    649 }
    650 
    651 /*
    652  *  3.3.5 Examine and Change Blocked Signals, P1003.1b-1993, p. 73
    653  *
    654  *  NOTE: P1003.1c/D10, p. 37 adds pthread_sigmask().
    655  *
    656  */
    657 
    658 int sigprocmask(
    659   int               how,
    660   const sigset_t   *set,
    661   sigset_t         *oset
    662 )
    663 {
    664   /*
    665    *  P1003.1c/Draft 10, p. 38 maps sigprocmask to pthread_sigmask.
    666    */
    667 
    668   return pthread_sigmask( how, set, oset );
    669 }
    670 
    671 /*
    672  *  3.3.5 Examine and Change Blocked Signals, P1003.1b-1993, p. 73
    673  *
    674  *  NOTE: P1003.1c/D10, p. 37 adds pthread_sigmask().
    675  */
    676 
    677 int pthread_sigmask(
    678   int               how,
    679   const sigset_t   *set,
    680   sigset_t         *oset
    681 )
    682 {
    683   POSIX_API_Control  *api;
    684 
    685   if ( !set && !oset )
    686     set_errno_and_return_minus_one( EINVAL );
    687 
    688   api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
    689 
    690   if ( oset )
    691     *oset = api->signals_blocked;
    692  
    693   if ( !set )
    694     return 0;
    695 
    696   switch ( how ) {
    697     case SIG_BLOCK:
    698       api->signals_blocked |= *set;
    699       break;
    700     case SIG_UNBLOCK:
    701       api->signals_blocked &= ~*set;
    702       break;
    703     case SIG_SETMASK:
    704       api->signals_blocked = *set;
    705       break;
    706     default:
    707       set_errno_and_return_minus_one( EINVAL );
    708   }
    709 
    710   /* XXX are there critical section problems here? */
    711 
    712   /* XXX evaluate the new set */
    713 
    714   if ( ~api->signals_blocked &
    715        (api->signals_pending | _POSIX_signals_Pending) ) {
    716     _Thread_Executing->do_post_task_switch_extension = TRUE;
    717     _Thread_Dispatch();
    718   }
    719 
    720   return 0;
    721 }
    722 
    723 /*
    724  *  3.3.6 Examine Pending Signals, P1003.1b-1993, p. 75
    725  */
    726 
    727 int sigpending(
    728   sigset_t  *set
    729 )
    730 {
    731   POSIX_API_Control  *api;
    732  
    733   if ( !set )
    734     set_errno_and_return_minus_one( EINVAL );
    735  
    736   api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
    737  
    738   *set = api->signals_pending | _POSIX_signals_Pending;
    739  
    740   return 0;
    741 }
    742 
    743 /*
    744  *  3.3.7 Wait for a Signal, P1003.1b-1993, p. 75
    745  */
    746 
    747 int sigsuspend(
    748   const sigset_t  *sigmask
    749 )
    750 {
    751   sigset_t            saved_signals_blocked;
    752   sigset_t            all_signals;
    753   int                 status;
    754   POSIX_API_Control  *api;
    755 
    756   api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
    757 
    758   status = sigprocmask( SIG_BLOCK, sigmask, &saved_signals_blocked );
    759  
    760   (void) sigfillset( &all_signals );
    761 
    762   status = sigtimedwait( &all_signals, NULL, NULL );
    763 
    764   (void) sigprocmask( SIG_SETMASK, &saved_signals_blocked, NULL );
    765 
    766   return status;
    767 }
    768 
    769 /*
    770  *  3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76
    771  *
    772  *  NOTE: P1003.1c/D10, p. 39 adds sigwait().
    773  */
    774 
    775 int sigwaitinfo(
    776   const sigset_t  *set,
    777   siginfo_t       *info
    778 )
    779 {
    780   return sigtimedwait( set, info, NULL );
    781 }
    782 
    783 /*
    784  *  3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76
    785  *
    786  *  NOTE: P1003.1c/D10, p. 39 adds sigwait().
    787  */
    788 
    789 int _POSIX_signals_Get_highest(
    790   sigset_t   set
    791 )
    792 {
    793   int signo;
    794  
    795   for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) {
    796     if ( set & signo_to_mask( signo ) )
    797       return signo;
    798   }
    799  
    800 /* XXX - add __SIGFIRSTNOTRT or something like that to newlib siginfo.h */
    801 
    802   for ( signo = SIGHUP ; signo <= __SIGLASTNOTRT ; signo++ ) {
    803     if ( set & signo_to_mask( signo ) )
    804       return signo;
    805   }
    806 
    807   return 0;
    808 }
    809 
    810 int sigtimedwait(
    811   const sigset_t         *set,
    812   siginfo_t              *info,
    813   const struct timespec  *timeout
    814 )
    815 {
    816   Thread_Control    *the_thread;
    817   POSIX_API_Control *api;
    818   Watchdog_Interval  interval;
    819   siginfo_t          signal_information;
    820   siginfo_t         *the_info;
    821   int                signo;
    822  
    823   the_info = ( info ) ? info : &signal_information;
    824 
    825   the_thread = _Thread_Executing;
    826 
    827   api = the_thread->API_Extensions[ THREAD_API_POSIX ];
    828 
    829   /*
    830    *  What if they are already pending?
    831    */
    832 
    833   /* API signals pending? */
    834 
    835   if ( *set & api->signals_pending ) {
    836     /* XXX real info later */
    837     the_info->si_signo = _POSIX_signals_Get_highest( api->signals_pending );
    838     _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info,
    839                                   FALSE, FALSE );
    840     the_info->si_code = SI_USER;
    841     the_info->si_value.sival_int = 0;
    842     return the_info->si_signo;
    843   }
    844 
    845   /* Process pending signals? */
    846 
    847   if ( *set & _POSIX_signals_Pending) {
    848     signo = _POSIX_signals_Get_highest( _POSIX_signals_Pending );
    849     _POSIX_signals_Clear_signals( api, signo, the_info, TRUE, FALSE );
    850 
    851     if ( !info ) {
    852       the_info->si_signo = signo;
    853       the_info->si_code = SI_USER;
    854       the_info->si_value.sival_int = 0;
    855     }
    856   }
    857 
    858   interval = 0;
    859   if ( timeout ) {
    860 
    861     if (timeout->tv_nsec < 0 || timeout->tv_nsec >= TOD_NANOSECONDS_PER_SECOND)
    862       set_errno_and_return_minus_one( EINVAL );
    863 
    864     interval = _POSIX_Timespec_to_interval( timeout );
    865   }
    866 
    867   the_info->si_signo = -1;
    868 
    869   _Thread_Disable_dispatch();
    870     the_thread->Wait.queue           = &_POSIX_signals_Wait_queue;
    871     the_thread->Wait.return_code     = EINTR;
    872     the_thread->Wait.option          = *set;
    873     the_thread->Wait.return_argument = (void *) the_info;
    874     _Thread_queue_Enter_critical_section( &_POSIX_signals_Wait_queue );
    875     _Thread_queue_Enqueue( &_POSIX_signals_Wait_queue, interval );
    876   _Thread_Enable_dispatch();
    877 
    878   /*
    879    * When the thread set free by a signal, it is needed to eliminate
    880    * that signal
    881    */
    882 
    883   _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info,
    884                                 FALSE, FALSE );
    885 
    886   errno = _Thread_Executing->Wait.return_code;
    887   return the_info->si_signo;
    888 }
    889 
    890 /*
    891  *  3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76
    892  *
    893  *  NOTE: P1003.1c/D10, p. 39 adds sigwait().
    894  */
    895 
    896 int sigwait(
    897   const sigset_t  *set,
    898   int             *sig
    899 )
    900 {
    901   int status;
    902 
    903   status = sigtimedwait( set, NULL, NULL );
    904 
    905   if ( status != -1 ) {
    906     if ( sig )
    907       *sig = status;
    908     return 0;
    909   }
    910 
    911   return errno;
    912 }
    913 
    914 /*
    915  *  3.3.9 Queue a Signal to a Process, P1003.1b-1993, p. 78
    916  */
    917 
    918 int sigqueue(
    919   pid_t               pid,
    920   int                 signo,
    921   const union sigval  value
    922 )
    923 {
    924   return killinfo( pid, signo, &value );
    925 }
    926 
    927 /*
    928  *  3.3.10 Send a Signal to a Thread, P1003.1c/D10, p. 43
    929  */
    930 
    931 int pthread_kill(
    932   pthread_t   thread,
    933   int         sig
    934 )
    935 {
    936   POSIX_API_Control  *api;
    937   Thread_Control     *the_thread;
    938   Objects_Locations  location;
    939 
    940   if ( sig && !is_valid_signo(sig) )
    941     set_errno_and_return_minus_one( EINVAL );
    942 /*
    943   if ( _POSIX_signals_Vectors[ sig ].sa_flags == SA_SIGINFO )
    944     set_errno_and_return_minus_one( ENOSYS );
    945 */
    946   /*
    947    *  RTEMS does not support sending  a siginfo signal to a specific thread.
    948    */
    949 
    950   the_thread = _POSIX_Threads_Get( thread, &location );
    951   switch ( location ) {
    952     case OBJECTS_ERROR:
    953     case OBJECTS_REMOTE:
    954       set_errno_and_return_minus_one( ESRCH );
    955     case OBJECTS_LOCAL:
    956       /*
    957        *  If sig == 0 then just validate arguments
    958        */
    959 
    960       api = the_thread->API_Extensions[ THREAD_API_POSIX ];
    961 
    962       if ( sig ) {
    963 
    964         if ( _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN ) {
    965           _Thread_Enable_dispatch();
    966           return 0;
    967         }
    968 
    969         /* XXX critical section */
    970 
    971         api->signals_pending |= signo_to_mask( sig );
    972 
    973         (void) _POSIX_signals_Unblock_thread( the_thread, sig, NULL );
    974 
    975         the_thread->do_post_task_switch_extension = TRUE;
    976 
    977         if ( _ISR_Is_in_progress() && _Thread_Is_executing( the_thread ) )
    978           _ISR_Signals_to_thread_executing = TRUE;
    979       }
    980       _Thread_Enable_dispatch();
    981       return 0;
    982   }
    983 
    984   return POSIX_BOTTOM_REACHED();
    985 }
Note: See TracChangeset for help on using the changeset viewer.