Skip to content

Commit 26bcb1f

Browse files
coolreader18youknowone
authored andcommitted
Add os.access on windows
1 parent d40533b commit 26bcb1f

File tree

1 file changed

+26
-10
lines changed

1 file changed

+26
-10
lines changed

vm/src/stdlib/os.rs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
use std::convert::TryFrom;
21
use std::ffi;
32
use std::fs::File;
43
use std::fs::OpenOptions;
54
use std::io::{self, ErrorKind, Read, Write};
6-
use std::mem::MaybeUninit;
75
#[cfg(unix)]
86
use std::os::unix::fs::OpenOptionsExt;
97
#[cfg(windows)]
@@ -46,6 +44,8 @@ use crate::vm::VirtualMachine;
4644
// just to avoid unused import warnings
4745
#[cfg(unix)]
4846
use crate::pyobject::PyIterable;
47+
#[cfg(unix)]
48+
use std::convert::TryFrom;
4949

5050
#[cfg(windows)]
5151
pub const MODULE_NAME: &str = "nt";
@@ -135,6 +135,11 @@ impl PyPathLike {
135135
mode: OutputMode::String,
136136
}
137137
}
138+
#[cfg(windows)]
139+
pub fn wide(&self) -> Vec<u16> {
140+
use std::os::windows::ffi::OsStrExt;
141+
self.path.encode_wide().chain(std::iter::once(0)).collect()
142+
}
138143
}
139144

140145
impl TryFromObject for PyPathLike {
@@ -409,19 +414,17 @@ fn getgroups() -> nix::Result<Vec<Gid>> {
409414
}
410415

411416
#[cfg(unix)]
412-
fn os_access(path: PyStringRef, mode: u8, vm: &VirtualMachine) -> PyResult<bool> {
417+
fn os_access(path: PyPathLike, mode: u8, vm: &VirtualMachine) -> PyResult<bool> {
413418
use std::os::unix::fs::MetadataExt;
414419

415-
let path = path.as_str();
416-
417420
let flags = AccessFlags::from_bits(mode).ok_or_else(|| {
418421
vm.new_value_error(
419422
"One of the flags is wrong, there are only 4 possibilities F_OK, R_OK, W_OK and X_OK"
420423
.to_owned(),
421424
)
422425
})?;
423426

424-
let metadata = fs::metadata(path);
427+
let metadata = fs::metadata(&path.path);
425428

426429
// if it's only checking for F_OK
427430
if flags == AccessFlags::F_OK {
@@ -443,6 +446,19 @@ fn os_access(path: PyStringRef, mode: u8, vm: &VirtualMachine) -> PyResult<bool>
443446

444447
Ok(r_ok && w_ok && x_ok)
445448
}
449+
#[cfg(windows)]
450+
fn os_access(path: PyPathLike, mode: u8) -> bool {
451+
use winapi::um::{fileapi, winnt};
452+
let attr = unsafe { fileapi::GetFileAttributesW(path.wide().as_ptr()) };
453+
attr != fileapi::INVALID_FILE_ATTRIBUTES
454+
&& (mode & 2 == 0
455+
|| attr & winnt::FILE_ATTRIBUTE_READONLY == 0
456+
|| attr & winnt::FILE_ATTRIBUTE_DIRECTORY != 0)
457+
}
458+
#[cfg(not(any(unix, windows)))]
459+
fn os_access(path: PyStringRef, mode: u8, vm: &VirtualMachine) -> PyResult<bool> {
460+
unimplemented!()
461+
}
446462

447463
fn os_error(message: OptionalArg<PyStringRef>, vm: &VirtualMachine) -> PyResult {
448464
let msg = message.map_or("".to_owned(), |msg| msg.as_str().to_owned());
@@ -1608,6 +1624,7 @@ fn envp_from_dict(dict: PyDictRef, vm: &VirtualMachine) -> PyResult<Vec<ffi::CSt
16081624
.collect()
16091625
}
16101626

1627+
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "macos"))]
16111628
#[derive(FromArgs)]
16121629
struct PosixSpawnArgs {
16131630
#[pyarg(positional_only)]
@@ -1639,7 +1656,7 @@ impl PosixSpawnArgs {
16391656
.map_err(|_| vm.new_value_error("path should not have nul bytes".to_owned()))?;
16401657

16411658
let mut file_actions = unsafe {
1642-
let mut fa = MaybeUninit::uninit();
1659+
let mut fa = std::mem::MaybeUninit::uninit();
16431660
assert!(libc::posix_spawn_file_actions_init(fa.as_mut_ptr()) == 0);
16441661
fa.assume_init()
16451662
};
@@ -1691,7 +1708,7 @@ impl PosixSpawnArgs {
16911708
}
16921709

16931710
let mut attrp = unsafe {
1694-
let mut sa = MaybeUninit::uninit();
1711+
let mut sa = std::mem::MaybeUninit::uninit();
16951712
assert!(libc::posix_spawnattr_init(sa.as_mut_ptr()) == 0);
16961713
sa.assume_init()
16971714
};
@@ -1857,7 +1874,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
18571874
#[allow(unused_mut)]
18581875
let mut support_funcs = vec![
18591876
SupportFunc::new(vm, "open", os_open, None, Some(false), None),
1860-
// access Some Some None
1877+
SupportFunc::new(vm, "access", os_access, Some(false), Some(false), None),
18611878
SupportFunc::new(vm, "chdir", os_chdir, Some(false), None, None),
18621879
// chflags Some, None Some
18631880
// chown Some Some Some
@@ -1973,7 +1990,6 @@ fn extend_module_platform_specific(vm: &VirtualMachine, module: &PyObjectRef) {
19731990
let uname_result = UnameResult::make_class(ctx);
19741991

19751992
extend_module!(vm, module, {
1976-
"access" => ctx.new_function(os_access),
19771993
"chmod" => ctx.new_function(os_chmod),
19781994
"get_inheritable" => ctx.new_function(os_get_inheritable), // TODO: windows
19791995
"get_blocking" => ctx.new_function(os_get_blocking),

0 commit comments

Comments
 (0)