|
1 |
| -use crate::stdio::StdioImpl; |
2 |
| -use crate::Error; |
3 |
| -use crate::Stdio; |
| 1 | +use crate::{stdio::StdioImpl, Error, Stdio}; |
4 | 2 |
|
5 |
| -use once_cell::sync::OnceCell; |
| 3 | +use std::{ |
| 4 | + fs::{File, OpenOptions}, |
| 5 | + io, |
| 6 | + os::unix::io::{AsRawFd, RawFd}, |
| 7 | +}; |
6 | 8 |
|
7 |
| -use std::fs::{File, OpenOptions}; |
8 |
| -use std::io; |
9 |
| -use std::os::unix::io::{AsRawFd, RawFd}; |
| 9 | +use libc::{c_int, fcntl, F_GETFL, F_SETFL, O_NONBLOCK}; |
| 10 | +use once_cell::sync::OnceCell; |
10 | 11 | use tokio_pipe::{pipe, PipeRead, PipeWrite};
|
11 | 12 |
|
12 | 13 | fn create_pipe() -> Result<(PipeRead, PipeWrite), Error> {
|
@@ -35,16 +36,39 @@ pub(crate) enum Fd {
|
35 | 36 | Null,
|
36 | 37 | }
|
37 | 38 |
|
| 39 | +fn cvt(ret: c_int) -> io::Result<c_int> { |
| 40 | + if ret == -1 { |
| 41 | + Err(io::Error::last_os_error()) |
| 42 | + } else { |
| 43 | + Ok(ret) |
| 44 | + } |
| 45 | +} |
| 46 | + |
| 47 | +fn set_blocking(fd: RawFd) -> io::Result<()> { |
| 48 | + let flags = cvt(unsafe { fcntl(fd, F_GETFL) })?; |
| 49 | + cvt(unsafe { fcntl(fd, F_SETFL, flags & (!O_NONBLOCK)) })?; |
| 50 | + |
| 51 | + Ok(()) |
| 52 | +} |
| 53 | + |
38 | 54 | impl Fd {
|
39 | 55 | pub(crate) fn as_raw_fd_or_null_fd(&self) -> Result<RawFd, Error> {
|
40 | 56 | use Fd::*;
|
41 | 57 |
|
42 |
| - match self { |
43 |
| - PipeReadEnd(fd) => Ok(AsRawFd::as_raw_fd(fd)), |
44 |
| - PipeWriteEnd(fd) => Ok(AsRawFd::as_raw_fd(fd)), |
| 58 | + let fd = match self { |
| 59 | + PipeReadEnd(fd) => Some(AsRawFd::as_raw_fd(fd)), |
| 60 | + PipeWriteEnd(fd) => Some(AsRawFd::as_raw_fd(fd)), |
| 61 | + |
| 62 | + Borrowed(rawfd) => Some(*rawfd), |
| 63 | + Null => None, |
| 64 | + }; |
| 65 | + |
| 66 | + if let Some(fd) = fd { |
| 67 | + set_blocking(fd).map_err(Error::ChildIo)?; |
45 | 68 |
|
46 |
| - Borrowed(rawfd) => Ok(*rawfd), |
47 |
| - Null => get_null_fd(), |
| 69 | + Ok(fd) |
| 70 | + } else { |
| 71 | + get_null_fd() |
48 | 72 | }
|
49 | 73 | }
|
50 | 74 | }
|
|
0 commit comments