Skip to content

Commit 50f91f3

Browse files
committed
Fix windows inode to use u128
1 parent db95946 commit 50f91f3

File tree

2 files changed

+26
-11
lines changed

2 files changed

+26
-11
lines changed

crates/vm/src/stdlib/os.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -508,10 +508,10 @@ pub(super) mod _os {
508508
mode: OutputMode,
509509
stat: OnceCell<PyObjectRef>,
510510
lstat: OnceCell<PyObjectRef>,
511-
#[cfg(unix)]
511+
#[cfg(not(windows))]
512512
ino: AtomicCell<u64>,
513-
#[cfg(not(unix))]
514-
ino: AtomicCell<Option<u64>>,
513+
#[cfg(windows)]
514+
ino: AtomicCell<Option<u128>>,
515515
}
516516

517517
#[pyclass(with(Representable, Unconstructible))]
@@ -608,9 +608,9 @@ pub(super) mod _os {
608608
Ok(stat.clone())
609609
}
610610

611-
#[cfg(not(unix))]
611+
#[cfg(windows)]
612612
#[pymethod]
613-
fn inode(&self, vm: &VirtualMachine) -> PyResult<u64> {
613+
fn inode(&self, vm: &VirtualMachine) -> PyResult<u128> {
614614
match self.ino.load() {
615615
Some(ino) => Ok(ino),
616616
None => {
@@ -625,14 +625,19 @@ pub(super) mod _os {
625625
)
626626
.map_err(|e| e.into_pyexception(vm))?
627627
.ok_or_else(|| crate::exceptions::cstring_error(vm))?;
628+
// On Windows, combine st_ino and st_ino_high into 128-bit value
629+
#[cfg(windows)]
630+
let ino: u128 = stat.st_ino as u128 | ((stat.st_ino_high as u128) << 64);
631+
#[cfg(not(windows))]
632+
let ino: u128 = stat.st_ino as u128;
628633
// Err(T) means other thread set `ino` at the mean time which is safe to ignore
629-
let _ = self.ino.compare_exchange(None, Some(stat.st_ino));
630-
Ok(stat.st_ino)
634+
let _ = self.ino.compare_exchange(None, Some(ino));
635+
Ok(ino)
631636
}
632637
}
633638
}
634639

635-
#[cfg(unix)]
640+
#[cfg(not(windows))]
636641
#[pymethod]
637642
fn inode(&self, _vm: &VirtualMachine) -> PyResult<u64> {
638643
Ok(self.ino.load())
@@ -882,9 +887,16 @@ pub(super) mod _os {
882887
#[cfg(not(windows))]
883888
let st_file_attributes = 0;
884889

890+
// On Windows, combine st_ino and st_ino_high into a 128-bit value
891+
// like _pystat_l128_from_l64_l64
892+
#[cfg(windows)]
893+
let st_ino: u128 = stat.st_ino as u128 | ((stat.st_ino_high as u128) << 64);
894+
#[cfg(not(windows))]
895+
let st_ino: u64 = stat.st_ino;
896+
885897
Self {
886898
st_mode: vm.ctx.new_pyref(stat.st_mode),
887-
st_ino: vm.ctx.new_pyref(stat.st_ino),
899+
st_ino: vm.ctx.new_pyref(st_ino),
888900
st_dev: vm.ctx.new_pyref(stat.st_dev),
889901
st_nlink: vm.ctx.new_pyref(stat.st_nlink),
890902
st_uid: vm.ctx.new_pyref(stat.st_uid),

crates/vm/src/windows.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -515,8 +515,11 @@ fn win32_xstat_impl(path: &OsStr, traverse: bool) -> std::io::Result<StatStruct>
515515
{
516516
let mut result =
517517
crate::common::fileutils::windows::stat_basic_info_to_stat(&stat_info);
518-
result.update_st_mode_from_path(path, stat_info.FileAttributes);
519-
return Ok(result);
518+
// If st_ino is 0, fall through to slow path to get proper file ID
519+
if result.st_ino != 0 || result.st_ino_high != 0 {
520+
result.update_st_mode_from_path(path, stat_info.FileAttributes);
521+
return Ok(result);
522+
}
520523
}
521524
}
522525
Err(e) => {

0 commit comments

Comments
 (0)