Exemple #1
0
/*
 *  This method will set the object name based upon the user string.
 *  If the object class uses 32-bit names, then only the first 4 bytes
 *  of the string will be used.
 */
rtems_status_code rtems_object_set_name(
  rtems_id       id,
  const char    *name
)
{
  Objects_Information *information;
  Objects_Control     *the_object;
  Objects_Id           tmpId;

  if ( !name )
    return RTEMS_INVALID_ADDRESS;

  tmpId = (id == OBJECTS_ID_OF_SELF) ? rtems_task_self() : id;

  information  = _Objects_Get_information_id( tmpId );
  if ( !information )
    return RTEMS_INVALID_ID;

  _Objects_Allocator_lock();
  the_object = _Objects_Get_no_protection( tmpId, information );

  if ( the_object == NULL ) {
    _Objects_Allocator_unlock();
    return RTEMS_INVALID_ID;
  }

  _Objects_Set_name( information, the_object, name );
  _Objects_Allocator_unlock();
  return RTEMS_SUCCESSFUL;
}
int mq_close(
    mqd_t  mqdes
)
{
    POSIX_Message_queue_Control *the_mq;
    Thread_queue_Context         queue_context;

    _Objects_Allocator_lock();
    the_mq = _POSIX_Message_queue_Get( mqdes, &queue_context );

    if ( the_mq == NULL ) {
        _Objects_Allocator_unlock();
        rtems_set_errno_and_return_minus_one( EBADF );
    }

    _CORE_message_queue_Acquire_critical(
        &the_mq->Message_queue,
        &queue_context
    );

    if ( the_mq->open_count == 0 ) {
        _CORE_message_queue_Release( &the_mq->Message_queue, &queue_context );
        _Objects_Allocator_unlock();
        rtems_set_errno_and_return_minus_one( EBADF );
    }

    the_mq->open_count -= 1;
    _POSIX_Message_queue_Delete( the_mq, &queue_context );

    _Objects_Allocator_unlock();
    return 0;
}
Exemple #3
0
const void *
rtems_monitor_mpci_next(
    void                  *object_info,
    rtems_monitor_mpci_t  *canonical_mpci,
    rtems_id              *next_id
)
{
    const rtems_configuration_table *c = &Configuration;
    int n = rtems_object_id_get_index(*next_id);

    if (n >= 1)
        goto failed;

    if ( ! c->User_multiprocessing_table)
        goto failed;

    _Objects_Allocator_lock();

    *next_id += 1;
    return (void *) c;

failed:
    *next_id = RTEMS_OBJECT_ID_FINAL;
    return 0;
}
Exemple #4
0
/*
 *  17.1.3 Thread-Specific Data Key Deletion, P1003.1c/Draft 10, p. 167
 */
int pthread_key_delete(
  pthread_key_t  key
)
{
  POSIX_Keys_Control *the_key;
  Objects_Locations   location;

  _Objects_Allocator_lock();
  the_key = _POSIX_Keys_Get( key, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      _POSIX_Keys_Free_memory( the_key );

      /*
       *  NOTE:  The destructor is not called and it is the responsibility
       *         of the application to free the memory.
       */
      _POSIX_Keys_Free( the_key );
      _Objects_Put(&the_key->Object);
      _Objects_Allocator_unlock();
      return 0;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:   /* should never happen */
#endif
    case OBJECTS_ERROR:
      break;
  }

  _Objects_Allocator_unlock();

  return EINVAL;
}
Exemple #5
0
int sem_unlink(
  const char *name
)
{
  int                      status;
  POSIX_Semaphore_Control *the_semaphore;
  Objects_Id               the_semaphore_id;
  size_t                   name_len;

  _Objects_Allocator_lock();
  _Thread_Disable_dispatch();

  status = _POSIX_Semaphore_Name_to_id( name, &the_semaphore_id, &name_len );
  if ( status != 0 ) {
    _Thread_Enable_dispatch();
    _Objects_Allocator_unlock();
    rtems_set_errno_and_return_minus_one( status );
  }

  the_semaphore = (POSIX_Semaphore_Control *) _Objects_Get_local_object(
    &_POSIX_Semaphore_Information,
    _Objects_Get_index( the_semaphore_id )
  );

  the_semaphore->linked = false;
  _POSIX_Semaphore_Namespace_remove( the_semaphore );
  _POSIX_Semaphore_Delete( the_semaphore );

  _Thread_Enable_dispatch();
  _Objects_Allocator_unlock();

  return 0;
}
Exemple #6
0
static int shm_mmap(
  rtems_libio_t *iop,
  void** addr,
  size_t len,
  int prot,
  off_t off
)
{
  POSIX_Shm_Control *shm = iop_to_shm( iop );

  _Objects_Allocator_lock();

  *addr = (*shm->shm_object.ops->object_mmap)( &shm->shm_object, len, prot, off);
  if ( *addr != NULL ) {
    /* Keep a reference in the shared memory to prevent its removal. */
    ++shm->reference_count;

    /* Update atime */
    _POSIX_Shm_Update_atime(shm);
  } else {
    _Objects_Allocator_unlock();
    rtems_set_errno_and_return_minus_one( ENOMEM );
  }

  _Objects_Allocator_unlock();

  return 0;
}
Exemple #7
0
int sem_init(
  sem_t         *sem,
  int            pshared,
  unsigned int   value
)
{
  int                        status;
  POSIX_Semaphore_Control   *the_semaphore;

  if ( !sem )
    rtems_set_errno_and_return_minus_one( EINVAL );

  _Objects_Allocator_lock();
  status = _POSIX_Semaphore_Create_support(
    NULL,
    0,
    pshared,
    value,
    &the_semaphore
  );
  _Objects_Allocator_unlock();

  if ( status != -1 )
    *sem = the_semaphore->Object.id;

  return status;
}
Exemple #8
0
rtems_status_code rtems_port_delete(
  rtems_id id
)
{
  Dual_ported_memory_Control          *the_port;
  Objects_Locations                    location;

  _Objects_Allocator_lock();
  the_port = _Dual_ported_memory_Get( id, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      _Objects_Close( &_Dual_ported_memory_Information, &the_port->Object );
      _Objects_Put( &the_port->Object );
      _Dual_ported_memory_Free( the_port );
      _Objects_Allocator_unlock();
      return RTEMS_SUCCESSFUL;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:        /* this error cannot be returned */
#endif
    case OBJECTS_ERROR:
      break;
  }

  _Objects_Allocator_unlock();

  return RTEMS_INVALID_ID;
}
Exemple #9
0
int pthread_getname_np( pthread_t thread, char *name, size_t len )
{
  Thread_Control   *the_thread;
  ISR_lock_Context  lock_context;
  size_t            actual_len;

  _Objects_Allocator_lock();
  the_thread = _Thread_Get( thread, &lock_context );

  if ( the_thread == NULL ) {
    _Objects_Allocator_unlock();
    strlcpy(name, "", len);
    return ESRCH;
  }

  _ISR_lock_ISR_enable( &lock_context );
  actual_len = _Thread_Get_name( the_thread, name, len );
  _Objects_Allocator_unlock();

  if ( actual_len >= len ) {
    return ERANGE;
  }

  return 0;
}
Exemple #10
0
int mq_unlink(
  const char *name
)
{
  POSIX_Message_queue_Control *the_mq;
  Objects_Get_by_name_error    error;
  Thread_queue_Context         queue_context;

  _Objects_Allocator_lock();

  the_mq = _POSIX_Message_queue_Get_by_name( name, NULL, &error );
  if ( the_mq == NULL ) {
    _Objects_Allocator_unlock();
    rtems_set_errno_and_return_minus_one( _POSIX_Get_by_name_error( error ) );
  }

  _POSIX_Message_queue_Namespace_remove( the_mq );

  _CORE_message_queue_Acquire( &the_mq->Message_queue, &queue_context );

  the_mq->linked = false;
  _POSIX_Message_queue_Delete( the_mq, &queue_context );

  _Objects_Allocator_unlock();
  return 0;
}
Exemple #11
0
int sem_close(
    sem_t *sem
)
{
    POSIX_Semaphore_Control          *the_semaphore;
    Objects_Locations                 location;

    _Objects_Allocator_lock();
    the_semaphore = _POSIX_Semaphore_Get( sem, &location );
    switch ( location ) {

    case OBJECTS_LOCAL:
        the_semaphore->open_count -= 1;
        _POSIX_Semaphore_Delete( the_semaphore );
        _Objects_Put( &the_semaphore->Object );
        _Objects_Allocator_unlock();
        return 0;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
#endif
    case OBJECTS_ERROR:
        break;
    }

    _Objects_Allocator_unlock();

    rtems_set_errno_and_return_minus_one( EINVAL );
}
Exemple #12
0
rtems_status_code rtems_message_queue_delete(
  rtems_id id
)
{
  Message_queue_Control          *the_message_queue;
  Objects_Locations               location;

  _Objects_Allocator_lock();
  the_message_queue = _Message_queue_Get( id, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      _Objects_Close( &_Message_queue_Information,
                      &the_message_queue->Object );

      _CORE_message_queue_Close(
        &the_message_queue->message_queue,
        _Message_queue_MP_Send_object_was_deleted,
        id
      );

#if defined(RTEMS_MULTIPROCESSING)
      if ( _Attributes_Is_global( the_message_queue->attribute_set ) ) {
        _Objects_MP_Close(
          &_Message_queue_Information,
          the_message_queue->Object.id
        );

        _Message_queue_MP_Send_process_packet(
          MESSAGE_QUEUE_MP_ANNOUNCE_DELETE,
          the_message_queue->Object.id,
          0,                                 /* Not used */
          0
        );
      }
#endif
      _Objects_Put( &the_message_queue->Object );
      _Message_queue_Free( the_message_queue );
      _Objects_Allocator_unlock();
      return RTEMS_SUCCESSFUL;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
      _Objects_Allocator_unlock();
      return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
#endif

    case OBJECTS_ERROR:
      break;
  }

  _Objects_Allocator_unlock();

  return RTEMS_INVALID_ID;
}
Exemple #13
0
/*
 *  15.2.2 Open a Message Queue, P1003.1b-1993, p. 272
 */
mqd_t mq_open(
  const char *name,
  int         oflag,
  ...
  /* mode_t mode, */
  /* struct mq_attr  attr */
)
{
  POSIX_Message_queue_Control *the_mq;
  size_t                       name_len;
  Objects_Get_by_name_error    error;
  mqd_t                        status;

  _Objects_Allocator_lock();
  the_mq = _POSIX_Message_queue_Get_by_name( name, &name_len, &error );

  /*
   *  If the name to id translation worked, then the message queue exists
   *  and we can just return a pointer to the id.  Otherwise we may
   *  need to check to see if this is a "message queue does not exist"
   *  or some other miscellaneous error on the name.
   */
  if ( the_mq == NULL ) {
    va_list               ap;
    const struct mq_attr *attr;

    /*
     * Unless provided a valid name that did not already exist
     * and we are willing to create then it is an error.
     */

    if ( error != OBJECTS_GET_BY_NAME_NO_OBJECT || ( oflag & O_CREAT ) == 0 ) {
      _Objects_Allocator_unlock();
      rtems_set_errno_and_return_value(
        _POSIX_Get_by_name_error( error ),
        MQ_OPEN_FAILED
      );
    }

    va_start( ap, oflag );
    va_arg( ap, mode_t );
    attr = va_arg( ap, const struct mq_attr * );
    va_end( ap );

    if ( attr == NULL ) {
      attr = &_POSIX_Message_queue_Default_attributes;
    }

    /*
     *  At this point, the message queue does not exist and everything has been
     *  checked. We should go ahead and create a message queue.
     */

    status = _POSIX_Message_queue_Create( name, name_len, oflag, attr );
  } else {
Exemple #14
0
/* read() is unspecified for shared memory objects */
static ssize_t shm_read( rtems_libio_t *iop, void *buffer, size_t count )
{
  ssize_t bytes_read;
  POSIX_Shm_Control *shm = iop_to_shm( iop );

  _Objects_Allocator_lock();
  bytes_read = (*shm->shm_object.ops->object_read)(
      &shm->shm_object,
      buffer,
      count
  );
  _POSIX_Shm_Update_atime( shm );

  _Objects_Allocator_unlock();
  return bytes_read;
}
Exemple #15
0
/**
 *  11.4.2 Initializing and Destroying a Condition Variable,
 *         P1003.1c/Draft 10, p. 87
 */
int pthread_cond_destroy(
  pthread_cond_t           *cond
)
{
  POSIX_Condition_variables_Control *the_cond;
  Objects_Locations                  location;

  _Objects_Allocator_lock();
  the_cond = _POSIX_Condition_variables_Get( cond, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:

      if (
        _Thread_queue_First(
          &the_cond->Wait_queue,
          POSIX_CONDITION_VARIABLES_TQ_OPERATIONS
        )
      ) {
        _Objects_Put( &the_cond->Object );
        _Objects_Allocator_unlock();
        return EBUSY;
      }

      _Objects_Close(
        &_POSIX_Condition_variables_Information,
        &the_cond->Object
      );
      _Objects_Put( &the_cond->Object );
      _POSIX_Condition_variables_Free( the_cond );
      _Objects_Allocator_unlock();
      return 0;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
#endif
    case OBJECTS_ERROR:
      break;
  }

  _Objects_Allocator_unlock();

  return EINVAL;
}
Exemple #16
0
static int shm_ftruncate( rtems_libio_t *iop, off_t length )
{
  int err;
  POSIX_Shm_Control *shm = iop_to_shm( iop );

  _Objects_Allocator_lock();

  err = (*shm->shm_object.ops->object_resize)( &shm->shm_object, length );

  if ( err != 0 ) {
    _Objects_Allocator_unlock();
    rtems_set_errno_and_return_minus_one( err );
  }

  _POSIX_Shm_Update_mtime_ctime( shm );

  _Objects_Allocator_unlock();
  return 0;
}
Exemple #17
0
/**
 *  This directive allows a thread to delete a barrier specified by
 *  the barrier id.  The barrier is freed back to the inactive
 *  barrier chain.
 *
 *  @param[in] barrier is the barrier id
 * 
 *  @return This method returns 0 if there was not an
 *  error. Otherwise, a status code is returned indicating the
 *  source of the error.
 */
int pthread_barrier_destroy(
  pthread_barrier_t *barrier
)
{
  POSIX_Barrier_Control *the_barrier = NULL;
  Objects_Locations      location;

  if ( !barrier )
    return EINVAL;

  _Objects_Allocator_lock();
  the_barrier = _POSIX_Barrier_Get( barrier, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      if ( the_barrier->Barrier.number_of_waiting_threads != 0 ) {
        _Objects_Put( &the_barrier->Object );
        return EBUSY;
      }

      _Objects_Close( &_POSIX_Barrier_Information, &the_barrier->Object );
      _Objects_Put( &the_barrier->Object );

      _POSIX_Barrier_Free( the_barrier );
      _Objects_Allocator_unlock();
      return 0;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
#endif
    case OBJECTS_ERROR:
      break;
  }

  _Objects_Allocator_unlock();

  return EINVAL;
}
Exemple #18
0
rtems_status_code rtems_region_delete(
  rtems_id id
)
{
  Objects_Locations   location;
  rtems_status_code   return_status;
  Region_Control     *the_region;

  _Objects_Allocator_lock();

    the_region = _Region_Get( id, &location );
    switch ( location ) {

      case OBJECTS_LOCAL:
        _Region_Debug_Walk( the_region, 5 );
        if ( the_region->number_of_used_blocks != 0 )
          return_status = RTEMS_RESOURCE_IN_USE;
        else {
          _Objects_Close( &_Region_Information, &the_region->Object );
          _Region_Free( the_region );
          return_status = RTEMS_SUCCESSFUL;
        }
        break;

#if defined(RTEMS_MULTIPROCESSING)
      case OBJECTS_REMOTE:        /* this error cannot be returned */
#endif

      case OBJECTS_ERROR:
      default:
        return_status = RTEMS_INVALID_ID;
        break;
    }

  _Objects_Allocator_unlock();

  return return_status;
}
Exemple #19
0
int timer_delete(
  timer_t timerid
)
{
 /*
  * IDEA: This function must probably stop the timer first and then delete it
  *
  *       It will have to do a call to rtems_timer_cancel and then another
  *       call to rtems_timer_delete.
  *       The call to rtems_timer_delete will be probably unnecessary,
  *       because rtems_timer_delete stops the timer before deleting it.
  */
  POSIX_Timer_Control *ptimer;
  ISR_lock_Context     lock_context;

  _Objects_Allocator_lock();

  ptimer = _POSIX_Timer_Get( timerid, &lock_context );
  if ( ptimer != NULL ) {
    Per_CPU_Control *cpu;

    _Objects_Close( &_POSIX_Timer_Information, &ptimer->Object );
    cpu = _POSIX_Timer_Acquire_critical( ptimer, &lock_context );
    ptimer->state = POSIX_TIMER_STATE_FREE;
    _Watchdog_Remove(
      &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ],
      &ptimer->Timer
    );
    _POSIX_Timer_Release( cpu, &lock_context );
    _POSIX_Timer_Free( ptimer );
    _Objects_Allocator_unlock();
    return 0;
  }

  _Objects_Allocator_unlock();

  rtems_set_errno_and_return_minus_one( EINVAL );
}
Exemple #20
0
rtems_status_code rtems_extension_delete(
  rtems_id id
)
{
  rtems_status_code  status;
  Extension_Control *the_extension;

  _Objects_Allocator_lock();

  the_extension = _Extension_Get( id );

  if ( the_extension != NULL ) {
    _Objects_Close( &_Extension_Information, &the_extension->Object );
    _User_extensions_Remove_set( &the_extension->Extension );
    _Extension_Free( the_extension );
    status = RTEMS_SUCCESSFUL;
  } else {
    status = RTEMS_INVALID_ID;
  }

  _Objects_Allocator_unlock();
  return status;
}
Exemple #21
0
int pthread_rwlock_destroy(
  pthread_rwlock_t *rwlock
)
{
  POSIX_RWLock_Control *the_rwlock;
  ISR_lock_Context      lock_context;

  _Objects_Allocator_lock();
  the_rwlock = _POSIX_RWLock_Get( rwlock, &lock_context );

  if ( the_rwlock == NULL ) {
    _Objects_Allocator_unlock();
    return EINVAL;
  }

  _CORE_RWLock_Acquire_critical( &the_rwlock->RWLock, &lock_context );

  /*
   *  If there is at least one thread waiting, then do not delete it.
   */

  if ( !_Thread_queue_Is_empty( &the_rwlock->RWLock.Wait_queue.Queue ) ) {
    _CORE_RWLock_Release( &the_rwlock->RWLock, &lock_context );
    _Objects_Allocator_unlock();
    return EBUSY;
  }

  /*
   *  POSIX doesn't require behavior when it is locked.
   */

  _Objects_Close( &_POSIX_RWLock_Information, &the_rwlock->Object );
  _CORE_RWLock_Release( &the_rwlock->RWLock, &lock_context );
  _POSIX_RWLock_Free( the_rwlock );
  _Objects_Allocator_unlock();
  return 0;
}
Exemple #22
0
rtems_status_code rtems_semaphore_delete(
  rtems_id   id
)
{
  Semaphore_Control    *the_semaphore;
  Thread_queue_Context  queue_context;
  Status_Control        status;

  _Objects_Allocator_lock();
  the_semaphore = _Semaphore_Get( id, &queue_context );

  if ( the_semaphore == NULL ) {
    _Objects_Allocator_unlock();

#if defined(RTEMS_MULTIPROCESSING)
    if ( _Semaphore_MP_Is_remote( id ) ) {
      return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
    }
#endif

    return RTEMS_INVALID_ID;
  }

  _Thread_queue_Acquire_critical(
    &the_semaphore->Core_control.Wait_queue,
    &queue_context.Lock_context
  );

  switch ( the_semaphore->variant ) {
    case SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY:
    case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING:
    case SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL:
      if (
        _CORE_mutex_Is_locked(
          &the_semaphore->Core_control.Mutex.Recursive.Mutex
        )
      ) {
        status = STATUS_RESOURCE_IN_USE;
      } else {
        status = STATUS_SUCCESSFUL;
      }

      break;
#if defined(RTEMS_SMP)
    case SEMAPHORE_VARIANT_MRSP:
      status = _MRSP_Can_destroy( &the_semaphore->Core_control.MRSP );
      break;
#endif
    default:
      _Assert(
        the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY
          || the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING
      );
      status = STATUS_SUCCESSFUL;
      break;
  }

  if ( status != STATUS_SUCCESSFUL ) {
    _Thread_queue_Release(
      &the_semaphore->Core_control.Wait_queue,
      &queue_context.Lock_context
    );
    _Objects_Allocator_unlock();
    return _Status_Get( status );
  }

  _Objects_Close( &_Semaphore_Information, &the_semaphore->Object );

  switch ( the_semaphore->variant ) {
#if defined(RTEMS_SMP)
    case SEMAPHORE_VARIANT_MRSP:
      _MRSP_Destroy( &the_semaphore->Core_control.MRSP, &queue_context );
      break;
#endif
    default:
      _Assert(
        the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY
          || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING
          || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL
          || the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY
          || the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING
      );
      _Thread_queue_Flush_critical(
        &the_semaphore->Core_control.Wait_queue.Queue,
        _Semaphore_Get_operations( the_semaphore ),
        _Thread_queue_Flush_status_object_was_deleted,
        &queue_context
      );
      _Thread_queue_Destroy( &the_semaphore->Core_control.Wait_queue );
      break;
  }

#if defined(RTEMS_MULTIPROCESSING)
  if ( the_semaphore->is_global ) {

    _Objects_MP_Close( &_Semaphore_Information, id );

    _Semaphore_MP_Send_process_packet(
      SEMAPHORE_MP_ANNOUNCE_DELETE,
      id,
      0,                         /* Not used */
      0                          /* Not used */
    );
  }
#endif

  _Semaphore_Free( the_semaphore );
  _Objects_Allocator_unlock();
  return RTEMS_SUCCESSFUL;
}
Exemple #23
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;
  unsigned int flags;

  if ( shm_check_oflag( oflag ) != 0 ) {
    return -1;
  }

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

  if ( shm == NULL ) {
    switch ( obj_err ) {
      case OBJECTS_GET_BY_NAME_INVALID_NAME:
        err = EINVAL;
        break;

      case OBJECTS_GET_BY_NAME_NAME_TOO_LONG:
        err = ENAMETOOLONG;
        break;

      case OBJECTS_GET_BY_NAME_NO_OBJECT:
      default:
        shm = shm_allocate(name, len, oflag, mode, &err);
        break;
    }
  } else { /* shm exists */
    if ( ( oflag & ( O_EXCL | O_CREAT ) ) == ( O_EXCL | O_CREAT ) ) {
      /* Request to create failed. */
      err = EEXIST;
    } else if ( !shm_access_ok( shm, oflag ) ) {
      err = EACCES;
    } else {
      ++shm->reference_count;
    }
  }
  _Objects_Allocator_unlock();
  if ( err != 0 ) {
    rtems_libio_free( iop );
    rtems_set_errno_and_return_minus_one( err );
  }

  if ( oflag & O_TRUNC ) {
    err = shm_ftruncate( iop, 0 );
    (void) err; /* ignore truncate error */
  }

  fd = rtems_libio_iop_to_descriptor( iop );
  iop->data0 = fd;
  iop->data1 = shm;
  iop->pathinfo.node_access = shm;
  iop->pathinfo.handlers = &shm_handlers;
  iop->pathinfo.mt_entry = &rtems_filesystem_null_mt_entry;
  rtems_filesystem_location_add_to_mt_entry( &iop->pathinfo );

  flags = LIBIO_FLAGS_CLOSE_ON_EXEC;
  if ( oflag & O_RDONLY ) {
    flags |= LIBIO_FLAGS_READ;
  } else {
    flags |= LIBIO_FLAGS_READ_WRITE;
  }

  rtems_libio_iop_flags_initialize( iop, flags );

  return fd;
}