示例#1
0
文件: fcntl.c 项目: AoLaD/rtems
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
文件: fcntl.c 项目: AoLaD/rtems
static int duplicate2_iop( rtems_libio_t *iop, int fd2 )
{
  rtems_libio_t *iop2;
  int            rv = 0;

  rtems_libio_check_fd( fd2 );
  iop2 = rtems_libio_iop( fd2 );

  if (iop != iop2)
  {
    int oflag;

    if ((iop2->flags & LIBIO_FLAGS_OPEN) != 0) {
      rv = (*iop2->pathinfo.handlers->close_h)( iop2 );
    }

    if (rv == 0) {
      oflag = rtems_libio_to_fcntl_flags( iop->flags );
      oflag &= ~O_CREAT;
      iop2->flags |= rtems_libio_fcntl_flags( oflag );

      rtems_filesystem_instance_lock( &iop->pathinfo );
      rtems_filesystem_location_clone( &iop2->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 = (*iop2->pathinfo.handlers->open_h)( iop2, NULL, oflag, 0 );
      if ( rv == 0 ) {
        rv = fd2;
      }
    }
  }

  return rv;
}
示例#3
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;
}
示例#4
0
文件: open.c 项目: AoLaD/rtems
static int do_open(
  rtems_libio_t *iop,
  const char *path,
  int oflag,
  mode_t mode
)
{
  int rv = 0;
  int fd = rtems_libio_iop_to_descriptor( iop );
  int rwflag = oflag + 1;
  bool read_access = (rwflag & _FREAD) == _FREAD;
  bool write_access = (rwflag & _FWRITE) == _FWRITE;
  bool make = (oflag & O_CREAT) == O_CREAT;
  bool exclusive = (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL);
  bool truncate = (oflag & O_TRUNC) == O_TRUNC;
  int eval_flags = RTEMS_FS_FOLLOW_LINK
    | (read_access ? RTEMS_FS_PERMS_READ : 0)
    | (write_access ? RTEMS_FS_PERMS_WRITE : 0)
    | (make ? RTEMS_FS_MAKE : 0)
    | (exclusive ?  RTEMS_FS_EXCLUSIVE : 0);
  rtems_filesystem_eval_path_context_t ctx;

  rtems_filesystem_eval_path_start( &ctx, path, eval_flags );

  if ( rtems_filesystem_eval_path_has_token( &ctx ) ) {
    create_regular_file( &ctx, mode );
  }

  if ( write_access ) {
    const rtems_filesystem_location_info_t *currentloc =
      rtems_filesystem_eval_path_get_currentloc( &ctx );
    mode_t type = rtems_filesystem_location_type( currentloc );

    if ( S_ISDIR( type ) ) {
      rtems_filesystem_eval_path_error( &ctx, EISDIR );
    }
  }

  iop->flags |= rtems_libio_fcntl_flags( oflag );
  rtems_filesystem_eval_path_extract_currentloc( &ctx, &iop->pathinfo );
  rtems_filesystem_eval_path_cleanup( &ctx );

  rv = (*iop->pathinfo.handlers->open_h)( iop, path, oflag, mode );

  if ( rv == 0 ) {
    if ( truncate ) {
      rv = ftruncate( fd, 0 );
      if ( rv != 0 ) {
        (*iop->pathinfo.handlers->close_h)( iop );
      }
    }

    if ( rv == 0 ) {
      rv = fd;
    } else {
      rv = -1;
    }
  }

  if ( rv < 0 ) {
    rtems_libio_free( iop );
  }

  return rv;
}