[libos] Fix error handling of sendfile
This commit is contained in:
		
							parent
							
								
									eba7e08453
								
							
						
					
					
						commit
						40ad9d1648
					
				| @ -22,28 +22,66 @@ pub fn do_sendfile( | |||||||
|         None => in_file.seek(SeekFrom::Current(0))?, |         None => in_file.seek(SeekFrom::Current(0))?, | ||||||
|     } as usize; |     } as usize; | ||||||
| 
 | 
 | ||||||
|     // read from specified offset and write new offset back
 |     // write_file is used to write buffer into out_file, the closure avoids complex loop structure
 | ||||||
|     let mut bytes_read = 0; |     let mut write_file = |buffer: &[u8]| -> Result<usize> { | ||||||
|     while bytes_read < count { |         let buffer_len = buffer.len(); | ||||||
|         let len = min(buffer.len(), count - bytes_read); |  | ||||||
|         let read_len = in_file.read_at(read_offset, &mut buffer[..len])?; |  | ||||||
|         if read_len == 0 { |  | ||||||
|             break; |  | ||||||
|         } |  | ||||||
|         bytes_read += read_len; |  | ||||||
|         read_offset += read_len; |  | ||||||
|         let mut bytes_written = 0; |         let mut bytes_written = 0; | ||||||
|         while bytes_written < read_len { |         let mut write_error = None; | ||||||
|             let write_len = out_file.write(&buffer[bytes_written..read_len])?; | 
 | ||||||
|             if write_len == 0 { |         while bytes_written < buffer_len { | ||||||
|                 return_errno!(EBADF, "sendfile write return 0"); |             match out_file.write(&buffer[bytes_written..]) { | ||||||
|  |                 Ok(write_len) => { | ||||||
|  |                     debug_assert!(write_len > 0); | ||||||
|  |                     bytes_written += write_len; | ||||||
|  |                 } | ||||||
|  |                 Err(e) => { | ||||||
|  |                     // handle sendmsg return err
 | ||||||
|  |                     write_error = Some(e); | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if bytes_written > 0 { | ||||||
|  |             Ok(bytes_written) | ||||||
|  |         } else { | ||||||
|  |             // if bytes_written = 0, write_error must be Some(e).
 | ||||||
|  |             Err(write_error.unwrap()) | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     // read from specified offset and write new offset back
 | ||||||
|  |     let mut bytes_sent = 0; | ||||||
|  |     let mut send_error = None; | ||||||
|  |     while bytes_sent < count { | ||||||
|  |         let len = min(buffer.len(), count - bytes_sent); | ||||||
|  | 
 | ||||||
|  |         match in_file.read_at(read_offset, &mut buffer[..len]) { | ||||||
|  |             Ok(read_len) if read_len > 0 => match write_file(&buffer[..read_len]) { | ||||||
|  |                 Ok(write_len) => { | ||||||
|  |                     bytes_sent += write_len; | ||||||
|  |                     read_offset += write_len; | ||||||
|  |                 } | ||||||
|  |                 Err(e) => { | ||||||
|  |                     send_error = Some(e); | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |             }, | ||||||
|  |             Ok(..) => break, | ||||||
|  |             Err(e) => { | ||||||
|  |                 send_error = Some(e); | ||||||
|  |                 break; | ||||||
|             } |             } | ||||||
|             bytes_written += write_len; |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if offset.is_none() { |     if offset.is_none() { | ||||||
|         in_file.seek(SeekFrom::Current(bytes_read as i64))?; |         in_file.seek(SeekFrom::Current(bytes_sent as i64))?; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if bytes_sent > 0 { | ||||||
|  |         Ok((bytes_sent, read_offset)) | ||||||
|  |     } else { | ||||||
|  |         send_error.map_or_else(|| Ok((0, read_offset)), |e| Err(e)) | ||||||
|     } |     } | ||||||
|     Ok((bytes_read, read_offset)) |  | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user