/* * 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; }
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); }
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); }
/* * 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; }
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; }