8000 Fix macos shutil (#5248) · RustPython/RustPython@4a93914 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4a93914

Browse files
authored
Fix macos shutil (#5248)
* Fix macos shutil * chmod+follow_symlinks=False calls lchmod
1 parent 1034477 commit 4a93914

File tree

3 files changed

+30
-9
lines changed

3 files changed

+30
-9
lines changed

Lib/test/test_shutil.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,8 +1088,7 @@ def test_copymode_follow_symlinks(self):
10881088
shutil.copymode(src_link, dst_link)
10891089
self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode)
10901090

1091-
# TODO: RUSTPYTHON
1092-
@unittest.expectedFailure
1091+
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
10931092
@unittest.skipUnless(hasattr(os, 'lchmod') or os.name == 'nt', 'requires os.lchmod')
10941093
@os_helper.skip_unless_symlink
10951094
def test_copymode_symlink_to_symlink(self):
@@ -3008,7 +3007,6 @@ def test_unhandled_exception(self):
30083007
self.assertRaises(ZeroDivisionError,
30093008
shutil.copyfile, TESTFN, TESTFN2)
30103009

3011-
@unittest.skipIf(sys.platform == "darwin", "TODO: RUSTPYTHON, OSError.error on macOS")
30123010
def test_exception_on_first_call(self):
30133011
# Emulate a case where the first call to the zero-copy
30143012
# function raises an exception in which case the function is
@@ -3019,7 +3017,6 @@ def test_exception_on_first_call(self):
30193017
with self.assertRaises(_GiveupOnFastCopy):
30203018
self.zerocopy_fun(src, dst)
30213019

3022-
@unittest.skipIf(sys.platform == "darwin", "TODO: RUSTPYTHON, OSError.error on macOS")
30233020
def test_filesystem_full(self):
30243021
# Emulate a case where filesystem is full and sendfile() fails
30253022
# on first call.

vm/src/stdlib/os.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ cfg_if::cfg_if! {
4848
const DEFAULT_DIR_FD: Fd = Fd(AT_FDCWD);
4949

5050
// XXX: AVAILABLE should be a bool, but we can't yet have it as a bool and just cast it to usize
51-
#[derive(Copy, Clone)]
51+
#[derive(Copy, Clone, PartialEq, Eq)]
5252
pub struct DirFd<const AVAILABLE: usize>(pub(crate) [Fd; AVAILABLE]);
5353

5454
impl<const AVAILABLE: usize> Default for DirFd<AVAILABLE> {

vm/src/stdlib/posix.rs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -940,7 +940,13 @@ pub mod module {
940940
vm: &VirtualMachine,
941941
) -> PyResult<()> {
942942
match path {
943-
OsPathOrFd::Path(path) => _chmod(path, dir_fd, mode, follow_symlinks, vm),
943+
OsPathOrFd::Path(path) => {
944+
#[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "netbsd",))]
945+
if !follow_symlinks.0 && dir_fd == Default::default() {
946+
return lchmod(path, mode, vm);
947+
}
948+
_chmod(path, dir_fd, mode, follow_symlinks, vm)
949+
}
944950
OsPathOrFd::Fd< 8000 /span>(fd) => _fchmod(fd, mode, vm),
945951
}
946952
}
@@ -963,10 +969,19 @@ pub mod module {
963969
_fchmod(fd, mode, vm)
964970
}
965971

966-
#[cfg(not(target_os = "redox"))]
972+
#[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "netbsd",))]
967973
#[pyfunction]
968974
fn lchmod(path: OsPath, mode: u32, vm: &VirtualMachine) -> PyResult<()> {
969-
_chmod(path, DirFd::default(), mode, FollowSymlinks(false), vm)
975+
extern "C" {
976+
fn lchmod(path: *const libc::c_char, mode: libc::mode_t) -> libc::c_int;
977+
}
978+
let c_path = path.clone().into_cstring(vm)?;
979+
if unsafe { lchmod(c_path.as_ptr(), mode as libc::mode_t) } == 0 {
980+
Ok(())
981+
} else {
982+
let err = std::io::Error::last_os_error();
983+
Err(IOErrorBuilder::with_filename(&err, path, vm))
984+
}
970985
}
971986

972987
#[pyfunction]
@@ -1691,7 +1706,16 @@ pub mod module {
16911706

16921707
pub(crate) fn support_funcs() -> Vec<SupportFunc> {
16931708
vec![
1694-
SupportFunc::new("chmod", Some(false), Some(false), Some(false)),
1709+
SupportFunc::new(
1710+
"chmod",
1711+
Some(false),
1712+
Some(false),
1713+
Some(cfg!(any(
1714+
target_os = "macos",
1715+
target_os = "freebsd",
1716+
target_os = "netbsd"
1717+
))),
1718+
),
16951719
#[cfg(not(target_os = "redox"))]
16961720
SupportFunc::new("chroot", Some(false), None, None),
16971721
#[cfg(not(target_os = "redox"))]

0 commit comments

Comments
 (0)
0