◐ Shell
clean mode source ↗

windows umask, win32_xstat_slow_impl, fake EXT_SUFFIX by youknowone · Pull Request #6340 · RustPython/RustPython

fn attribute_data_to_stat( info: &windows_sys::Win32::Storage::FileSystem::BY_HANDLE_FILE_INFORMATION, reparse_tag: u32, basic_info: Option<&windows_sys::Win32::Storage::FileSystem::FILE_BASIC_INFO>, id_info: Option<&windows_sys::Win32::Storage::FileSystem::FILE_ID_INFO>, ) -> StatStruct { use crate::common::fileutils::windows::SECS_BETWEEN_EPOCHS; use windows_sys::Win32::Storage::FileSystem::FILE_ATTRIBUTE_REPARSE_POINT;
let mut st_mode = attributes_to_mode(info.dwFileAttributes); let st_size = ((info.nFileSizeHigh as u64) << 32) | (info.nFileSizeLow as u64); let st_dev = id_info .map(|id| id.VolumeSerialNumber as u32) .unwrap_or(info.dwVolumeSerialNumber); let st_nlink = info.nNumberOfLinks as i32;
// Convert FILETIME/LARGE_INTEGER to (time_t, nsec) let filetime_to_time = |ft_low: u32, ft_high: u32| -> (libc::time_t, i32) { let ticks = ((ft_high as i64) << 32) | (ft_low as i64); let nsec = ((ticks % 10_000_000) * 100) as i32; let sec = (ticks / 10_000_000 - SECS_BETWEEN_EPOCHS) as libc::time_t; (sec, nsec) };
let large_integer_to_time = |li: i64| -> (libc::time_t, i32) { let nsec = ((li % 10_000_000) * 100) as i32; let sec = (li / 10_000_000 - SECS_BETWEEN_EPOCHS) as libc::time_t; (sec, nsec) };
let (st_birthtime, st_birthtime_nsec); let (st_mtime, st_mtime_nsec); let (st_atime, st_atime_nsec);
if let Some(bi) = basic_info { (st_birthtime, st_birthtime_nsec) = large_integer_to_time(bi.CreationTime); (st_mtime, st_mtime_nsec) = large_integer_to_time(bi.LastWriteTime); (st_atime, st_atime_nsec) = large_integer_to_time(bi.LastAccessTime); } else { (st_birthtime, st_birthtime_nsec) = filetime_to_time( info.ftCreationTime.dwLowDateTime, info.ftCreationTime.dwHighDateTime, ); (st_mtime, st_mtime_nsec) = filetime_to_time( info.ftLastWriteTime.dwLowDateTime, info.ftLastWriteTime.dwHighDateTime, ); (st_atime, st_atime_nsec) = filetime_to_time( info.ftLastAccessTime.dwLowDateTime, info.ftLastAccessTime.dwHighDateTime, ); }
// Get file ID from id_info or fallback to file index let (st_ino, st_ino_high) = if let Some(id) = id_info { // FILE_ID_INFO.FileId is FILE_ID_128 which is [u8; 16] let bytes = id.FileId.Identifier; let low = u64::from_le_bytes(bytes[0..8].try_into().unwrap()); let high = u64::from_le_bytes(bytes[8..16].try_into().unwrap()); (low, high) } else { let ino = ((info.nFileIndexHigh as u64) << 32) | (info.nFileIndexLow as u64); (ino, 0u64) };
// Set symlink mode if applicable if info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT != 0 && reparse_tag == IO_REPARSE_TAG_SYMLINK { st_mode = (st_mode & !S_IFMT) | S_IFLNK; }
StatStruct { st_dev, st_ino, st_ino_high, st_mode, st_nlink, st_uid: 0, st_gid: 0, st_rdev: 0, st_size, st_atime, st_atime_nsec, st_mtime, st_mtime_nsec, st_ctime: 0, // Will be set by caller st_ctime_nsec: 0, st_birthtime, st_birthtime_nsec, st_file_attributes: info.dwFileAttributes, st_reparse_tag: reparse_tag, } }