[PATCH 2/2] posix: simplify paths and check errors in shm_open
Gedare Bloom
gedare at rtems.org
Fri Aug 26 16:23:26 UTC 2016
I have added some error checks for the heap-backed shm implementation,
and simplified the control flow to get all error checking done before
allocating memory. I will eventually send a v2 patch series, but I
wanted to show these self-contained fixes. I am looking into mmap
support presently.
On Fri, Aug 26, 2016 at 12:17 PM, Gedare Bloom <gedare at rtems.org> wrote:
> ---
> cpukit/posix/src/shmopen.c | 84 +++++++++++++++++++++++++++-------------------
> 1 file changed, 49 insertions(+), 35 deletions(-)
>
> diff --git a/cpukit/posix/src/shmopen.c b/cpukit/posix/src/shmopen.c
> index 7823785..cbea88c 100644
> --- a/cpukit/posix/src/shmopen.c
> +++ b/cpukit/posix/src/shmopen.c
> @@ -39,6 +39,7 @@ static int shm_ftruncate( rtems_libio_t *iop, off_t length )
> err = (*shm->shm_object.ops->object_resize)( shm, length );
>
> if ( err != 0 ) {
> + _POSIX_Shm_Release( shm, &queue_context );
> rtems_set_errno_and_return_minus_one( err );
> }
>
> @@ -60,6 +61,18 @@ static inline POSIX_Shm_Control *shm_allocate(
> char *name;
> struct timeval tv;
>
> + /* Reject any name without a leading slash. */
> + if ( name_arg[0] != '/' ) {
> + *error = EINVAL;
> + return NULL;
> + }
> +
> + /* Only create the object if requested. */
> + if ( ( oflag & O_CREAT ) != O_CREAT ) {
> + *error = ENOENT;
> + return NULL;
> + }
> +
> name = _Workspace_String_duplicate( name_arg, name_len );
> if ( name == NULL ) {
> *error = ENOSPC;
> @@ -102,16 +115,8 @@ static inline bool shm_access_ok( POSIX_Shm_Control *shm, int oflag )
> return rtems_filesystem_check_access( flags, shm->mode, shm->uid, shm->gid );
> }
>
> -int shm_open( const char *name, int oflag, mode_t mode )
> +static inline int shm_check_oflag( int oflag )
> {
> - int err = 0;
> - int fd;
> - rtems_libio_t *iop;
> - POSIX_Shm_Control *shm;
> - size_t len;
> - Objects_Get_by_name_error obj_err;
> - Thread_queue_Context queue_context;
> -
> if ( ( oflag & O_ACCMODE ) != O_RDONLY && ( oflag & O_ACCMODE ) != O_RDWR ) {
> rtems_set_errno_and_return_minus_one( EACCES );
> }
> @@ -123,8 +128,28 @@ int shm_open( const char *name, int oflag, mode_t mode )
> if ( ( oflag & O_TRUNC ) != 0 && ( oflag & O_ACCMODE ) != O_RDWR ) {
> rtems_set_errno_and_return_minus_one( EACCES );
> }
> + return 0;
> +}
> +
> +int shm_open( const char *name, int oflag, mode_t mode )
> +{
> + int err = 0;
> + int fd;
> + rtems_libio_t *iop;
> + POSIX_Shm_Control *shm;
> + size_t len;
> + Objects_Get_by_name_error obj_err;
> + Thread_queue_Context queue_context;
> +
> + if ( shm_check_oflag( oflag ) != 0 ) {
> + return -1;
> + }
>
> /* TODO see if the object exists, shms available */
> + iop = rtems_libio_allocate();
> + if ( iop == NULL ) {
> + rtems_set_errno_and_return_minus_one( EMFILE );
> + }
>
> _Objects_Allocator_lock();
> shm = _POSIX_Shm_Get_by_name( name, &len, &obj_err );
> @@ -141,44 +166,33 @@ int shm_open( const char *name, int oflag, mode_t mode )
>
> case OBJECTS_GET_BY_NAME_NO_OBJECT:
> default:
> - /* Reject any name without a leading slash. */
> - if ( name[0] != '/' ) {
> - err = EINVAL;
> - break;
> - }
> -
> - if ( ( oflag & O_CREAT ) != O_CREAT ) {
> - err = ENOENT;
> - break;
> - }
> -
> shm = shm_allocate(name, len, oflag, mode, &err);
> break;
> }
> _Objects_Allocator_unlock();
> - if ( err != 0 ) {
> - rtems_set_errno_and_return_minus_one( err );
> - }
> } else { /* shm exists */
> _Objects_Allocator_unlock();
> if ( ( oflag & ( O_EXCL | O_CREAT ) ) == ( O_EXCL | O_CREAT ) ) {
> - rtems_set_errno_and_return_minus_one( EEXIST );
> - }
> - if ( !shm_access_ok( shm, oflag ) ) {
> - rtems_set_errno_and_return_minus_one( EACCES );
> + /* Request to create failed. */
> + err = EEXIST;
> + } else if ( !shm_access_ok( shm, oflag ) ) {
> + err = EACCES;
> + } else {
> + _POSIX_Shm_Acquire_critical( shm, &queue_context );
> + ++shm->reference_count;
> + _POSIX_Shm_Release( shm, &queue_context );
> }
> - _POSIX_Shm_Acquire_critical( shm, &queue_context );
> - ++shm->reference_count;
> - _POSIX_Shm_Release( shm, &queue_context );
> }
> -
> - iop = rtems_libio_allocate();
> - if ( iop == NULL ) {
> - rtems_set_errno_and_return_minus_one( EMFILE );
> + if ( err != 0 ) {
> + rtems_libio_free( iop );
> + rtems_set_errno_and_return_minus_one( err );
> }
> +
> if ( oflag & O_TRUNC ) {
> - shm_ftruncate( iop, 0 );
> + err = shm_ftruncate( iop, 0 );
> + (void) err; /* ignore truncate error */
> }
> +
> fd = rtems_libio_iop_to_descriptor( iop );
> iop->flags |= LIBIO_FLAGS_CLOSE_ON_EXEC;
> if ( oflag & O_RDONLY ) {
> --
> 1.9.1
>
More information about the devel
mailing list