Пример #1
0
static int duplicate_iop( rtems_libio_t *iop )
{
  int rv = 0;

  rtems_libio_t *diop = rtems_libio_allocate();

  if (diop != NULL) {
    int oflag = rtems_libio_to_fcntl_flags( iop->flags );

    oflag &= ~O_CREAT;
    diop->flags |= rtems_libio_fcntl_flags( oflag );

    rtems_filesystem_instance_lock( &iop->pathinfo );
    rtems_filesystem_location_clone( &diop->pathinfo, &iop->pathinfo );
    rtems_filesystem_instance_unlock( &iop->pathinfo );

    /*
     * XXX: We call the open handler here to have a proper open and close pair.
     *
     * FIXME: What to do with the path?
     */
    rv = (*diop->pathinfo.handlers->open_h)( diop, NULL, oflag, 0 );
    if ( rv == 0 ) {
      rv = rtems_libio_iop_to_descriptor( diop );
    } else {
      rtems_libio_free( diop );
    }
  } else {
    rv = -1;
  }

  return rv;
}
Пример #2
0
int rtems_bsdnet_makeFdForSocket(
  void *so,
  const rtems_filesystem_file_handlers_r *h
)
{
  rtems_libio_t *iop;
  int fd;

  iop = rtems_libio_allocate();
  if (iop == 0)
      rtems_set_errno_and_return_minus_one( ENFILE );

  fd = iop - rtems_libio_iops;
  iop->flags |= LIBIO_FLAGS_WRITE | LIBIO_FLAGS_READ;
  iop->data0 = fd;
  iop->data1 = so;
  iop->pathinfo.handlers = h;
  iop->pathinfo.ops = &rtems_filesystem_operations_default;
  return fd;
}
Пример #3
0
/*
 * Create an RTEMS file descriptor for a socket
 */
static int
rtems_bsdnet_makeFdForSocket (void *so)
{
  rtems_libio_t *iop;
  int fd;

  iop = rtems_libio_allocate();
  if (iop == 0)
      rtems_set_errno_and_return_minus_one( ENFILE );

  fd = iop - rtems_libio_iops;
  iop->flags |= LIBIO_FLAGS_WRITE | LIBIO_FLAGS_READ;
  iop->data0 = fd;
  iop->data1 = so;
  iop->pathinfo.handlers = &socket_handlers;
  iop->pathinfo.ops = &rtems_filesystem_operations_default;
  iop->pathinfo.mt_entry = &rtems_filesystem_null_mt_entry;
  rtems_filesystem_location_add_to_mt_entry(&iop->pathinfo);
  return fd;
}
Пример #4
0
Файл: open.c Проект: AoLaD/rtems
/**
*  POSIX 1003.1 5.3.1 - Open a File
*/
int open( const char *path, int oflag, ... )
{
  int rv = 0;
  va_list ap;
  mode_t mode = 0;
  rtems_libio_t *iop = NULL;

  va_start( ap, oflag );

  mode = va_arg( ap, mode_t );

  iop = rtems_libio_allocate();
  if ( iop != NULL ) {
    rv = do_open( iop, path, oflag, mode );
  } else {
    errno = ENFILE;
    rv = -1;
  }

  va_end( ap );

  return rv;
}
Пример #5
0
int open(
  const char   *pathname,
  int           flags,
  ...
)
{
  va_list                             ap;
  int                                 mode;
  int                                 rc;
  rtems_libio_t                      *iop = 0;
  int                                 status;
  rtems_filesystem_location_info_t    loc;
  rtems_filesystem_location_info_t   *loc_to_free = NULL;
  int                                 eval_flags;


  /*
   * Set the Evaluation flags
   */

  eval_flags = 0;
  status = flags + 1;
  if ( ( status & _FREAD ) == _FREAD )
    eval_flags |= RTEMS_LIBIO_PERMS_READ;
  if ( ( status & _FWRITE ) == _FWRITE )
    eval_flags |= RTEMS_LIBIO_PERMS_WRITE;


  va_start(ap, flags);

  mode = va_arg( ap, int );

  /*
   * NOTE: This comment is OBSOLETE.  The proper way to do this now
   *       would be to support a magic mounted file system.
   *
   *             Additional external I/O handlers would be supported by adding
   *             code to pick apart the pathname appropriately. The networking
   *             code does not require changes here since network file
   *             descriptors are obtained using socket(), not open().
   */

  /* allocate a file control block */
  iop = rtems_libio_allocate();
  if ( iop == 0 ) {
    rc = ENFILE;
    goto done;
  }

  /*
   *  See if the file exists.
   */

  status = rtems_filesystem_evaluate_path(
     pathname, eval_flags, &loc, TRUE );

  if ( status == -1 ) {
    if ( errno != ENOENT ) {
      rc = errno;
      goto done;
    }

    /* If the file does not exist and we are not trying to create it--> error */
    if ( !(flags & O_CREAT) ) {
      rc = ENOENT;
      goto done;
    }

    /* Create the node for the new regular file */
    rc = mknod( pathname, S_IFREG | mode, 0LL );
    if ( rc ) {
      rc = errno;
      goto done;
    }

    /* Sanity check to see if the file name exists after the mknod() */
    status = rtems_filesystem_evaluate_path( pathname, 0x0, &loc, TRUE );
    if ( status != 0 ) {   /* The file did not exist */
      rc = EACCES;
      goto done;
    }

  } else if ((flags & (O_EXCL|O_CREAT)) == (O_EXCL|O_CREAT)) {
    /* We were trying to create a file that already exists */
    rc = EEXIST;
    loc_to_free = &loc;
    goto done;
  }

  loc_to_free = &loc;

  /*
   *  Fill in the file control block based on the loc structure
   *  returned by successful path evaluation.
   */

  iop->handlers   = loc.handlers;
  iop->file_info  = loc.node_access;
  iop->flags     |= rtems_libio_fcntl_flags( flags );
  iop->pathinfo   = loc;

  if ( !iop->handlers->open_h ) {
    rc = ENOTSUP;
    goto done;
  }

  rc = (*iop->handlers->open_h)( iop, pathname, flags, mode );
  if ( rc )
    goto done;

  /*
   *  Optionally truncate the file.
   */

  if ( (flags & O_TRUNC) == O_TRUNC ) {
    rc = ftruncate( iop - rtems_libio_iops, 0 );
    if ( rc ) {
      if(errno) rc = errno;
      close( iop - rtems_libio_iops );
      /* those are released by close(): */
      iop = 0;
      loc_to_free = NULL;
    }
  }

  /*
   *  Single exit and clean up path.
   */

done:
  va_end(ap);

  if ( rc ) {
    if ( iop )
      rtems_libio_free( iop );
    if ( loc_to_free )
      rtems_filesystem_freenode( loc_to_free );
    rtems_set_errno_and_return_minus_one( rc );
  }

  return iop - rtems_libio_iops;
}
Пример #6
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;
}
Пример #7
0
static int vfcntl(
  int fd,
  int cmd,
  va_list ap
)
{
  rtems_libio_t *iop;
  rtems_libio_t *diop;
  int            fd2;
  int            flags;
  int            mask;
  int            ret = 0;

  rtems_libio_check_fd( fd );
  iop = rtems_libio_iop( fd );
  rtems_libio_check_is_open(iop);

  /*
   *  Now process the fcntl().
   */

  /*
   *  This switch should contain all the cases from POSIX.
   */

  switch ( cmd ) {
    case F_DUPFD:        /* dup */
      fd2 = va_arg( ap, int );
      if ( fd2 )
        diop = rtems_libio_iop( fd2 );
      else {
        /* allocate a file control block */
        diop = rtems_libio_allocate();
        if ( diop == 0 ) {
          ret = -1;
          break;
        }
      }

      diop->handlers   = iop->handlers;
      diop->file_info  = iop->file_info;
      diop->flags      = iop->flags;
      diop->pathinfo   = iop->pathinfo;
      ret = (int) (diop - rtems_libio_iops);
      break;

    case F_GETFD:        /* get f_flags */
      ret = ((iop->flags & LIBIO_FLAGS_CLOSE_ON_EXEC) != 0);
      break;

    case F_SETFD:        /* set f_flags */
      /*
       *  Interpret the third argument as the "close on exec()" flag.
       *  If this argument is 1, then the file descriptor is to be closed
       *  if a new process is exec()'ed.  Since RTEMS does not support
       *  processes, then we can ignore this one except to make
       *  F_GETFD work.
       */

      if ( va_arg( ap, int ) )
        iop->flags |= LIBIO_FLAGS_CLOSE_ON_EXEC;
      else
        iop->flags &= ~LIBIO_FLAGS_CLOSE_ON_EXEC;
      break;

    case F_GETFL:        /* more flags (cloexec) */
      ret = rtems_libio_to_fcntl_flags( iop->flags );
      break;

    case F_SETFL:
      flags = rtems_libio_fcntl_flags( va_arg( ap, int ) );
      mask = LIBIO_FLAGS_NO_DELAY | LIBIO_FLAGS_APPEND;

      /*
       *  XXX If we are turning on append, should we seek to the end?
       */

      iop->flags = (iop->flags & ~mask) | (flags & mask);
      break;

    case F_GETLK:
      errno = ENOTSUP;
      ret = -1;
      break;

    case F_SETLK:
      errno = ENOTSUP;
      ret = -1;
      break;

    case F_SETLKW:
      errno = ENOTSUP;
      ret = -1;
      break;

    case F_SETOWN:       /*  for sockets. */
      errno = ENOTSUP;
      ret = -1;
      break;

    case F_GETOWN:       /*  for sockets. */
      errno = ENOTSUP;
      ret = -1;
      break;

    default:
      errno = EINVAL;
      ret = -1;
      break;
  }