diff --git a/cpukit/include/aio.h b/cpukit/include/aio.h index fbea82ae08..01f7ca4436 100644 --- a/cpukit/include/aio.h +++ b/cpukit/include/aio.h @@ -36,7 +36,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ - #ifndef _AIO_H #define _AIO_H @@ -160,6 +159,7 @@ struct aiocb { * - EINVAL the starting position of the file is past the maximum offset * for this file. * - EINVAL aiocbp is a NULL pointer + * - EINVAL aiocbp->sigevent is not valid. */ int aio_read( struct aiocb *aiocbp @@ -178,6 +178,7 @@ int aio_read( * - EINVAL invalid aio_reqprio or aio_offset or aio_nbytes * - EAGAIN not enough memory * - EINVAL aiocbp is a NULL pointer + * - EINVAL aiocbp->sigevent is not valid. */ int aio_write( struct aiocb *aiocbp @@ -213,7 +214,6 @@ int aio_error( const struct aiocb *aiocbp ); - /** * @brief Retrieve Return Status of Asynchronous I/O Operation * @@ -284,6 +284,7 @@ int aio_suspend( * - EINVAL A value of op other than O_SYNC was specified. * The current implemetation only supports O_SYNC. * - EINVAL aiocbp is a NULL pointer. + * - EINVAL aiocbp->sigevent is not valid. */ int aio_fsync( int op, diff --git a/cpukit/include/rtems/posix/aio_misc.h b/cpukit/include/rtems/posix/aio_misc.h index f292000393..b4bb0c4e0a 100644 --- a/cpukit/include/rtems/posix/aio_misc.h +++ b/cpukit/include/rtems/posix/aio_misc.h @@ -41,14 +41,18 @@ #ifndef _AIO_MISC_H #define _AIO_MISC_H -#include #include +#include #include #include #include #include #include +#ifdef RTEMS_DEBUG +#include +#endif + #ifdef __cplusplus extern "C" { #endif @@ -190,6 +194,17 @@ int rtems_aio_remove_req( struct aiocb *aiocbp ); +/** + * @brief Checks the validity of a sigevent struct + * + * Checks if the pointer passed as parameter points to a valid sigevent struct. + * + * @param sigp Is a pointer to the sigevent struct to check. + * @retval 0 The struct is not valid. + * @retval 1 The struct is valid. + */ +int rtems_aio_check_sigevent( struct sigevent *sigp ); + #ifdef RTEMS_DEBUG #include diff --git a/cpukit/posix/src/aio_cancel.c b/cpukit/posix/src/aio_cancel.c index b42e3cd4cb..b682e516cd 100644 --- a/cpukit/posix/src/aio_cancel.c +++ b/cpukit/posix/src/aio_cancel.c @@ -36,7 +36,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ - #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -76,7 +75,7 @@ int aio_cancel( int fildes, struct aiocb *aiocbp ) return AIO_ALLDONE; } - AIO_printf ( "Request chain on [IQ]\n" ); + AIO_printf( "Request chain on [IQ]\n" ); rtems_chain_extract( &r_chain->next_fd ); rtems_aio_remove_fd( r_chain ); diff --git a/cpukit/posix/src/aio_fsync.c b/cpukit/posix/src/aio_fsync.c index ca4a1dc2f6..fa946da484 100644 --- a/cpukit/posix/src/aio_fsync.c +++ b/cpukit/posix/src/aio_fsync.c @@ -59,6 +59,9 @@ int aio_fsync( if ( op != O_SYNC ) rtems_set_errno_and_return_minus_one( EINVAL ); + + if ( rtems_aio_check_sigevent( &aiocbp->aio_sigevent ) == 0 ) + rtems_set_errno_and_return_minus_one( EINVAL ); mode = fcntl( aiocbp->aio_fildes, F_GETFL ); if ( diff --git a/cpukit/posix/src/aio_misc.c b/cpukit/posix/src/aio_misc.c index 14fe6b7945..66b5c19dbc 100644 --- a/cpukit/posix/src/aio_misc.c +++ b/cpukit/posix/src/aio_misc.c @@ -42,7 +42,9 @@ #include #include #include +#include #include +#include #include /** @@ -82,6 +84,31 @@ static void rtems_aio_insert_prio( rtems_aio_request *req ); +/** + * @brief Wrapper for pthread_create() call. + * + * This function serves as a wrapper with the appropriate signature for a call + * to pthread_create(). It receives a pointer to a sigevent structure that + * contains a pointer to the function to be called and the parameters to be + * passed to it. + * + * @param args Pointer to the sigevent struct containing a pointer to the + * function and its parameters. + * @return void* + */ +static void *rtems_aio_notify_function_wrapper( void *args ); + +/** + * @brief Generates a notification. + * + * The signal is generated using a sigevent struct, as defined from the + * POSIX specifications. + * + * @param sigp is a pointer to the sigevent struct that will be used + * to generate the signal + */ +static void rtems_aio_notify( struct sigevent *sigp ); + rtems_aio_queue aio_request_queue; int rtems_aio_init( void ) @@ -253,10 +280,8 @@ int rtems_aio_remove_req( rtems_chain_control *chain, struct aiocb *aiocbp ) return AIO_CANCELED; } -int -rtems_aio_enqueue( rtems_aio_request *req ) +int rtems_aio_enqueue( rtems_aio_request *req ) { - rtems_aio_request_chain *r_chain; rtems_chain_control *chain; pthread_t thid; @@ -358,9 +383,100 @@ rtems_aio_enqueue( rtems_aio_request *req ) return 0; } +int rtems_aio_check_sigevent( struct sigevent *sigp ) +{ + _Assert( sigp != NULL ); + + switch ( sigp->sigev_notify ) { + case SIGEV_NONE: + break; + + case SIGEV_SIGNAL: + if ( sigp->sigev_signo < 1 && sigp->sigev_signo > 32 ) { + return 0; + } + break; + + case SIGEV_THREAD: + if ( sigp->sigev_notify_function == NULL ) { + return 0; + } + break; + + default: + return 0; + } + + return 1; +} + +static void *rtems_aio_notify_function_wrapper( void *args ) +{ + struct sigevent *sig = ( struct sigevent * ) args; + void (*notify_function)( union sigval ) = sig->sigev_notify_function; + union sigval param = ( union sigval ) sig->sigev_value; + + notify_function( param ); + + pthread_exit( NULL ); +} + +static void rtems_aio_notify( struct sigevent *sigp ) +{ +#ifdef RTEMS_POSIX_API + + int result; +#ifndef RTEMS_DEBUG + (void) result; +#endif + + _Assert( sigp != NULL ); + + switch ( sigp->sigev_notify ) { + case SIGEV_SIGNAL: + result = sigqueue( + getpid(), + sigp->sigev_signo, + sigp->sigev_value + ); + _Assert( result == 0 ); + break; + + case SIGEV_THREAD: + pthread_t thread; + pthread_attr_t attr; + pthread_attr_t *attrp = sigp->sigev_notify_attributes; + + if ( attrp == NULL ) { + attrp = &attr; + + result = pthread_attr_init( attrp ); + _Assert( result == 0 ); + + result = pthread_attr_setdetachstate( + attrp, + PTHREAD_CREATE_DETACHED + ); + _Assert( result == 0 ); + } + + result = pthread_create( + &thread, + attrp, + rtems_aio_notify_function_wrapper, + sigp + ); + _Assert( result == 0 ); + break; + } + +#else + (void) sigp; +#endif +} + static void *rtems_aio_handle( void *arg ) { - rtems_aio_request_chain *r_chain = arg; rtems_aio_request *req; rtems_chain_control *chain; @@ -525,6 +641,8 @@ static void rtems_aio_handle_helper( rtems_aio_request *req ) result = -1; } + rtems_aio_notify( &req->aiocbp->aio_sigevent ); + if ( result < 0 ) { req->aiocbp->return_value = -1; req->aiocbp->error_code = errno; diff --git a/cpukit/posix/src/aio_read.c b/cpukit/posix/src/aio_read.c index cf206d5317..876042bfd8 100644 --- a/cpukit/posix/src/aio_read.c +++ b/cpukit/posix/src/aio_read.c @@ -71,6 +71,9 @@ int aio_read( struct aiocb *aiocbp ) if ( aiocbp->aio_offset < 0 ) rtems_set_errno_and_return_minus_one( EINVAL ); + if ( rtems_aio_check_sigevent( &aiocbp->aio_sigevent ) == 0 ) + rtems_set_errno_and_return_minus_one( EINVAL ); + req = malloc( sizeof( rtems_aio_request ) ); if ( req == NULL ) rtems_set_errno_and_return_minus_one( EAGAIN ); diff --git a/cpukit/posix/src/aio_write.c b/cpukit/posix/src/aio_write.c index 27992e7694..3f7999ef93 100644 --- a/cpukit/posix/src/aio_write.c +++ b/cpukit/posix/src/aio_write.c @@ -45,8 +45,7 @@ #include #include -int -aio_write( struct aiocb *aiocbp ) +int aio_write( struct aiocb *aiocbp ) { rtems_aio_request *req; int mode; @@ -69,6 +68,9 @@ aio_write( struct aiocb *aiocbp ) if ( aiocbp->aio_offset < 0 ) rtems_set_errno_and_return_minus_one( EINVAL ); + if ( rtems_aio_check_sigevent( &aiocbp->aio_sigevent ) == 0 ) + rtems_set_errno_and_return_minus_one( EINVAL ); + req = malloc( sizeof( rtems_aio_request ) ); if ( req == NULL ) rtems_set_errno_and_return_minus_one( EAGAIN ); diff --git a/spec/build/testsuites/psxtests/grp.yml b/spec/build/testsuites/psxtests/grp.yml index fe6a707b99..fe69ce1b6d 100644 --- a/spec/build/testsuites/psxtests/grp.yml +++ b/spec/build/testsuites/psxtests/grp.yml @@ -61,6 +61,8 @@ links: uid: psxaio02 - role: build-dependency uid: psxaio03 +- role: build-dependency + uid: psxaio04 - role: build-dependency uid: psxalarm01 - role: build-dependency diff --git a/spec/build/testsuites/psxtests/psxaio04.yml b/spec/build/testsuites/psxtests/psxaio04.yml new file mode 100644 index 0000000000..09b8fbe126 --- /dev/null +++ b/spec/build/testsuites/psxtests/psxaio04.yml @@ -0,0 +1,20 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +build-type: test-program +cflags: [] +copyrights: +- Copyright (C) 2024 Alessandro Nardin +cppflags: [] +cxxflags: [] +enabled-by: +- RTEMS_POSIX_API +features: c cprogram +includes: [] +ldflags: [] +links: [] +source: +- testsuites/psxtests/psxaio04/init.c +stlib: [] +target: testsuites/psxtests/psxaio04.exe +type: build +use-after: [] +use-before: [] diff --git a/testsuites/psxtests/psxaio01/init.c b/testsuites/psxtests/psxaio01/init.c index f6c29b39cc..f5a3545e00 100644 --- a/testsuites/psxtests/psxaio01/init.c +++ b/testsuites/psxtests/psxaio01/init.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include @@ -61,13 +60,14 @@ struct aiocb *create_aiocb( int fd ) aiocbp->aio_offset = 0; aiocbp->aio_reqprio = 0; aiocbp->aio_fildes = fd; + aiocbp->aio_sigevent.sigev_notify = SIGEV_NONE; return aiocbp; } void free_aiocb( struct aiocb *aiocbp ) { - free ((char*) aiocbp->aio_buf); - free (aiocbp); + free( (void*) aiocbp->aio_buf ); + free( aiocbp ); } void *POSIX_Init( void *argument ) diff --git a/testsuites/psxtests/psxaio01/system.h b/testsuites/psxtests/psxaio01/system.h index 70224470e9..9427ae343e 100644 --- a/testsuites/psxtests/psxaio01/system.h +++ b/testsuites/psxtests/psxaio01/system.h @@ -32,7 +32,7 @@ #include #include -void *POSIX_Init (void *argument); +void *POSIX_Init( void *argument ); /* configuration information */ @@ -42,7 +42,7 @@ void *POSIX_Init (void *argument); #define CONFIGURE_MAXIMUM_TASKS 20 #define CONFIGURE_MAXIMUM_SEMAPHORES 20 #define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 20 -#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 20 +#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 20 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION @@ -50,8 +50,8 @@ void *POSIX_Init (void *argument); #define CONFIGURE_MAXIMUM_POSIX_KEYS 10 #define CONFIGURE_POSIX_INIT_THREAD_TABLE -#define CONFIGURE_EXTRA_TASK_STACKS (10 * RTEMS_MINIMUM_STACK_SIZE) -#define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE (10 * RTEMS_MINIMUM_STACK_SIZE) +#define CONFIGURE_EXTRA_TASK_STACKS ( 10 * RTEMS_MINIMUM_STACK_SIZE ) +#define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE ( 10 * RTEMS_MINIMUM_STACK_SIZE ) #include diff --git a/testsuites/psxtests/psxaio02/init.c b/testsuites/psxtests/psxaio02/init.c index 0b416221c8..518e861b59 100644 --- a/testsuites/psxtests/psxaio02/init.c +++ b/testsuites/psxtests/psxaio02/init.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -45,38 +44,35 @@ const char rtems_test_name[] = "PSXAIO 2"; /* forward declarations to avoid warnings */ -struct aiocb *create_aiocb(int fd); -void free_aiocb(struct aiocb *aiocbp); +struct aiocb *create_aiocb( int fd ); +void free_aiocb( struct aiocb *aiocbp ); #define BUFSIZE 32 #define FD_COUNT 10 #define WRONG_FD 666 -struct aiocb * -create_aiocb (int fd) +struct aiocb *create_aiocb( int fd ) { struct aiocb *aiocbp; - aiocbp = malloc (sizeof (struct aiocb)); - memset (aiocbp, 0, sizeof (struct aiocb)); - aiocbp->aio_buf = malloc (BUFSIZE * sizeof (char)); + aiocbp = malloc( sizeof( struct aiocb ) ); + memset( aiocbp, 0, sizeof( struct aiocb ) ); + aiocbp->aio_buf = malloc( BUFSIZE * sizeof( char ) ); aiocbp->aio_nbytes = BUFSIZE; aiocbp->aio_offset = 0; aiocbp->aio_reqprio = 0; aiocbp->aio_fildes = fd; - + aiocbp->aio_sigevent.sigev_notify = SIGEV_NONE; return aiocbp; } -void -free_aiocb (struct aiocb *aiocbp) +void free_aiocb( struct aiocb *aiocbp ) { - free ((char*) aiocbp->aio_buf); - free (aiocbp); + free( (void*) aiocbp->aio_buf ); + free( aiocbp ); } -void * -POSIX_Init (void *argument) +void *POSIX_Init( void *argument ) { int fd[FD_COUNT]; struct aiocb *aiocbp[FD_COUNT+1]; @@ -84,123 +80,111 @@ POSIX_Init (void *argument) char filename[BUFSIZE]; struct sched_param param; - status = rtems_aio_init (); - rtems_test_assert (status == 0); + status = rtems_aio_init(); + rtems_test_assert( status == 0 ); param.sched_priority = 30; - status = pthread_setschedparam (pthread_self(), policy, ¶m); - rtems_test_assert (status == 0); + status = pthread_setschedparam( + pthread_self(), + policy, ¶m + ); + rtems_test_assert( status == 0 ); - status = mkdir ("/tmp", S_IRWXU); - rtems_test_assert (!status); + status = mkdir( "/tmp", S_IRWXU ); + rtems_test_assert( !status ); TEST_BEGIN(); - puts ("Init: Open files"); + puts( "Init: Open files" ); - for (i=0; iaio_fildes != fildes"); - status = aio_cancel (fd[4],aiocbp[4]); - rtems_test_assert (status == -1 ); + status = aio_cancel( fd[4], aiocbp[4] ); + rtems_test_assert( status == -1 ); - puts ("Init: [NONE] aio_cancel FD on [IQ], aiocb not on chain"); - aiocbp[10] = create_aiocb (fd[9]); - status = aio_cancel (fd[9], aiocbp[10]); - rtems_test_assert (status == -1); + aiocbp[10] = create_aiocb( fd[9] ); + status = aio_cancel( fd[9], aiocbp[10] ); + rtems_test_assert( status == -1 ); - puts ("Init: [IQ] aio_cancel 6th file only one request"); - status = aio_cancel (fd[5], aiocbp[6]); - rtems_test_assert (status == AIO_CANCELED); + status = aio_cancel( fd[5], aiocbp[6] ); + rtems_test_assert( status == AIO_CANCELED ); - puts ("Init: [WQ] aio_cancel 1st file only one request"); - status = aio_cancel (fd[0], aiocbp[9]); - rtems_test_assert (status == AIO_CANCELED); + status = aio_cancel( fd[0], aiocbp[9] ); + rtems_test_assert( status == AIO_CANCELED ); - puts ("Init: [NONE] aio_cancel empty [IQ]"); - status = aio_cancel (fd[5], aiocbp[6]); - rtems_test_assert (status == AIO_ALLDONE); + status = aio_cancel( fd[5], aiocbp[6] ); + rtems_test_assert( status == AIO_ALLDONE ); TEST_END(); - for (i = 0; i < FD_COUNT; i++) + for ( i = 0; i < FD_COUNT; i++ ) { - close (fd[i]); - free_aiocb (aiocbp[i]); + close( fd[i] ); + free_aiocb( aiocbp[i] ); } - free_aiocb (aiocbp[i]); - rtems_test_exit (0); + free_aiocb( aiocbp[i] ); + rtems_test_exit( 0 ); return NULL; diff --git a/testsuites/psxtests/psxaio02/psxaio02.scn b/testsuites/psxtests/psxaio02/psxaio02.scn index 8c474c4701..fc46dbf193 100644 --- a/testsuites/psxtests/psxaio02/psxaio02.scn +++ b/testsuites/psxtests/psxaio02/psxaio02.scn @@ -1,22 +1,2 @@ *** POSIX AIO TEST 02 *** -Init: Open files -Init: [WQ] aio_write on 1st file -Init: [WQ] aio_write on 2nd file -Init: [WQ] aio_read on 2nd file add by priority -Init: [WQ] aio_write on 3rd file -Init: [WQ] aio_write on 4th file -Init: [WQ] aio_write on 5th file -- [WQ] full -Init: [IQ] aio_write on 6th file -Init: [IQ] aio_write on 7th file -Init: [IQ] aio_read on 7th file add by priority -Init: [WQ] aio_sync on 1st file add by priority -Init: [NONE] aio_cancel aiocbp=NULL and invalid fildes -Init: [NONE] aio_cancel aiocbp=NULL valid fildes not in queue -Init: [WQ] aio_cancel aiocbp=NULL fildes=fd[1] -Init: [IQ] aio_cancel aiocbp=NULL fildes=fd[6] -Init: [NONE] aio_cancel aiocbp->aio_fildes != fildes -Init: [NONE] aio_cancel FD on [IQ], aiocb not on chain -Init: [IQ] aio_cancel 6th file only one request -Init: [WQ] aio_cancel 1st file only one request -Init: [NONE] aio_cancel empty [IQ] *** END OF POSIX AIO TEST 02 *** diff --git a/testsuites/psxtests/psxaio02/system.h b/testsuites/psxtests/psxaio02/system.h index 70224470e9..5d7372ca82 100644 --- a/testsuites/psxtests/psxaio02/system.h +++ b/testsuites/psxtests/psxaio02/system.h @@ -32,7 +32,7 @@ #include #include -void *POSIX_Init (void *argument); +void *POSIX_Init( void *argument ); /* configuration information */ @@ -42,7 +42,7 @@ void *POSIX_Init (void *argument); #define CONFIGURE_MAXIMUM_TASKS 20 #define CONFIGURE_MAXIMUM_SEMAPHORES 20 #define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 20 -#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 20 +#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 20 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION diff --git a/testsuites/psxtests/psxaio03/init.c b/testsuites/psxtests/psxaio03/init.c index 082937ea4a..1c1b71f8fb 100644 --- a/testsuites/psxtests/psxaio03/init.c +++ b/testsuites/psxtests/psxaio03/init.c @@ -26,7 +26,7 @@ * */ -#if !defined(OPERATION_COUNT) +#if !defined( OPERATION_COUNT ) #define OPERATION_COUNT 100 #endif @@ -50,38 +50,34 @@ const char rtems_test_name[] = "PSXAIO 3"; /* forward declarations to avoid warnings */ -struct aiocb *create_aiocb(int fd); -void free_aiocb(struct aiocb *aiocbp); +struct aiocb *create_aiocb( int fd ); +void free_aiocb( struct aiocb *aiocbp ); #define FD_COUNT 6 #define BUFSIZE 128 -struct aiocb * -create_aiocb (int fd) +struct aiocb *create_aiocb( int fd ) { struct aiocb *aiocbp; - aiocbp = malloc (sizeof (struct aiocb)); - memset (aiocbp, 0, sizeof (struct aiocb)); - aiocbp->aio_buf = malloc (BUFSIZE * sizeof (char)); + aiocbp = malloc( sizeof( struct aiocb ) ); + memset( aiocbp, 0, sizeof( struct aiocb ) ); + aiocbp->aio_buf = malloc( BUFSIZE * sizeof( char ) ); aiocbp->aio_nbytes = BUFSIZE; aiocbp->aio_offset = 0; aiocbp->aio_reqprio = 0; aiocbp->aio_fildes = fd; - + aiocbp->aio_sigevent.sigev_notify = SIGEV_NONE; return aiocbp; } -void -free_aiocb (struct aiocb *aiocbp) +void free_aiocb( struct aiocb *aiocbp ) { - free ((char*) aiocbp->aio_buf); - free (aiocbp); + free( (void*) aiocbp->aio_buf ); + free( aiocbp ); } - -void * -POSIX_Init (void *argument) +void *POSIX_Init( void *argument ) { int fd[FD_COUNT]; struct aiocb *aiocbp[FD_COUNT+1]; @@ -89,79 +85,74 @@ POSIX_Init (void *argument) char filename[BUFSIZE]; struct sched_param param; - status = rtems_aio_init (); - rtems_test_assert (status == 0); + status = rtems_aio_init(); + rtems_test_assert( status == 0 ); param.sched_priority = 30; - status = pthread_setschedparam (pthread_self(), policy, ¶m); - rtems_test_assert (status == 0); + status = pthread_setschedparam( + pthread_self(), + policy, + ¶m + ); + rtems_test_assert( status == 0 ); - status = mkdir ("/tmp", S_IRWXU); - rtems_test_assert (!status); + status = mkdir( "/tmp", S_IRWXU ); + rtems_test_assert( !status ); TEST_BEGIN(); - puts (" Init: Open files "); - - for (i=0; i #include -void *POSIX_Init (void *argument); +void *POSIX_Init( void *argument ); /* configuration information */ @@ -26,7 +26,7 @@ void *POSIX_Init (void *argument); #define CONFIGURE_MAXIMUM_TASKS 10 #define CONFIGURE_MAXIMUM_SEMAPHORES 10 #define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 10 -#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 10 +#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 10 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION @@ -34,8 +34,8 @@ void *POSIX_Init (void *argument); #define CONFIGURE_MAXIMUM_POSIX_KEYS 10 #define CONFIGURE_POSIX_INIT_THREAD_TABLE -#define CONFIGURE_EXTRA_TASK_STACKS (5 * RTEMS_MINIMUM_STACK_SIZE) -#define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE (5 * RTEMS_MINIMUM_STACK_SIZE) +#define CONFIGURE_EXTRA_TASK_STACKS ( 5 * RTEMS_MINIMUM_STACK_SIZE ) +#define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE ( 5 * RTEMS_MINIMUM_STACK_SIZE ) #include diff --git a/testsuites/psxtests/psxaio04/init.c b/testsuites/psxtests/psxaio04/init.c new file mode 100644 index 0000000000..80b1293ef0 --- /dev/null +++ b/testsuites/psxtests/psxaio04/init.c @@ -0,0 +1,151 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* + * Copyright 2024, Alessandro Nardin + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define CONFIGURE_INIT +#include "system.h" +#include +#include "tmacros.h" +#include +#include +#include +#include +#include +#include +#include + +const char rtems_test_name[] = "PSXAIO 4"; + +#define BUFSIZE 512 +#define WRONG_FD 404 + +/* forward declarations to avoid warnings */ +struct aiocb *create_aiocb( int fd ); +void free_aiocb( struct aiocb *aiocbp ); +void notify( union sigval sig ); + +struct aiocb *create_aiocb( int fd ) +{ + struct aiocb *aiocbp; + + aiocbp = malloc( sizeof( struct aiocb ) ); + memset( aiocbp, 0, sizeof( struct aiocb ) ); + aiocbp->aio_buf = malloc( BUFSIZE * sizeof( char ) ); + aiocbp->aio_nbytes = BUFSIZE; + aiocbp->aio_offset = 0; + aiocbp->aio_reqprio = 0; + aiocbp->aio_fildes = fd; + aiocbp->aio_sigevent.sigev_notify = SIGEV_NONE; + return aiocbp; +} + +void free_aiocb( struct aiocb *aiocbp ) +{ + free( (void*) aiocbp->aio_buf ); + free( aiocbp ); +} + +void notify( union sigval sig ) +{ + kill( getpid(), sig.sival_int ); +} + +void *POSIX_Init( void *argument ) +{ + int fd, status, received_signal, sig; + struct aiocb *aiocbp; + sigset_t sig_set; + sig = SIGUSR1; + + rtems_aio_init(); + + status = mkdir( "/tmp", S_IRWXU ); + rtems_test_assert( !status ); + + fd = open( + "/tmp/aio_fildes", + O_RDWR|O_CREAT, + S_IRWXU|S_IRWXG|S_IRWXO + ); + rtems_test_assert( fd != -1 ); + + TEST_BEGIN(); + + aiocbp = create_aiocb( fd ); + aiocbp->aio_sigevent.sigev_notify = SIGEV_SIGNAL; + aiocbp->aio_sigevent.sigev_signo = SIGUSR1; + + status =sigemptyset( &sig_set ); + rtems_test_assert( status == 0 ); + + status =sigaddset( &sig_set, sig ); + rtems_test_assert( status == 0 ); + + status = sigprocmask( SIG_BLOCK, &sig_set, NULL ); + rtems_test_assert( status == 0 ); + + status = aio_write( aiocbp ); + rtems_test_assert( status == 0 ); + + status = sigwait( &sig_set, &received_signal ); + rtems_test_assert( status == 0 ); + + rtems_test_assert( received_signal == sig ); + + aiocbp = create_aiocb( fd ); + aiocbp->aio_sigevent.sigev_notify = SIGEV_THREAD; + aiocbp->aio_sigevent.sigev_notify_attributes = NULL; + aiocbp->aio_sigevent.sigev_notify_function = ¬ify; + aiocbp->aio_sigevent.sigev_value.sival_int = sig; + + status =sigemptyset( &sig_set ); + rtems_test_assert( status == 0 ); + + status =sigaddset( &sig_set, sig ); + rtems_test_assert( status == 0 ); + + status = sigprocmask( SIG_BLOCK, &sig_set, NULL ); + rtems_test_assert( status == 0 ); + + status = aio_write( aiocbp ); + rtems_test_assert( status == 0 ); + + status = sigwait( &sig_set, &received_signal ); + rtems_test_assert( status == 0 ); + + rtems_test_assert( received_signal == sig ); + + TEST_END(); + + close( fd ); + rtems_test_exit( 0 ); + + return NULL; +} diff --git a/testsuites/psxtests/psxaio04/psxaio04.scn b/testsuites/psxtests/psxaio04/psxaio04.scn new file mode 100644 index 0000000000..b1139338fc --- /dev/null +++ b/testsuites/psxtests/psxaio04/psxaio04.scn @@ -0,0 +1,2 @@ +*** BEGIN OF TEST PSXAIO 4 *** +*** END OF TEST PSXAIO 4 *** \ No newline at end of file diff --git a/testsuites/psxtests/psxaio04/system.h b/testsuites/psxtests/psxaio04/system.h new file mode 100644 index 0000000000..2b2036bc91 --- /dev/null +++ b/testsuites/psxtests/psxaio04/system.h @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* + * Copyright 2024, Alessandro Nardin + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* functions */ + +#include +#include +#include +#include + +void *POSIX_Init( void *argument ); + +/* configuration information */ + +#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER + +#define CONFIGURE_MAXIMUM_TASKS 20 +#define CONFIGURE_MAXIMUM_SEMAPHORES 20 +#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 20 +#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 20 + +#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION + +#define CONFIGURE_MAXIMUM_POSIX_THREADS 10 +#define CONFIGURE_MAXIMUM_POSIX_KEYS 10 + +#define CONFIGURE_POSIX_INIT_THREAD_TABLE +#define CONFIGURE_EXTRA_TASK_STACKS ( 10 * RTEMS_MINIMUM_STACK_SIZE ) +#define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE ( 10 * RTEMS_MINIMUM_STACK_SIZE ) + +#include + +/* global variables */ +TEST_EXTERN pthread_t Init_id; + +/* end of include file */