Skip to content

Commit

Permalink
Fix Builder on cfg(not(any(unix, windows)))
Browse files Browse the repository at this point in the history
- cfg(target_arch = "wasm32") would panic if you tried to do any std::fs
  Builder stuff, which was fine for wasm32-unknown-unknown and
  wasm32-unknown-emscripten, but not good for wasm32-wasi, which has a
  file system.

  (Might still want a specialised implementation for wasm32-wasi:
  std::os::wasi::fs::FileTypeExt is currently unstable, but offers
  is_block_device, is_character_device, is_socket_dgram and
  is_socket_stream. But this one is good to start with.)

- cfg(not(any(unix, windows, target_arch = "wasm32"))) would fail to
  compile (… unless you disabled the builder feature, since my previous
  commit).

Now it all works pretty decently.
  • Loading branch information
chris-morgan committed Jan 7, 2022
1 parent 2fb7496 commit b031dee
Showing 1 changed file with 39 additions and 31 deletions.
70 changes: 39 additions & 31 deletions src/header.rs
Expand Up @@ -736,12 +736,6 @@ impl Header {
}
}

#[cfg(all(target_arch = "wasm32", feature = "builder"))]
#[allow(unused_variables)]
fn fill_platform_from(&mut self, meta: &fs::Metadata, mode: HeaderMode) {
unimplemented!();
}

#[cfg(all(unix, feature = "builder"))]
fn fill_platform_from(&mut self, meta: &fs::Metadata, mode: HeaderMode) {
match mode {
Expand Down Expand Up @@ -801,39 +795,53 @@ impl Header {
}
}

#[cfg(all(windows, feature = "builder"))]
#[cfg(all(not(unix), feature = "builder"))]
#[allow(unused_variables)]
fn fill_platform_from(&mut self, meta: &fs::Metadata, mode: HeaderMode) {
// There's no concept of a file mode on Windows, so do a best approximation here.
match mode {
// Fallback implementation: approximate modes, and get as good an mtime as we can.
let mtime = match mode {
#[cfg(windows)]
HeaderMode::Complete => {
self.set_uid(0);
self.set_gid(0);
// The dates listed in tarballs are always seconds relative to
// January 1, 1970. On Windows, however, the timestamps are returned as
// dates relative to January 1, 1601 (in 100ns intervals), so we need to
// add in some offset for those dates.
let mtime = (meta.last_write_time() / (1_000_000_000 / 100)) - 11644473600;
self.set_mtime(mtime);
let fs_mode = {
const FILE_ATTRIBUTE_READONLY: u32 = 0x00000001;
let readonly = meta.file_attributes() & FILE_ATTRIBUTE_READONLY;
match (meta.is_dir(), readonly != 0) {
(true, false) => 0o755,
(true, true) => 0o555,
(false, false) => 0o644,
(false, true) => 0o444,
}
};
self.set_mode(fs_mode);
(meta.last_write_time() / (1_000_000_000 / 100)) - 11644473600
}
HeaderMode::Deterministic => {
self.set_uid(0);
self.set_gid(0);
self.set_mtime(123456789); // see above in unix
let fs_mode = if meta.is_dir() { 0o755 } else { 0o644 };
self.set_mode(fs_mode);
#[cfg(not(windows))]
HeaderMode::Complete => {
meta.modified()
.ok()
.and_then(|time| time.duration_since(std::time::SystemTime::UNIX_EPOCH).ok())
.map(|duration| duration.as_secs())
.unwrap_or(1) // avoiding zero mtimes, see above in unix
}
}
HeaderMode::Deterministic => 123456789, // see above in unix
};
let fs_mode = match mode {
#[cfg(windows)]
HeaderMode::Complete => {
const FILE_ATTRIBUTE_READONLY: u32 = 0x00000001;
let readonly = meta.file_attributes() & FILE_ATTRIBUTE_READONLY;
match (meta.is_dir(), readonly != 0) {
(true, false) => 0o755,
(true, true) => 0o555,
(false, false) => 0o644,
(false, true) => 0o444,
}
}
_ => {
if meta.is_dir() {
0o755
} else {
0o644
}
}
};
self.set_uid(0);
self.set_gid(0);
self.set_mtime(mtime);
self.set_mode(fs_mode);

let ft = meta.file_type();
self.set_entry_type(if ft.is_dir() {
Expand Down

0 comments on commit b031dee

Please sign in to comment.