From 156cf6bc8602b1f1ab6d558471bf6614e36ba212 Mon Sep 17 00:00:00 2001 From: Daniel Watkins Date: Wed, 27 Oct 2021 14:33:37 -0400 Subject: [PATCH 1/2] stdlib/posix.rs: implement mknod --- Lib/test/test_posix.py | 7 ++----- vm/src/stdlib/posix.rs | 45 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 89362ba0a..bb76f2dba 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -1172,11 +1172,8 @@ class PosixTester(unittest.TestCase): posix.close(f) support.rmtree(support.TESTFN + 'dir') - # TODO: RUSTPYTHON: AttributeError: module 'os' has no attribute 'mknod' - # - # @unittest.skipUnless((os.mknod in os.supports_dir_fd) and hasattr(stat, 'S_IFIFO'), - # "test requires both stat.S_IFIFO and dir_fd support for os.mknod()") - @unittest.expectedFailure + @unittest.skipUnless((os.mknod in os.supports_dir_fd) and hasattr(stat, 'S_IFIFO'), + "test requires both stat.S_IFIFO and dir_fd support for os.mknod()") def test_mknod_dir_fd(self): # Test using mknodat() to create a FIFO (the only use specified # by POSIX). diff --git a/vm/src/stdlib/posix.rs b/vm/src/stdlib/posix.rs index 267ecf6f0..749c07b13 100644 --- a/vm/src/stdlib/posix.rs +++ b/vm/src/stdlib/posix.rs @@ -413,6 +413,50 @@ pub mod module { ) } + #[derive(FromArgs)] + struct MknodArgs { + #[pyarg(any)] + path: PyPathLike, + #[pyarg(any)] + mode: libc::mode_t, + #[pyarg(any)] + device: libc::dev_t, + #[pyarg(flatten)] + dir_fd: DirFd<1>, + } + + impl MknodArgs { + fn mknod(self, vm: &VirtualMachine) -> PyResult<()> { + let ret = match self.dir_fd.get_opt() { + None => unsafe { + libc::mknod( + self.path.into_cstring(vm)?.as_ptr(), + self.mode, + self.device, + ) + }, + Some(non_default_fd) => unsafe { + libc::mknodat( + non_default_fd, + self.path.into_cstring(vm)?.as_ptr(), + self.mode, + self.device, + ) + }, + }; + if ret != 0 { + Err(errno_err(vm)) + } else { + Ok(()) + } + } + } + + #[pyfunction] + fn mknod(args: MknodArgs, vm: &VirtualMachine) -> PyResult<()> { + args.mknod(vm) + } + #[cfg(not(target_os = "redox"))] #[pyfunction] fn nice(increment: i32, vm: &VirtualMachine) -> PyResult { @@ -1497,6 +1541,7 @@ pub mod module { SupportFunc::new("lchown", None, None, None), #[cfg(not(target_os = "redox"))] SupportFunc::new("fchown", Some(true), None, Some(true)), + SupportFunc::new("mknod", Some(true), Some(true), Some(false)), SupportFunc::new("umask", Some(false), Some(false), Some(false)), SupportFunc::new("execv", None, None, None), SupportFunc::new("pathconf", Some(true), None, None), From 34950fdd2a9dbddb3e0611af841811b1de4b67dd Mon Sep 17 00:00:00 2001 From: Daniel Watkins Date: Thu, 28 Oct 2021 12:05:48 -0400 Subject: [PATCH 2/2] stdlib/posix.rs: fix mknod for MacOS mknod at isn't available in their libc. --- vm/src/stdlib/posix.rs | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/vm/src/stdlib/posix.rs b/vm/src/stdlib/posix.rs index 749c07b13..90e244de5 100644 --- a/vm/src/stdlib/posix.rs +++ b/vm/src/stdlib/posix.rs @@ -421,24 +421,29 @@ pub mod module { mode: libc::mode_t, #[pyarg(any)] device: libc::dev_t, + #[allow(unused)] #[pyarg(flatten)] dir_fd: DirFd<1>, } impl MknodArgs { + fn _mknod(self, vm: &VirtualMachine) -> PyResult { + Ok(unsafe { + libc::mknod( + self.path.clone().into_cstring(vm)?.as_ptr(), + self.mode, + self.device, + ) + }) + } + #[cfg(not(target_os = "macos"))] fn mknod(self, vm: &VirtualMachine) -> PyResult<()> { let ret = match self.dir_fd.get_opt() { - None => unsafe { - libc::mknod( - self.path.into_cstring(vm)?.as_ptr(), - self.mode, - self.device, - ) - }, + None => self._mknod(vm)?, Some(non_default_fd) => unsafe { libc::mknodat( non_default_fd, - self.path.into_cstring(vm)?.as_ptr(), + self.path.clone().into_cstring(vm)?.as_ptr(), self.mode, self.device, ) @@ -450,6 +455,15 @@ pub mod module { Ok(()) } } + #[cfg(target_os = "macos")] + fn mknod(self, vm: &VirtualMachine) -> PyResult<()> { + let ret = self._mknod(vm)?; + if ret != 0 { + Err(errno_err(vm)) + } else { + Ok(()) + } + } } #[pyfunction] @@ -1541,7 +1555,10 @@ pub mod module { SupportFunc::new("lchown", None, None, None), #[cfg(not(target_os = "redox"))] SupportFunc::new("fchown", Some(true), None, Some(true)), + #[cfg(not(target_os = "macos"))] SupportFunc::new("mknod", Some(true), Some(true), Some(false)), + #[cfg(target_os = "macos")] + SupportFunc::new("mknod", Some(true), Some(false), Some(false)), SupportFunc::new("umask", Some(false), Some(false), Some(false)), SupportFunc::new("execv", None, None, None), SupportFunc::new("pathconf", Some(true), None, None),