示例#1
0
/*
 *  memfile_ftruncate
 *
 *  This routine processes the ftruncate() system call.
 */
int memfile_ftruncate(
  rtems_libio_t        *iop,
  off_t                 length
)
{
  IMFS_jnode_t   *the_jnode;

  the_jnode = iop->pathinfo.node_access;

  /*
   *  POSIX 1003.1b does not specify what happens if you truncate a file
   *  and the new length is greater than the current size.  We treat this
   *  as an extend operation.
   */

  if ( length > the_jnode->info.file.size )
    return IMFS_memfile_extend( the_jnode, length );

  /*
   *  The in-memory files do not currently reclaim memory until the file is
   *  deleted.  So we leave the previously allocated blocks in place for
   *  future use and just set the length.
   */
  the_jnode->info.file.size = length;
  iop->size = the_jnode->info.file.size;

  IMFS_update_atime( the_jnode );

  return 0;
}
示例#2
0
static ssize_t IMFS_fifo_read(
    rtems_libio_t *iop,
    void          *buffer,
    size_t         count
)
{
    IMFS_jnode_t *jnode = iop->pathinfo.node_access;

    int err = pipe_read(JNODE2PIPE(jnode), buffer, count, iop);
    if (err > 0)
        IMFS_update_atime(jnode);

    IMFS_FIFO_RETURN(err);
}
示例#3
0
ssize_t IMFS_fifo_read(
  epos_libio_t *iop,
  void          *buffer,
  size_t         count
)
{
  IMFS_jnode_t *jnode = iop->file_info;

  int err = pipe_read(JNODE2PIPE(jnode), buffer, count, iop);
  if (err > 0)
    IMFS_update_atime(jnode);

  IMFS_FIFO_RETURN(err);
}
示例#4
0
/*
 *  IMFS_memfile_read
 *
 *  This routine read from memory file pointed to by the_jnode into
 *  the specified data buffer specified by destination.  The file
 *  is NOT extended.  An offset greater than the length of the file
 *  is considered an error.  Read from an offset for more bytes than
 *  are between the offset and the end of the file will result in
 *  reading the data between offset and the end of the file (truncated
 *  read).
 */
static ssize_t IMFS_memfile_read(
   IMFS_file_t     *file,
   off_t            start,
   unsigned char   *destination,
   unsigned int     length
)
{
  block_p             *block_ptr;
  unsigned int         block;
  unsigned int         my_length;
  unsigned int         to_copy = 0;
  unsigned int         last_byte;
  unsigned int         copied;
  unsigned int         start_offset;
  unsigned char       *dest;

  dest = destination;

  /*
   *  Perform internal consistency checks
   */
  IMFS_assert( file );
  IMFS_assert( dest );

  /*
   *  Linear files (as created from a tar file are easier to handle
   *  than block files).
   */
  my_length = length;

  /*
   *  If the last byte we are supposed to read is past the end of this
   *  in memory file, then shorten the length to read.
   */
  last_byte = start + length;
  if ( last_byte > file->Memfile.File.size )
    my_length = file->Memfile.File.size - start;

  copied = 0;

  /*
   *  Three phases to the read:
   *    + possibly the last part of one block
   *    + all of zero of more blocks
   *    + possibly the first part of one block
   */

  /*
   *  Phase 1: possibly the last part of one block
   */
  start_offset = start % IMFS_MEMFILE_BYTES_PER_BLOCK;
  block = start / IMFS_MEMFILE_BYTES_PER_BLOCK;
  if ( start_offset )  {
    to_copy = IMFS_MEMFILE_BYTES_PER_BLOCK - start_offset;
    if ( to_copy > my_length )
      to_copy = my_length;
    block_ptr = IMFS_memfile_get_block_pointer( &file->Memfile, block, 0 );
    if ( !block_ptr )
      return copied;
    memcpy( dest, &(*block_ptr)[ start_offset ], to_copy );
    dest += to_copy;
    block++;
    my_length -= to_copy;
    copied += to_copy;
  }

  /*
   *  Phase 2: all of zero of more blocks
   */
  to_copy = IMFS_MEMFILE_BYTES_PER_BLOCK;
  while ( my_length >= IMFS_MEMFILE_BYTES_PER_BLOCK ) {
    block_ptr = IMFS_memfile_get_block_pointer( &file->Memfile, block, 0 );
    if ( !block_ptr )
      return copied;
    memcpy( dest, &(*block_ptr)[ 0 ], to_copy );
    dest += to_copy;
    block++;
    my_length -= to_copy;
    copied += to_copy;
  }

  /*
   *  Phase 3: possibly the first part of one block
   */
  IMFS_assert( my_length < IMFS_MEMFILE_BYTES_PER_BLOCK );

  if ( my_length ) {
    block_ptr = IMFS_memfile_get_block_pointer( &file->Memfile, block, 0 );
    if ( !block_ptr )
      return copied;
    memcpy( dest, &(*block_ptr)[ 0 ], my_length );
    copied += my_length;
  }

  IMFS_update_atime( &file->Node );

  return copied;
}
示例#5
0
文件: memfile.c 项目: epicsdeb/rtems
MEMFILE_STATIC ssize_t IMFS_memfile_read(
   IMFS_jnode_t    *the_jnode,
   off_t            start,
   unsigned char   *destination,
   unsigned int     length
)
{
  block_p             *block_ptr;
  unsigned int         block;
  unsigned int         my_length;
  unsigned int         to_copy = 0;
  unsigned int         last_byte;
  unsigned int         copied;
  unsigned int         start_offset;
  unsigned char       *dest;

  dest = destination;

  /*
   *  Perform internal consistency checks
   */

  assert( the_jnode );
  if ( !the_jnode )
    rtems_set_errno_and_return_minus_one( EIO );

  assert( the_jnode->type == IMFS_MEMORY_FILE ||
          the_jnode->type == IMFS_LINEAR_FILE );
  if ( the_jnode->type != IMFS_MEMORY_FILE &&
       the_jnode->type != IMFS_LINEAR_FILE )
    rtems_set_errno_and_return_minus_one( EIO );

  /*
   *  Error checks on arguments
   */

  assert( dest );
  if ( !dest )
    rtems_set_errno_and_return_minus_one( EINVAL );

  /*
   *  If there is nothing to read, then quick exit.
   */

  my_length = length;
  if ( !my_length )
    rtems_set_errno_and_return_minus_one( EINVAL );

  /*
   *  Linear files (as created from a tar file are easier to handle
   *  than block files).
   */
  if (the_jnode->type == IMFS_LINEAR_FILE) {
    unsigned char  *file_ptr;

    file_ptr = (unsigned char *)the_jnode->info.linearfile.direct;

    if (my_length > (the_jnode->info.linearfile.size - start))
      my_length = the_jnode->info.linearfile.size - start;

    memcpy(dest, &file_ptr[start], my_length);

    IMFS_update_atime( the_jnode );

    return my_length;
  }

  /*
   *  If the last byte we are supposed to read is past the end of this
   *  in memory file, then shorten the length to read.
   */

  last_byte = start + length;
  if ( last_byte > the_jnode->info.file.size )
    my_length = the_jnode->info.file.size - start;

  copied = 0;

  /*
   *  Three phases to the read:
   *    + possibly the last part of one block
   *    + all of zero of more blocks
   *    + possibly the first part of one block
   */

  /*
   *  Phase 1: possibly the last part of one block
   */

  start_offset = start % IMFS_MEMFILE_BYTES_PER_BLOCK;
  block = start / IMFS_MEMFILE_BYTES_PER_BLOCK;
  if ( start_offset )  {
    to_copy = IMFS_MEMFILE_BYTES_PER_BLOCK - start_offset;
    if ( to_copy > my_length )
      to_copy = my_length;
    block_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 0 );
    assert( block_ptr );
    if ( !block_ptr )
      return copied;
    memcpy( dest, &(*block_ptr)[ start_offset ], to_copy );
    dest += to_copy;
    block++;
    my_length -= to_copy;
    copied += to_copy;
  }

  /*
   *  Phase 2: all of zero of more blocks
   */

  to_copy = IMFS_MEMFILE_BYTES_PER_BLOCK;
  while ( my_length >= IMFS_MEMFILE_BYTES_PER_BLOCK ) {
    block_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 0 );
    assert( block_ptr );
    if ( !block_ptr )
      return copied;
    memcpy( dest, &(*block_ptr)[ 0 ], to_copy );
    dest += to_copy;
    block++;
    my_length -= to_copy;
    copied += to_copy;
  }

  /*
   *  Phase 3: possibly the first part of one block
   */

  assert( my_length < IMFS_MEMFILE_BYTES_PER_BLOCK );

  if ( my_length ) {
    block_ptr = IMFS_memfile_get_block_pointer( the_jnode, block, 0 );
    assert( block_ptr );
    if ( !block_ptr )
      return copied;
    memcpy( dest, &(*block_ptr)[ 0 ], my_length );
    copied += my_length;
  }

  IMFS_update_atime( the_jnode );

  return copied;
}