[PATCH 2/2] posix: simplify paths and check errors in shm_open

Gedare Bloom gedare at rtems.org
Fri Aug 26 16:17:43 UTC 2016


---
 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