pub async fn sys_copy_file_range(
        &self,
        in_fd: FileDesc,
        mut in_offset: UserInOutPtr<u64>,
        out_fd: FileDesc,
        mut out_offset: UserInOutPtr<u64>,
        count: usize,
        flags: usize,
    ) -> SysResult {
        info!(
            "copy_file_range: in={:?}, out={:?}, in_offset={:?}, out_offset={:?}, count={}, flags={}",
            in_fd, out_fd, in_offset, out_offset, count, flags
        );
        let proc = self.linux_process();
        let in_file = proc.get_file(in_fd)?;
        let out_file = proc.get_file(out_fd)?;
        let mut buffer = [0u8; 1024];

        // for in_offset and out_offset
        // null means update file offset
        // non-null means update {in,out}_offset instead

        let mut read_offset = if !in_offset.is_null() {
            in_offset.read()?
        } else {
            in_file.seek(SeekFrom::Current(0))?
        };

        let orig_out_file_offset = out_file.seek(SeekFrom::Current(0))?;
        let write_offset = if !out_offset.is_null() {
            let offset = out_offset.read()?;
            out_file.seek(SeekFrom::Start(offset))?
        } else {
            0
        };

        // read from specified offset and write new offset back
        let mut bytes_read = 0;
        let mut total_written = 0;
        while bytes_read < count {
            let len = buffer.len().min(count - bytes_read);
            let read_len = in_file.read_at(read_offset, &mut buffer[..len]).await?;
            if read_len == 0 {
                break;
            }
            bytes_read += read_len;
            read_offset += read_len as u64;

            let mut bytes_written = 0;
            let mut rlen = read_len;
            while bytes_written < read_len {
                let write_len = out_file.write(&buffer[bytes_written..(bytes_written + rlen)])?;
                if write_len == 0 {
                    info!(
                        "copy_file_range:END_ERR in={:?}, out={:?}, in_offset={:?}, out_offset={:?}, count={} = bytes_read {}, bytes_written {}, write_len {}",
                        in_fd, out_fd, in_offset, out_offset, count, bytes_read, bytes_written, write_len
                    );
                    return Err(LxError::EBADF);
                }
                bytes_written += write_len;
                rlen -= write_len;
            }
            total_written += bytes_written;
        }

        if !in_offset.is_null() {
            in_offset.write(read_offset)?;
        } else {
            in_file.seek(SeekFrom::Current(bytes_read as i64))?;
        }
        out_offset.write_if_not_null(write_offset + total_written as u64)?;
        if !out_offset.is_null() {
            out_file.seek(SeekFrom::Start(orig_out_file_offset))?;
        }
        Ok(total_written)
    }
/// copies data between one file descriptor and anothe, read from specified offset and write new offset back
copies data between one file descriptor and anothe, read from specified offset and write new offset back
copies data between one file descriptor and anothe read from specified offset and write new offset back
pub async fn sys_copy_file_range(
        &self,
        in_fd: FileDesc,
        mut in_offset: UserInOutPtr<u64>,
        out_fd: FileDesc,
        mut out_offset: UserInOutPtr<u64>,
        count: usize,
        flags: usize,
    ) -> SysResult {
        info!(
            "copy_file_range: in={:?}, out={:?}, in_offset={:?}, out_offset={:?}, count={}, flags={}",
            in_fd, out_fd, in_offset, out_offset, count, flags
        );
        let proc = self.linux_process();
        let in_file = proc.get_file(in_fd)?;
        let out_file = proc.get_file(out_fd)?;
        let mut buffer = [0u8; 1024];
        // for in_offset and out_offset
        // null means update file offset
        // non-null means update {in,out}_offset instead
        let mut read_offset = if !in_offset.is_null() {
            in_offset.read()?
        } else {
            in_file.seek(SeekFrom::Current(0))?
        };
        let orig_out_file_offset = out_file.seek(SeekFrom::Current(0))?;
        let write_offset = if !out_offset.is_null() {
            let offset = out_offset.read()?;
            out_file.seek(SeekFrom::Start(offset))?
        } else {
            0
        };
        // read from specified offset and write new offset back
        let mut bytes_read = 0;
        let mut total_written = 0;
        while bytes_read < count {
            let len = buffer.len().min(count - bytes_read);
            let read_len = in_file.read_at(read_offset, &mut buffer[..len]).await?;
            if read_len == 0 {
                break;
            }
            bytes_read += read_len;
            read_offset += read_len as u64;
            let mut bytes_written = 0;
            let mut rlen = read_len;
            while bytes_written < read_len {
                let write_len = out_file.write(&buffer[bytes_written..(bytes_written + rlen)])?;
                if write_len == 0 {
                    info!(
                        "copy_file_range:END_ERR in={:?}, out={:?}, in_offset={:?}, out_offset={:?}, count={} = bytes_read {}, bytes_written {}, write_len {}",
                        in_fd, out_fd, in_offset, out_offset, count, bytes_read, bytes_written, write_len
                    );
                    return Err(LxError::EBADF);
                }
                bytes_written += write_len;
                rlen -= write_len;
            }
            total_written += bytes_written;
        }
        if !in_offset.is_null() {
            in_offset.write(read_offset)?;
        } else {
            in_file.seek(SeekFrom::Current(bytes_read as i64))?;
        }
        out_offset.write_if_not_null(write_offset + total_written as u64)?;
        if !out_offset.is_null() {
            out_file.seek(SeekFrom::Start(orig_out_file_offset))?;
        }
        Ok(total_written)
    }
pub async fn sys_copy_file_range ( & self , in_fd : FileDesc , mut in_offset : UserInOutPtr < u64 > , out_fd : FileDesc , mut out_offset : UserInOutPtr < u64 > , count : usize , flags : usize , ) -> SysResult { info ! ( " " in_fd out_fd in_offset out_offset count flags ) ; let proc = self . linux_process ( ) ; let in_file = proc . get_file ( in_fd ) ? ; let out_file = proc . get_file ( out_fd ) ? ; let mut buffer = [ 0u8 ; 1024 ] ; // for in_offset and out_offset // null means update file offset // non-null means update {in,out}_offset instead let mut read_offset = if ! in_offset . is_null ( ) { in_offset . read ( ) ? } else { in_file . seek ( SeekFrom :: Current ( 0 ) ) ? } ; let orig_out_file_offset = out_file . seek ( SeekFrom :: Current ( 0 ) ) ? ; let write_offset = if ! out_offset . is_null ( ) { let offset = out_offset . read ( ) ? ; out_file . seek ( SeekFrom :: Start ( offset ) ) ? } else { 0 } ; // read from specified offset and write new offset back let mut bytes_read = 0 ; let mut total_written = 0 ; while bytes_read < count { let len = buffer . len ( ) . min ( count - bytes_read ) ; let read_len = in_file . read_at ( read_offset , & mut buffer [ .. len ] ) . await ? ; if read_len == 0 { break ; } bytes_read += read_len ; read_offset += read_len as u64 ; let mut bytes_written = 0 ; let mut rlen = read_len ; while bytes_written < read_len { let write_len = out_file . write ( & buffer [ bytes_written .. ( bytes_written + rlen ) ] ) ? ; if write_len == 0 { info ! ( " " in_fd out_fd in_offset out_offset count bytes_read bytes_written write_len ) ; return Err ( LxError :: EBADF ) ; } bytes_written += write_len ; rlen -= write_len ; } total_written += bytes_written ; } if ! in_offset . is_null ( ) { in_offset . write ( read_offset ) ? ; } else { in_file . seek ( SeekFrom :: Current ( bytes_read as i64 ) ) ? ; } out_offset . write_if_not_null ( write_offset + total_written as u64 ) ? ; if ! out_offset . is_null ( ) { out_file . seek ( SeekFrom :: Start ( orig_out_file_offset ) ) ? ; } Ok ( total_written ) }
copies data between one file descriptor and anothe, read from specified offset and write new offset back
copies data between one file descriptor and anothe read from specified offset and write new offset back
&self
in_fd
FileDesc
in_offset
UserInOutPtr<u64>
out_fd
FileDesc
out_offset
UserInOutPtr<u64>
count
usize
flags
usize
&self
in_fd
FileDesc
in_offset
UserInOutPtr<u64>
out_fd
FileDesc
out_offset
UserInOutPtr<u64>
count
usize
flags
usize