[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