Пример #1
0
/* msdos_file_lseek --
 *     Process lseek call to the file: extend file if lseek is up to the end
 *     of the file.
 *
 * PARAMETERS:
 *     iop    - file control block
 *     offset - new offset
 *     whence - predefine directive
 *
 * RETURNS:
 *     new offset on success, or -1 if error occured (errno set
 *     appropriately).
 */
rtems_off64_t
msdos_file_lseek(rtems_libio_t *iop, rtems_off64_t offset, int whence)
{
    int                rc = RC_OK;
    rtems_status_code  sc = RTEMS_SUCCESSFUL;
    msdos_fs_info_t   *fs_info = iop->pathinfo.mt_entry->fs_info;
    fat_file_fd_t     *fat_fd = iop->pathinfo.node_access;
    uint32_t           real_size = 0;

    sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
                                MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
    if (sc != RTEMS_SUCCESSFUL)
        rtems_set_errno_and_return_minus_one(EIO);

    rc = fat_file_extend(iop->pathinfo.mt_entry, fat_fd, iop->offset,
                         &real_size);
    if (rc != RC_OK)
    {
        rtems_semaphore_release(fs_info->vol_sema);
        return rc;
    }

    if (real_size > fat_fd->fat_file_size)
        fat_fd->fat_file_size = iop->offset = real_size;

    iop->size = fat_fd->fat_file_size;

    rtems_semaphore_release(fs_info->vol_sema);
    return iop->offset;
}
Пример #2
0
/* msdos_file_ftruncate --
 *     Truncate the file.
 *
 * PARAMETERS:
 *     iop    - file control block
 *     length - new length
 *
 * RETURNS:
 *     RC_OK on success, or -1 if error occured (errno set appropriately).
 */
int
msdos_file_ftruncate(rtems_libio_t *iop, off_t length)
{
    int                rc = RC_OK;
    rtems_status_code  sc = RTEMS_SUCCESSFUL;
    msdos_fs_info_t   *fs_info = iop->pathinfo.mt_entry->fs_info;
    fat_file_fd_t     *fat_fd = iop->pathinfo.node_access;
    uint32_t old_length;

    sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
                                MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
    if (sc != RTEMS_SUCCESSFUL)
        rtems_set_errno_and_return_minus_one(EIO);

    old_length = fat_fd->fat_file_size;
    if (length < old_length) {
        rc = fat_file_truncate(&fs_info->fat, fat_fd, length);
    } else {
        uint32_t new_length;

        rc = fat_file_extend(&fs_info->fat,
                             fat_fd,
                             true,
                             length,
                             &new_length);
        if (rc == RC_OK && length != new_length) {
            fat_file_truncate(&fs_info->fat, fat_fd, old_length);
            errno = ENOSPC;
            rc = -1;
        }
    }

    if (rc == RC_OK)
    {
        fat_file_set_file_size(fat_fd, length);
        fat_file_set_ctime_mtime(fat_fd, time(NULL));
    }

    rtems_semaphore_release(fs_info->vol_sema);

    return rc;
}