Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:36

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  *  COPYRIGHT (c) 1989-2009.
0005  *  On-Line Applications Research Corporation (OAR).
0006  *
0007  * Redistribution and use in source and binary forms, with or without
0008  * modification, are permitted provided that the following conditions
0009  * are met:
0010  * 1. Redistributions of source code must retain the above copyright
0011  *    notice, this list of conditions and the following disclaimer.
0012  * 2. Redistributions in binary form must reproduce the above copyright
0013  *    notice, this list of conditions and the following disclaimer in the
0014  *    documentation and/or other materials provided with the distribution.
0015  *
0016  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0017  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0018  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0019  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0020  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0021  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0022  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0023  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0024  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0025  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0026  * POSSIBILITY OF SUCH DAMAGE.
0027  */
0028 
0029 #ifdef HAVE_CONFIG_H
0030 #include "config.h"
0031 #endif
0032 
0033 #define CONFIGURE_INIT
0034 #include "system.h"
0035 #include <signal.h>
0036 #include <errno.h>
0037 
0038 const char rtems_test_name[] = "PSX 4";
0039 
0040 volatile int Signal_occurred;
0041 volatile int Signal_count;
0042 void Signal_handler( int signo );
0043 void Signal_info_handler(
0044   int        signo,
0045   siginfo_t *info,
0046   void      *context
0047 );
0048 
0049 void Signal_handler(
0050   int signo
0051 )
0052 {
0053   Signal_count++;
0054   printf(
0055     "Signal: %d caught by 0x%" PRIxpthread_t " (%d)\n",
0056     signo,
0057     pthread_self(),
0058     Signal_count
0059   );
0060   Signal_occurred = 1;
0061 }
0062 
0063 void Signal_info_handler(
0064   int        signo,
0065   siginfo_t *info,
0066   void      *context
0067 )
0068 {
0069   Signal_count++;
0070   printf(
0071     "Signal_info: %d caught by 0x%" PRIxpthread_t " (%d) si_signo= %d si_code= %d value= %d\n",
0072     signo,
0073     pthread_self(),
0074     Signal_count,
0075     info->si_signo,
0076     info->si_code,
0077     info->si_value.sival_int
0078   );
0079   Signal_occurred = 1;
0080 }
0081 
0082 void *POSIX_Init(
0083   void *argument
0084 )
0085 {
0086   unsigned int      remaining;
0087   int               status;
0088   struct sigaction  act;
0089   sigset_t          mask;
0090   sigset_t          pending_set;
0091   sigset_t          oset;
0092   struct timespec   timeout;
0093   siginfo_t         info;
0094 
0095   TEST_BEGIN();
0096 
0097   /* set the time of day, and print our buffer in multiple ways */
0098 
0099   set_time( TM_FRIDAY, TM_MAY, 24, 96, 11, 5, 0 );
0100 
0101   /* get id of this thread */
0102 
0103   Init_id = pthread_self();
0104   printf( "Init's ID is 0x%08" PRIxpthread_t "\n", Init_id );
0105 
0106   /* generate some easy error cases */
0107 
0108   status = sigwait( NULL, NULL );
0109   if ( status != EINVAL )
0110     printf( "status = %d (%s)\n", status, strerror(status) );
0111   rtems_test_assert( status == EINVAL );
0112   puts( "Init: sigwait - EINVAL (NULL set)" );
0113 
0114   status = sigtimedwait( NULL, NULL, NULL );
0115   if ( status != -1 )
0116     printf( "status = %d\n", status );
0117   rtems_test_assert( errno == EINVAL );
0118   puts( "Init: sigwait - EINVAL (NULL set)" );
0119 
0120 /* install a signal handler for SIGUSR1 */
0121 
0122   status = sigemptyset( &act.sa_mask );
0123   rtems_test_assert( !status );
0124   printf( "Init: sigemptyset -  set= 0x%08x\n", (unsigned int) act.sa_mask );
0125 
0126   /* test sigfillset following the above sigemptyset */
0127 
0128   status = sigfillset( &act.sa_mask );
0129   rtems_test_assert( !status );
0130   printf( "Init: sigfillset -  set= 0x%08x\n", (unsigned int) act.sa_mask );
0131 
0132   /* test sigdelset */
0133 
0134   status = sigdelset( &act.sa_mask, SIGUSR1 );
0135   rtems_test_assert( !status );
0136   printf( "Init: sigdelset - delete SIGUSR1 set= 0x%08x\n",
0137       (unsigned int) act.sa_mask );
0138 
0139   /* test sigismember - FALSE */
0140 
0141   status = sigismember( &act.sa_mask, SIGUSR1 );
0142   rtems_test_assert( !status );
0143   puts( "Init: sigismember - FALSE since SIGUSR1 is not a member" );
0144 
0145   /* test sigismember - TRUE */
0146 
0147   status = sigismember( &act.sa_mask, SIGUSR2 );
0148   rtems_test_assert( status );
0149   puts( "Init: sigismember - TRUE since SIGUSR2 is a member" );
0150 
0151   /* return the set to empty */
0152 
0153   act.sa_handler = Signal_handler;
0154   act.sa_flags   = 0;
0155 
0156   sigaction( SIGUSR1, &act, NULL );
0157 
0158   /* simple signal to process */
0159 
0160   Signal_count = 0;
0161   Signal_occurred = 0;
0162 
0163   puts( "Init: send SIGUSR1 to process" );
0164   status = kill( getpid(), SIGUSR1 );
0165   rtems_test_assert( !status );
0166 
0167 /* end of install a signal handler for SIGUSR1 */
0168 
0169   Signal_occurred = 0;
0170 
0171   /* now block the signal, send it, see if it is pending, and unblock it */
0172 
0173   empty_line();
0174 
0175   status = sigemptyset( &mask );
0176   rtems_test_assert( !status );
0177 
0178   status = sigaddset( &mask, SIGUSR1 );
0179   rtems_test_assert( !status );
0180 
0181   puts( "Init: Block SIGUSR1" );
0182   act.sa_handler = Signal_handler;
0183   act.sa_flags   = 0;
0184 
0185   sigaction( SIGUSR1, &act, NULL );
0186 
0187   /* simple signal to process */
0188 
0189   Signal_count = 0;
0190   Signal_occurred = 0;
0191 
0192   puts( "Init: send SIGUSR1 to process" );
0193   status = kill( getpid(), SIGUSR1 );
0194   rtems_test_assert( !status );
0195 
0196   Signal_occurred = 0;
0197 
0198   /* now block the signal, send it, see if it is pending, and unblock it */
0199 
0200   empty_line();
0201 
0202   status = sigemptyset( &mask );
0203   rtems_test_assert( !status );
0204 
0205   status = sigaddset( &mask, SIGUSR1 );
0206   rtems_test_assert( !status );
0207 
0208   puts( "Init: Block SIGUSR1" );
0209   status = sigprocmask( SIG_BLOCK, &mask, NULL );
0210   rtems_test_assert( !status );
0211 
0212   status = sigpending( &pending_set );
0213   rtems_test_assert( !status );
0214   printf( "Init: Signals pending 0x%08x\n", (unsigned int) pending_set );
0215 
0216   puts( "Init: send SIGUSR1 to process" );
0217   status = kill( getpid(), SIGUSR1 );
0218   rtems_test_assert( !status );
0219 
0220   status = sigpending( &pending_set );
0221   rtems_test_assert( !status );
0222   printf( "Init: Signals pending 0x%08x\n", (unsigned int) pending_set );
0223 
0224   puts( "Init: Unblock SIGUSR1" );
0225   status = sigprocmask( SIG_UNBLOCK, &mask, NULL );
0226   rtems_test_assert( !status );
0227 
0228   /* now let another task get interrupted by a signal */
0229 
0230   empty_line();
0231 
0232   puts( "Init: create a thread interested in SIGUSR1" );
0233   status = pthread_create( &Task1_id, NULL, Task_1, NULL );
0234   rtems_test_assert( !status );
0235 
0236   puts( "Init: Block SIGUSR1" );
0237   status = sigprocmask( SIG_BLOCK, &mask, NULL );
0238   rtems_test_assert( !status );
0239 
0240   status = sigpending( &pending_set );
0241   rtems_test_assert( !status );
0242   printf( "Init: Signals pending 0x%08x\n", (unsigned int) pending_set );
0243 
0244   puts( "Init: sleep so the other task can block" );
0245   remaining = sleep( 1 );
0246   rtems_test_assert( !status );
0247 
0248      /* switch to task 1 */
0249 
0250   puts( "Init: send SIGUSR1 to process" );
0251   status = kill( getpid(), SIGUSR1 );
0252   rtems_test_assert( !status );
0253 
0254   status = sigpending( &pending_set );
0255   rtems_test_assert( !status );
0256   printf( "Init: Signals pending 0x%08x\n", (unsigned int) pending_set );
0257 
0258   puts( "Init: sleep so the other task can catch signal" );
0259   remaining = sleep( 1 );
0260   rtems_test_assert( !status );
0261 
0262      /* switch to task 1 */
0263 
0264   /* test alarm */
0265 
0266   empty_line();
0267 
0268   /* install a signal handler for SIGALRM and unblock it */
0269 
0270   status = sigemptyset( &act.sa_mask );
0271   rtems_test_assert( !status );
0272 
0273   act.sa_handler = Signal_handler;
0274   act.sa_flags   = 0;
0275 
0276   sigaction( SIGALRM, &act, NULL );
0277 
0278   status = sigemptyset( &mask );
0279   rtems_test_assert( !status );
0280 
0281   status = sigaddset( &mask, SIGALRM );
0282   rtems_test_assert( !status );
0283 
0284   puts( "Init: Unblock SIGALRM" );
0285   status = sigprocmask( SIG_UNBLOCK, &mask, NULL );
0286   rtems_test_assert( !status );
0287 
0288   /* schedule the alarm */
0289 
0290   puts( "Init: Firing alarm in 5 seconds" );
0291   remaining = alarm( 5 );
0292   printf( "Init: %d seconds left on previous alarm\n", status );
0293   rtems_test_assert( !status );
0294 
0295   puts( "Init: Firing alarm in 2 seconds" );
0296   remaining = alarm( 2 );
0297   printf( "Init: %d seconds left on previous alarm\n", remaining );
0298   rtems_test_assert( remaining == 5 );
0299 
0300   puts( "Init: Wait 4 seconds for alarm" );
0301   remaining = sleep( 4 );
0302   printf( "Init: %d seconds left in sleep\n", remaining );
0303 
0304   /*
0305    * sleep() uses nanosleep() internally which discards the nanoseconds part,
0306    * e.g. 1.99s -> 1s
0307    */
0308   rtems_test_assert( remaining == 1 || remaining == 2 );
0309 
0310   /* test SIG_SETMASK case and returning oset of pthread_sigmask */
0311 
0312   empty_line();
0313 
0314   status = sigemptyset( &mask );
0315   rtems_test_assert( !status );
0316 
0317   status = sigaddset( &mask, SIGUSR1 );
0318   rtems_test_assert( !status );
0319 
0320   status = sigaddset( &mask, SIGUSR2 );
0321   rtems_test_assert( !status );
0322 
0323   puts( "Init: Block SIGUSR1 and SIGUSR2 only" );
0324   status = pthread_sigmask( SIG_SETMASK, &mask, &oset );
0325   printf( "Init: Previous blocked set was 0x%08x\n", (unsigned int) oset );
0326   rtems_test_assert( !status );
0327 
0328   /* test inquiry about current blocked set with pthread_sigmask */
0329 
0330   status = pthread_sigmask( 0, NULL, &oset );
0331   printf( "Init: Current blocked set is 0x%08x\n", (unsigned int) oset );
0332   rtems_test_assert( !status );
0333 
0334   /* return blocked mask to no signals blocked */
0335 
0336   status = sigemptyset( &mask );
0337   rtems_test_assert( !status );
0338 
0339   puts( "Init: Unblock all signals" );
0340   status = pthread_sigmask( SIG_SETMASK, &mask, &oset );
0341   printf( "Init: Previous blocked set was 0x%08x\n", (unsigned int) oset );
0342   rtems_test_assert( !status );
0343 
0344   /* test sigsuspend */
0345 
0346   empty_line();
0347 
0348   puts( "Init: create a thread to send Init SIGUSR1" );
0349   status = pthread_create( &Task2_id, NULL, Task_2, NULL );
0350   rtems_test_assert( !status );
0351 
0352   status = sigemptyset( &mask );
0353   rtems_test_assert( !status );
0354 
0355   puts( "Init: sigsuspend for any signal" );
0356   status = sigsuspend( &mask );
0357   rtems_test_assert( status );
0358   printf( "Init: awakended from sigsuspend status=%08d \n", status );
0359 
0360   /* test a SIGINFO case, these are signals sent to a process only */
0361 
0362   empty_line();
0363 
0364   puts( "Init: create a thread to sent Process SIGUSR1 with SA_SIGINFO" );
0365   status = pthread_create( &Task3_id, NULL, Task_3, NULL );
0366   rtems_test_assert( !status );
0367 
0368   /* set action on SIGUSR1 to an info case */
0369   act.sa_handler   = Signal_handler;
0370   act.sa_flags     = SA_SIGINFO;
0371   act.sa_sigaction = Signal_info_handler;
0372 
0373   sigaction( SIGUSR1, &act, NULL );
0374 
0375   puts( "Init: sleep so the Task_3 can sigqueue SIGUSR1" );
0376   remaining = sleep( 1 );
0377   rtems_test_assert( !status );
0378 
0379      /* switch to task 1 */
0380 
0381   puts( "Init: sigqueue occurred" );
0382 
0383   /* Send SIGUSR1, Task_3 has issued a sigwaitinfo */
0384 
0385   status = sigemptyset( &mask );
0386   rtems_test_assert( !status );
0387 
0388   status = sigaddset( &mask, SIGUSR1 );
0389   rtems_test_assert( !status );
0390 
0391   puts( "Init: Block SIGUSR1" );
0392   status = sigprocmask( SIG_BLOCK, &mask, NULL );
0393   rtems_test_assert( !status );
0394 
0395   puts( "Init: send SIGUSR1 to process" );
0396   status = kill( getpid(), SIGUSR1 );
0397   rtems_test_assert( !status );
0398 
0399   puts( "Init: sleep so the Task_3 can receive SIGUSR1" );
0400   remaining = sleep( 1 );
0401   rtems_test_assert( !status );
0402 
0403   /* Send SIGUSR1, Task_3 has issued a sigwait */
0404 
0405   status = sigemptyset( &mask );
0406   rtems_test_assert( !status );
0407 
0408   status = sigaddset( &mask, SIGUSR1 );
0409   rtems_test_assert( !status );
0410 
0411   puts( "Init: Block SIGUSR1" );
0412   status = sigprocmask( SIG_BLOCK, &mask, NULL );
0413   rtems_test_assert( !status );
0414 
0415   puts( "Init: send SIGUSR1 to process" );
0416   status = kill( getpid(), SIGUSR1 );
0417   rtems_test_assert( !status );
0418 
0419   puts( "Init: sleep so the Task_3 can receive SIGUSR1" );
0420   remaining = sleep( 1 );
0421   rtems_test_assert( !status );
0422 
0423   /* Send SIGUSR1, Task_3 has issued a sigwaitinfo */
0424 
0425   status = sigemptyset( &mask );
0426   rtems_test_assert( !status );
0427 
0428   status = sigaddset( &mask, SIGUSR2 );
0429   rtems_test_assert( !status );
0430 
0431   puts( "Init: Block SIGUSR2" );
0432   status = sigprocmask( SIG_BLOCK, &mask, NULL );
0433   rtems_test_assert( !status );
0434 
0435   puts( "Init: send SIGUSR2 to process" );
0436   status = kill( getpid(), SIGUSR2 );
0437   rtems_test_assert( !status );
0438 
0439   puts( "Init: sleep so the Task_3 can receive SIGUSR2" );
0440   remaining = sleep( 1 );
0441   rtems_test_assert( !status );
0442 
0443   /* Suspend for signal that has already be sent */
0444 
0445   status = sigemptyset( &mask );
0446   rtems_test_assert( !status );
0447 
0448   puts( "Init: sigsuspend for any signal" );
0449   status = sigsuspend( &mask );
0450   rtems_test_assert( status );
0451   printf( "Init: awakended from sigsuspend status=%d \n", status );
0452 
0453   /* generate error cases for psignal */
0454 
0455   empty_line();
0456 
0457   status = sigemptyset( NULL );
0458   if ( status != -1 )
0459     printf( "status = %d\n", status );
0460   rtems_test_assert( errno == EINVAL );
0461   puts( "Init: sigemptyset - EINVAL (set invalid)" );
0462 
0463   status = sigfillset( NULL );
0464   if ( status != -1 )
0465     printf( "status = %d\n", status );
0466   rtems_test_assert( errno == EINVAL );
0467   puts( "Init: sigfillset - EINVAL (set invalid)" );
0468 
0469   status = sigaddset( NULL, SIGUSR1 );
0470   if ( status != -1 )
0471     printf( "status = %d\n", status );
0472   rtems_test_assert( errno == EINVAL );
0473   puts( "Init: sigaddset - EINVAL (set invalid)" );
0474 
0475   status = sigaddset( &mask, 0 );
0476   if ( status != -1 )
0477     printf( "status = %d\n", status );
0478   rtems_test_assert( errno == EINVAL );
0479   puts( "Init: sigaddset - EINVAL (signal = 0)" );
0480 
0481   status = sigaddset( &mask, 999 );
0482   if ( status != -1 )
0483     printf( "status = %d\n", status );
0484   rtems_test_assert( errno == EINVAL );
0485   puts( "Init: sigaddset - EINVAL (set invalid)" );
0486 
0487   status = sigdelset( NULL, SIGUSR1 );
0488   if ( status != -1 )
0489     printf( "status = %d\n", status );
0490   rtems_test_assert( errno == EINVAL );
0491   puts( "Init: sigdelset - EINVAL (set invalid)" );
0492 
0493   status = sigdelset( &mask, 0 );
0494   rtems_test_assert( !status );
0495   puts( "Init: sigdelset - SUCCESSFUL (signal = 0)" );
0496 
0497   status = sigdelset( &mask, 999 );
0498   if ( status != -1 )
0499     printf( "status = %d\n", status );
0500   rtems_test_assert( errno == EINVAL );
0501   puts( "Init: sigdelset - EINVAL (set invalid)" );
0502 
0503   status = sigismember( NULL, SIGUSR1 );
0504   if ( status != -1 )
0505     printf( "status = %d\n", status );
0506   rtems_test_assert( errno == EINVAL );
0507   puts( "Init: sigismember - EINVAL (set invalid)" );
0508 
0509   status = sigismember( &mask, 0 );
0510   rtems_test_assert( !status );
0511   puts( "Init: sigismember - SUCCESSFUL (signal = 0)" );
0512 
0513   status = sigismember( &mask, 999 );
0514   if ( status != -1 )
0515     printf( "status = %d\n", status );
0516   rtems_test_assert( errno == EINVAL );
0517   puts( "Init: sigismember - EINVAL (signal invalid)" );
0518 
0519   status = sigaction( 0, &act, 0 );
0520   if ( status != -1 )
0521     printf( "status = %d\n", status );
0522   rtems_test_assert( errno == EINVAL );
0523   puts( "Init: sigaction - EINVAL (signal = 0)" );
0524 
0525   status = sigaction( 999, &act, NULL );
0526   if ( status != -1 )
0527     printf( "status = %d\n", status );
0528   rtems_test_assert( errno == EINVAL );
0529   puts( "Init: sigaction - EINVAL (signal invalid)" );
0530 
0531   status = sigaction( SIGKILL, &act, NULL );
0532   if ( status != -1 )
0533     printf( "status = %d\n", status );
0534   rtems_test_assert( errno == EINVAL );
0535   puts( "Init: sigaction - EINVAL (SIGKILL)" );
0536 
0537   status = pthread_sigmask( SIG_BLOCK, NULL, NULL );
0538   if ( status != -1 )
0539     printf( "status = %d\n", status );
0540   rtems_test_assert( errno == EINVAL );
0541   puts( "Init: pthread_sigmask - EINVAL (set and oset invalid)" );
0542 
0543   status = pthread_sigmask( 999, &pending_set, NULL );
0544   if ( status != -1 )
0545     printf( "status = %d\n", status );
0546   rtems_test_assert( errno == EINVAL );
0547   puts( "Init: pthread_sigmask - EINVAL (how invalid)" );
0548 
0549   status = sigpending( NULL );
0550   if ( status != -1 )
0551     printf( "status = %d\n", status );
0552   rtems_test_assert( errno == EINVAL );
0553   puts( "Init: sigpending - EINVAL (set invalid)" );
0554 
0555   timeout.tv_nsec = -1;
0556   status = sigtimedwait( &mask, &info, &timeout );
0557   if ( status != -1 )
0558     printf( "status = %d\n", status );
0559   rtems_test_assert( errno == EINVAL );
0560   puts( "Init: pthread_sigmask - EINVAL (timout->nsec invalid < 0)" );
0561 
0562   timeout.tv_nsec = 0x7fffffff;
0563   status = sigtimedwait( &mask, &info, &timeout );
0564   if ( status != -1 )
0565     printf( "status = %d\n", status );
0566   rtems_test_assert( errno == EINVAL );
0567   puts( "Init: pthread_sigmask - EINVAL (timout->nsec invalid to large)" );
0568 
0569   status = pthread_kill( Init_id, 999 );
0570   rtems_test_assert( status == EINVAL );
0571   puts( "Init: pthread_kill - EINVAL (sig invalid)" );
0572 
0573   status = pthread_kill( Init_id, 0 );
0574   rtems_test_assert( status == EINVAL );
0575   puts( "Init: pthread_kill - EINVAL (signal = 0)" );
0576 
0577   act.sa_handler = SIG_IGN;
0578   act.sa_flags = 0;
0579   sigaction( SIGUSR2, &act, NULL );
0580   status = pthread_kill( Init_id, SIGUSR2 );
0581   rtems_test_assert( !status );
0582   puts( "Init: pthread_kill - SUCCESSFUL (signal = SIG_IGN)" );
0583 
0584   status = kill( INT_MAX, SIGUSR1 );
0585   if ( status != -1 )
0586     printf( "status = %d\n", status );
0587   rtems_test_assert( errno == ESRCH );
0588   puts( "Init: kill - ESRCH (pid invalid)" );
0589 
0590   status = kill( getpid(), 0 );
0591   if ( status != -1 )
0592     printf( "status = %d\n", status );
0593   rtems_test_assert( errno == EINVAL );
0594   puts( "Init: kill - EINVAL (signal = 0)" );
0595 
0596   status = kill( getpid(), 999 );
0597   if ( status != -1 )
0598     printf( "status = %d\n", status );
0599   rtems_test_assert( errno == EINVAL );
0600   puts( "Init: kill - EINVAL (sig invalid)" );
0601 
0602   /* exit this thread */
0603 
0604   TEST_END();
0605   rtems_test_exit( 0 );
0606 
0607   return NULL; /* just so the compiler thinks we returned something */
0608 }