/** * This routine processes the read() system call. * * @param iop * @param buffer * @param count * @return int */ static ssize_t rtems_rfs_rtems_file_read (rtems_libio_t* iop, void* buffer, size_t count) { rtems_rfs_file_handle* file = rtems_rfs_rtems_get_iop_file_handle (iop); rtems_rfs_pos pos; uint8_t* data = buffer; ssize_t read = 0; int rc; if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_READ)) printf("rtems-rfs: file-read: handle:%p count:%zd\n", file, count); rtems_rfs_rtems_lock (rtems_rfs_file_fs (file)); pos = iop->offset; if (pos < rtems_rfs_file_size (file)) { while (count) { size_t size; rc = rtems_rfs_file_io_start (file, &size, true); if (rc > 0) { read = rtems_rfs_rtems_error ("file-read: read: io-start", rc); break; } if (size == 0) break; if (size > count) size = count; memcpy (data, rtems_rfs_file_data (file), size); data += size; count -= size; read += size; rc = rtems_rfs_file_io_end (file, size, true); if (rc > 0) { read = rtems_rfs_rtems_error ("file-read: read: io-end", rc); break; } } } if (read >= 0) iop->offset = pos + read; rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file)); return read; }
/** * This routine processes the write() system call. * * @param iop * @param buffer * @param count * @return ssize_t */ static ssize_t rtems_rfs_rtems_file_write (rtems_libio_t* iop, const void* buffer, size_t count) { rtems_rfs_file_handle* file = rtems_rfs_rtems_get_iop_file_handle (iop); rtems_rfs_pos pos; rtems_rfs_pos file_size; const uint8_t* data = buffer; ssize_t write = 0; int rc; if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_WRITE)) printf("rtems-rfs: file-write: handle:%p count:%zd\n", file, count); rtems_rfs_rtems_lock (rtems_rfs_file_fs (file)); pos = iop->offset; file_size = rtems_rfs_file_size (file); if (pos > file_size) { /* * If the iop position is past the physical end of the file we need to set * the file size to the new length before writing. The * rtems_rfs_file_io_end() will grow the file subsequently. */ rc = rtems_rfs_file_set_size (file, pos); if (rc) { rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file)); return rtems_rfs_rtems_error ("file-write: write extend", rc); } rtems_rfs_file_set_bpos (file, pos); } else if (pos < file_size && rtems_libio_iop_is_append(iop)) { pos = file_size; rc = rtems_rfs_file_seek (file, pos, &pos); if (rc) { rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file)); return rtems_rfs_rtems_error ("file-write: write append seek", rc); } } while (count) { size_t size = count; rc = rtems_rfs_file_io_start (file, &size, false); if (rc) { /* * If we have run out of space and have written some data return that * amount first as the inode will have accounted for it. This means * there was no error and the return code from can be ignored. */ if (!write) write = rtems_rfs_rtems_error ("file-write: write open", rc); break; } if (size > count) size = count; memcpy (rtems_rfs_file_data (file), data, size); data += size; count -= size; write += size; rc = rtems_rfs_file_io_end (file, size, false); if (rc) { write = rtems_rfs_rtems_error ("file-write: write close", rc); break; } } if (write >= 0) iop->offset = pos + write; rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file)); return write; }
/** * This routine processes the write() system call. * * @param iop * @param buffer * @param count * @return ssize_t */ static ssize_t rtems_rfs_rtems_file_write (rtems_libio_t* iop, const void* buffer, size_t count) { rtems_rfs_file_handle* file = rtems_rfs_rtems_get_iop_file_handle (iop); rtems_rfs_pos pos; const uint8_t* data = buffer; ssize_t write = 0; int rc; if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_WRITE)) printf("rtems-rfs: file-write: handle:%p count:%zd\n", file, count); rtems_rfs_rtems_lock (rtems_rfs_file_fs (file)); pos = iop->offset; /* * If the iop position is past the physical end of the file we need to set * the file size to the new length before writing. If the position equals the * size of file we are still past the end of the file as positions number * from 0. For a specific position we need a file that has a length of one * more. */ if (pos >= rtems_rfs_file_size (file)) { rc = rtems_rfs_file_set_size (file, pos + 1); if (rc) { rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file)); return rtems_rfs_rtems_error ("file-write: write extend", rc); } } rtems_rfs_file_set_bpos (file, pos); while (count) { size_t size = count; rc = rtems_rfs_file_io_start (file, &size, false); if (rc) { write = rtems_rfs_rtems_error ("file-write: write open", rc); break; } if (size > count) size = count; memcpy (rtems_rfs_file_data (file), data, size); data += size; count -= size; write += size; rc = rtems_rfs_file_io_end (file, size, false); if (rc) { write = rtems_rfs_rtems_error ("file-write: write close", rc); break; } } iop->size = rtems_rfs_file_size (file); rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file)); return write; }