Skip to content

Commit 74e3a7d

Browse files
committed
Auto merge of #8093 - pfmooney:illumos-deps, r=alexcrichton
Update dependencies to support illumos target Several dependencies of cargo require updates in order to build with illumos as the `target_os` platform (rust-lang/rust#55553). Most are patch revisions to include `#[cfg()]` updates. In the case of `fs2`, the maintainer does not appear to be minding activity on the project, so it was forked into `fs3`, maintaining the same interfaces and logic (but featuring the widened platform support).
2 parents 15d8044 + c04a87c commit 74e3a7d

File tree

2 files changed

+134
-27
lines changed

2 files changed

+134
-27
lines changed

Cargo.toml

+3-4
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,9 @@ curl-sys = "0.4.22"
3030
env_logger = "0.7.0"
3131
pretty_env_logger = { version = "0.4", optional = true }
3232
anyhow = "1.0"
33-
filetime = "0.2"
33+
filetime = "0.2.9"
3434
flate2 = { version = "1.0.3", default-features = false, features = ["zlib"] }
35-
fs2 = "0.4"
36-
git2 = "0.13.0"
35+
git2 = "0.13.1"
3736
git2-curl = "0.14.0"
3837
glob = "0.3.0"
3938
hex = "0.4"
@@ -45,7 +44,7 @@ jobserver = "0.1.21"
4544
lazycell = "1.2.0"
4645
libc = "0.2"
4746
log = "0.4.6"
48-
libgit2-sys = "0.12.0"
47+
libgit2-sys = "0.12.1"
4948
memchr = "2.1.3"
5049
num_cpus = "1.0"
5150
opener = "0.4"

src/cargo/util/flock.rs

+131-23
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@ use std::io;
33
use std::io::{Read, Seek, SeekFrom, Write};
44
use std::path::{Display, Path, PathBuf};
55

6-
use fs2::{lock_contended_error, FileExt};
76
use termcolor::Color::Cyan;
8-
#[cfg(windows)]
9-
use winapi::shared::winerror::ERROR_INVALID_FUNCTION;
107

118
use crate::util::errors::{CargoResult, CargoResultExt};
129
use crate::util::paths;
1310
use crate::util::Config;
11+
use sys::*;
1412

1513
#[derive(Debug)]
1614
pub struct FileLock {
@@ -95,7 +93,7 @@ impl Drop for FileLock {
9593
fn drop(&mut self) {
9694
if self.state != State::Unlocked {
9795
if let Some(f) = self.f.take() {
98-
let _ = f.unlock();
96+
let _ = unlock(&f);
9997
}
10098
}
10199
}
@@ -231,13 +229,13 @@ impl Filesystem {
231229
.chain_err(|| format!("failed to open: {}", path.display()))?;
232230
match state {
233231
State::Exclusive => {
234-
acquire(config, msg, &path, &|| f.try_lock_exclusive(), &|| {
235-
f.lock_exclusive()
232+
acquire(config, msg, &path, &|| try_lock_exclusive(&f), &|| {
233+
lock_exclusive(&f)
236234
})?;
237235
}
238236
State::Shared => {
239-
acquire(config, msg, &path, &|| f.try_lock_shared(), &|| {
240-
f.lock_shared()
237+
acquire(config, msg, &path, &|| try_lock_shared(&f), &|| {
238+
lock_shared(&f)
241239
})?;
242240
}
243241
State::Unlocked => {}
@@ -281,8 +279,8 @@ fn acquire(
281279
config: &Config,
282280
msg: &str,
283281
path: &Path,
284-
r#try: &dyn Fn() -> io::Result<()>,
285-
block: &dyn Fn() -> io::Result<()>,
282+
lock_try: &dyn Fn() -> io::Result<()>,
283+
lock_block: &dyn Fn() -> io::Result<()>,
286284
) -> CargoResult<()> {
287285
// File locking on Unix is currently implemented via `flock`, which is known
288286
// to be broken on NFS. We could in theory just ignore errors that happen on
@@ -298,24 +296,16 @@ fn acquire(
298296
return Ok(());
299297
}
300298

301-
match r#try() {
299+
match lock_try() {
302300
Ok(()) => return Ok(()),
303301

304302
// In addition to ignoring NFS which is commonly not working we also
305303
// just ignore locking on filesystems that look like they don't
306-
// implement file locking. We detect that here via the return value of
307-
// locking (e.g., inspecting errno).
308-
#[cfg(unix)]
309-
Err(ref e) if e.raw_os_error() == Some(libc::ENOTSUP) => return Ok(()),
310-
311-
#[cfg(target_os = "linux")]
312-
Err(ref e) if e.raw_os_error() == Some(libc::ENOSYS) => return Ok(()),
313-
314-
#[cfg(windows)]
315-
Err(ref e) if e.raw_os_error() == Some(ERROR_INVALID_FUNCTION as i32) => return Ok(()),
304+
// implement file locking.
305+
Err(e) if error_unsupported(&e) => return Ok(()),
316306

317307
Err(e) => {
318-
if e.raw_os_error() != lock_contended_error().raw_os_error() {
308+
if !error_contended(&e) {
319309
let e = anyhow::Error::from(e);
320310
let cx = format!("failed to lock file: {}", path.display());
321311
return Err(e.context(cx).into());
@@ -325,7 +315,7 @@ fn acquire(
325315
let msg = format!("waiting for file lock on {}", msg);
326316
config.shell().status_with_color("Blocking", &msg, Cyan)?;
327317

328-
block().chain_err(|| format!("failed to lock file: {}", path.display()))?;
318+
lock_block().chain_err(|| format!("failed to lock file: {}", path.display()))?;
329319
return Ok(());
330320

331321
#[cfg(all(target_os = "linux", not(target_env = "musl")))]
@@ -352,3 +342,121 @@ fn acquire(
352342
false
353343
}
354344
}
345+
346+
#[cfg(unix)]
347+
mod sys {
348+
use std::fs::File;
349+
use std::io::{Error, Result};
350+
use std::os::unix::io::AsRawFd;
351+
352+
pub(super) fn lock_shared(file: &File) -> Result<()> {
353+
flock(file, libc::LOCK_SH)
354+
}
355+
356+
pub(super) fn lock_exclusive(file: &File) -> Result<()> {
357+
flock(file, libc::LOCK_EX)
358+
}
359+
360+
pub(super) fn try_lock_shared(file: &File) -> Result<()> {
361+
flock(file, libc::LOCK_SH | libc::LOCK_NB)
362+
}
363+
364+
pub(super) fn try_lock_exclusive(file: &File) -> Result<()> {
365+
flock(file, libc::LOCK_EX | libc::LOCK_NB)
366+
}
367+
368+
pub(super) fn unlock(file: &File) -> Result<()> {
369+
flock(file, libc::LOCK_UN)
370+
}
371+
372+
pub(super) fn error_contended(err: &Error) -> bool {
373+
err.raw_os_error().map_or(false, |x| x == libc::EWOULDBLOCK)
374+
}
375+
376+
pub(super) fn error_unsupported(err: &Error) -> bool {
377+
match err.raw_os_error() {
378+
Some(libc::ENOTSUP) => true,
379+
#[cfg(target_os = "linux")]
380+
Some(libc::ENOSYS) => true,
381+
_ => false,
382+
}
383+
}
384+
385+
#[cfg(not(target_os = "solaris"))]
386+
fn flock(file: &File, flag: libc::c_int) -> Result<()> {
387+
let ret = unsafe { libc::flock(file.as_raw_fd(), flag) };
388+
if ret < 0 {
389+
Err(Error::last_os_error())
390+
} else {
391+
Ok(())
392+
}
393+
}
394+
395+
#[cfg(target_os = "solaris")]
396+
fn flock(file: &File, flag: libc::c_int) -> Result<()> {
397+
// Solaris lacks flock(), so simply succeed with a no-op
398+
Ok(())
399+
}
400+
}
401+
402+
#[cfg(windows)]
403+
mod sys {
404+
use std::fs::File;
405+
use std::io::{Error, Result};
406+
use std::mem;
407+
use std::os::windows::io::AsRawHandle;
408+
409+
use winapi::shared::minwindef::DWORD;
410+
use winapi::shared::winerror::{ERROR_INVALID_FUNCTION, ERROR_LOCK_VIOLATION};
411+
use winapi::um::fileapi::{LockFileEx, UnlockFile};
412+
use winapi::um::minwinbase::{LOCKFILE_EXCLUSIVE_LOCK, LOCKFILE_FAIL_IMMEDIATELY};
413+
414+
pub(super) fn lock_shared(file: &File) -> Result<()> {
415+
lock_file(file, 0)
416+
}
417+
418+
pub(super) fn lock_exclusive(file: &File) -> Result<()> {
419+
lock_file(file, LOCKFILE_EXCLUSIVE_LOCK)
420+
}
421+
422+
pub(super) fn try_lock_shared(file: &File) -> Result<()> {
423+
lock_file(file, LOCKFILE_FAIL_IMMEDIATELY)
424+
}
425+
426+
pub(super) fn try_lock_exclusive(file: &File) -> Result<()> {
427+
lock_file(file, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY)
428+
}
429+
430+
pub(super) fn error_contended(err: &Error) -> bool {
431+
err.raw_os_error()
432+
.map_or(false, |x| x == ERROR_LOCK_VIOLATION as i32)
433+
}
434+
435+
pub(super) fn error_unsupported(err: &Error) -> bool {
436+
err.raw_os_error()
437+
.map_or(false, |x| x == ERROR_INVALID_FUNCTION as i32)
438+
}
439+
440+
pub(super) fn unlock(file: &File) -> Result<()> {
441+
unsafe {
442+
let ret = UnlockFile(file.as_raw_handle(), 0, 0, !0, !0);
443+
if ret == 0 {
444+
Err(Error::last_os_error())
445+
} else {
446+
Ok(())
447+
}
448+
}
449+
}
450+
451+
fn lock_file(file: &File, flags: DWORD) -> Result<()> {
452+
unsafe {
453+
let mut overlapped = mem::zeroed();
454+
let ret = LockFileEx(file.as_raw_handle(), flags, 0, !0, !0, &mut overlapped);
455+
if ret == 0 {
456+
Err(Error::last_os_error())
457+
} else {
458+
Ok(())
459+
}
460+
}
461+
}
462+
}

0 commit comments

Comments
 (0)