Ejemplo n.º 1
0
/*****************************************************************************
 * Read commands.
 *****************************************************************************/
static int libc_read ( dvdcss_t dvdcss, void *p_buffer, int i_blocks )
{
    off_t i_size, i_ret, i_ret_blocks;

    i_size = (off_t)i_blocks * (off_t)DVDCSS_BLOCK_SIZE;
    i_ret = 0;
    while (i_ret < i_size)
    {
      off_t i_r;
      i_r = read(dvdcss->i_fd, ((char*)p_buffer) + i_ret, i_size - i_ret);
      if (i_r < 0)
      {
        print_error(dvdcss, "read error");
        dvdcss->i_pos = -1;
        return i_r;
      }
      if (i_r == 0)
        break;

      i_ret += i_r;
    }

    i_ret_blocks = i_ret / DVDCSS_BLOCK_SIZE;

    /* Handle partial reads */
    if( i_ret != i_size )
    {
        int i_seek, i_set_pos;

        i_set_pos = dvdcss->i_pos + i_ret_blocks;
        dvdcss->i_pos = -1;
        i_seek = libc_seek( dvdcss, i_set_pos );
        if( i_seek < 0 )
        {
            return i_seek;
        }

        /* We have to return now so that i_pos isn't clobbered */
        return i_ret_blocks;
    }

    dvdcss->i_pos += i_ret_blocks;
    return i_ret_blocks;
}
Ejemplo n.º 2
0
/*****************************************************************************
 * Readv commands.
 *****************************************************************************/
static int libc_readv ( dvdcss_t dvdcss, const struct iovec *p_iovec,
                        int i_blocks )
{
#if defined( _WIN32 )
    int i_index, i_len, i_total = 0;
    unsigned char *p_base;
    int i_bytes;

    for( i_index = i_blocks;
         i_index;
         i_index--, p_iovec++ )
    {
        i_len  = p_iovec->iov_len;
        p_base = p_iovec->iov_base;

        if( i_len <= 0 )
        {
            continue;
        }

        i_bytes = read( dvdcss->i_fd, p_base, i_len );

        if( i_bytes < 0 )
        {
            /* One of the reads failed, too bad.
             * We won't even bother returning the reads that went OK,
             * and as in the POSIX spec the file position is left
             * unspecified after a failure */
            dvdcss->i_pos = -1;
            return -1;
        }

        i_total += i_bytes;
        i_total /= DVDCSS_BLOCK_SIZE;

        if( i_bytes != i_len )
        {
            /* We reached the end of the file or a signal interrupted
             * the read. Return a partial read. */
            int i_seek;

            dvdcss->i_pos = -1;
            i_seek = libc_seek( dvdcss, i_total );
            if( i_seek < 0 )
            {
                return i_seek;
            }

            /* We have to return now so that i_pos isn't clobbered */
            return i_total;
        }
    }

    dvdcss->i_pos += i_total;
    return i_total;
#else
    int i_read = readv( dvdcss->i_fd, p_iovec, i_blocks );

    if( i_read < 0 )
    {
        dvdcss->i_pos = -1;
        return i_read;
    }

    i_read /= DVDCSS_BLOCK_SIZE;
    dvdcss->i_pos += i_read;
    return i_read;
#endif
}