Skip to content

Commit c4de7d1

Browse files
committed
Fix Client::configure* on unix
rust-lang#100 Signed-off-by: Jiahao XU <[email protected]>
1 parent 8785d86 commit c4de7d1

File tree

1 file changed

+41
-18
lines changed

1 file changed

+41
-18
lines changed

src/unix.rs

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,19 @@ use libc::c_int;
1515

1616
use crate::Command;
1717

18+
#[derive(Debug)]
19+
enum ClientCreationArg {
20+
Fds { read: c_int, write: c_int },
21+
Fifo(Box<Path>),
22+
}
23+
1824
#[derive(Debug)]
1925
pub struct Client {
2026
/// This fd is set to be nonblocking
2127
read: File,
2228
/// This fd is set to be blocking
2329
write: File,
24-
/// Path to the named fifo if any
25-
path: Option<Box<Path>>,
30+
creation_arg: ClientCreationArg,
2631
/// If the Client owns the fifo, then we should remove it on drop.
2732
owns_fifo: bool,
2833
}
@@ -78,7 +83,7 @@ impl Client {
7883
let client = Self {
7984
read: file.try_clone()?,
8085
write: file,
81-
path: Some(name.into_boxed_path()),
86+
creation_arg: ClientCreationArg::Fifo(name.into_boxed_path()),
8287
owns_fifo: true,
8388
};
8489

@@ -131,13 +136,13 @@ impl Client {
131136

132137
/// `--jobserver-auth=fifo:PATH`
133138
fn from_fifo(path: &Path) -> Option<Self> {
134-
let file = open_file_rw(path).ok()?;
139+
let read = open_file_rw(path).ok()?;
135140

136-
if is_pipe(&file)? {
141+
if is_pipe(&read)? {
137142
Some(Self {
138-
read: file.try_clone().ok()?,
139-
write: file,
140-
path: Some(path.into()),
143+
read,
144+
write: open_file_rw(path).ok()?,
145+
creation_arg: ClientCreationArg::Fifo(path.into()),
141146
owns_fifo: false,
142147
})
143148
} else {
@@ -152,6 +157,8 @@ impl Client {
152157
let read = read.parse().ok()?;
153158
let write = write.parse().ok()?;
154159

160+
let creation_arg = ClientCreationArg::Fds { read, write };
161+
155162
let read = ManuallyDrop::new(File::from_raw_fd(read));
156163
let write = ManuallyDrop::new(File::from_raw_fd(write));
157164

@@ -183,6 +190,19 @@ impl Client {
183190
//
184191
// I tested this on macOS 14 and Linux 6.5.13
185192
#[cfg(target_os = "linux")]
193+
if let (Ok(read), Ok(write)) = (
194+
File::open(format!("/dev/fd/{}", read)),
195+
OpenOptions::new()
196+
.write(true)
197+
.open(format!("/dev/fd/{}", write)),
198+
) {
199+
return Ok(Some(Client {
200+
read,
201+
write,
202+
creation_arg,
203+
owns_fifo: false,
204+
}));
205+
}
186206
if let Some(jobserver) =
187207
Self::from_fifo(Path::new(&format!("/dev/fd/{}", read.as_raw_fd())))
188208
{
@@ -195,7 +215,7 @@ impl Client {
195215
Some(Self {
196216
read,
197217
write,
198-
path: None,
218+
creation_arg,
199219
owns_fifo: false,
200220
})
201221
}
@@ -207,7 +227,7 @@ impl Client {
207227
Self {
208228
read: File::from_raw_fd(read),
209229
write: File::from_raw_fd(write),
210-
path: None,
230+
creation_arg: ClientCreationArg::Fds { read, write },
211231
owns_fifo: false,
212232
}
213233
}
@@ -268,15 +288,18 @@ impl Client {
268288
}
269289

270290
pub fn string_arg(&self) -> Cow<'_, str> {
271-
Cow::Owned(format!(
272-
"{},{}",
273-
self.read.as_raw_fd(),
274-
self.write.as_raw_fd()
275-
))
291+
Cow::Owned(match &self.creation_arg {
292+
ClientCreationArg::Fifo(path) => format!("fifo:{}", path.display()),
293+
ClientCreationArg::Fds { read, write } => format!("{},{}", read, write),
294+
})
276295
}
277296

278297
pub fn get_fifo(&self) -> Option<&Path> {
279-
self.path.as_deref()
298+
if let ClientCreationArg::Fifo(path) = &self.creation_arg {
299+
Some(path)
300+
} else {
301+
None
302+
}
280303
}
281304

282305
pub fn pre_run<Cmd>(&self, cmd: &mut Cmd)
@@ -309,7 +332,7 @@ impl Client {
309332
}
310333

311334
pub fn is_try_acquire_safe(&self) -> bool {
312-
self.path.is_some()
335+
self.get_fifo().is_some()
313336
}
314337

315338
pub fn set_nonblocking(&self) -> io::Result<()> {
@@ -325,7 +348,7 @@ impl Client {
325348

326349
impl Drop for Client {
327350
fn drop(&mut self) {
328-
if let Some(path) = &self.path {
351+
if let Some(path) = self.get_fifo() {
329352
if self.owns_fifo {
330353
fs::remove_file(path).ok();
331354
}

0 commit comments

Comments
 (0)