mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-09 22:49:57 +09:00
Merge pull request #1191 from mpajkowski/os_module
Implement several methods - os module
This commit is contained in:
14
Cargo.lock
generated
14
Cargo.lock
generated
@@ -588,6 +588,18 @@ dependencies = [
|
||||
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nodrop"
|
||||
version = "0.1.13"
|
||||
@@ -1019,6 +1031,7 @@ dependencies = [
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"md-5 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-complex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1913,6 +1926,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
|
||||
"checksum new_debug_unreachable 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f40f005c60db6e03bae699e414c58bf9aa7ea02a2d0b9bfbcf19286cc4c82b30"
|
||||
"checksum nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4dbdc256eaac2e3bd236d93ad999d3479ef775c863dbda3068c4006a92eec51b"
|
||||
"checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce"
|
||||
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
|
||||
"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
|
||||
"checksum num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "57450397855d951f1a41305e54851b1a7b8f5d2e349543a02a2effe25459f718"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import os
|
||||
import time
|
||||
import stat
|
||||
import sys
|
||||
|
||||
from testutils import assert_raises
|
||||
|
||||
@@ -251,3 +252,25 @@ with TestWithTempDir() as tmpdir:
|
||||
assert isinstance(os.supports_fd, set)
|
||||
assert isinstance(os.supports_dir_fd, set)
|
||||
assert isinstance(os.supports_follow_symlinks, set)
|
||||
|
||||
# get pid
|
||||
assert isinstance(os.getpid(), int)
|
||||
|
||||
# unix
|
||||
if "win" not in sys.platform:
|
||||
assert isinstance(os.getegid(), int)
|
||||
assert isinstance(os.getgid(), int)
|
||||
assert isinstance(os.getsid(os.getpid()), int)
|
||||
assert isinstance(os.getuid(), int)
|
||||
assert isinstance(os.geteuid(), int)
|
||||
assert isinstance(os.getppid(), int)
|
||||
assert isinstance(os.getpgid(os.getpid()), int)
|
||||
|
||||
assert os.getppid() < os.getpid()
|
||||
|
||||
if os.getuid() != 0:
|
||||
assert_raises(PermissionError, lambda: os.setgid(42))
|
||||
assert_raises(PermissionError, lambda: os.setegid(42))
|
||||
assert_raises(PermissionError, lambda: os.setpgid(os.getpid(), 42))
|
||||
assert_raises(PermissionError, lambda: os.setuid(42))
|
||||
assert_raises(PermissionError, lambda: os.seteuid(42))
|
||||
|
||||
@@ -61,6 +61,7 @@ maplit = "1.0"
|
||||
proc-macro-hack = { version = "0.5", optional = true }
|
||||
bitflags = "1.1"
|
||||
libc = "0.2"
|
||||
nix = "0.14.1"
|
||||
|
||||
flame = { version = "0.2", optional = true }
|
||||
flamer = { version = "0.3", optional = true }
|
||||
|
||||
@@ -892,6 +892,7 @@ pub fn make_module(vm: &VirtualMachine, module: PyObjectRef) {
|
||||
"FileExistsError" => ctx.exceptions.file_exists_error.clone(),
|
||||
"StopIteration" => ctx.exceptions.stop_iteration.clone(),
|
||||
"SystemError" => ctx.exceptions.system_error.clone(),
|
||||
"PermissionError" => ctx.exceptions.permission_error.clone(),
|
||||
"UnicodeError" => ctx.exceptions.unicode_error.clone(),
|
||||
"UnicodeDecodeError" => ctx.exceptions.unicode_decode_error.clone(),
|
||||
"UnicodeEncodeError" => ctx.exceptions.unicode_encode_error.clone(),
|
||||
|
||||
@@ -6,6 +6,10 @@ use std::time::{Duration, SystemTime};
|
||||
use std::{env, fs};
|
||||
|
||||
use bitflags::bitflags;
|
||||
#[cfg(unix)]
|
||||
use nix::errno::Errno;
|
||||
#[cfg(unix)]
|
||||
use nix::unistd::{self, Gid, Pid, Uid};
|
||||
use num_traits::cast::ToPrimitive;
|
||||
|
||||
use crate::function::{IntoPyNativeFunc, PyFuncArgs};
|
||||
@@ -174,6 +178,43 @@ fn convert_io_error(vm: &VirtualMachine, err: io::Error) -> PyObjectRef {
|
||||
os_error
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn convert_nix_error(vm: &VirtualMachine, err: nix::Error) -> PyObjectRef {
|
||||
let nix_error = match err {
|
||||
nix::Error::InvalidPath => {
|
||||
let exc_type = vm.ctx.exceptions.file_not_found_error.clone();
|
||||
vm.new_exception(exc_type, err.to_string())
|
||||
}
|
||||
nix::Error::InvalidUtf8 => {
|
||||
let exc_type = vm.ctx.exceptions.unicode_error.clone();
|
||||
vm.new_exception(exc_type, err.to_string())
|
||||
}
|
||||
nix::Error::UnsupportedOperation => {
|
||||
let exc_type = vm.ctx.exceptions.runtime_error.clone();
|
||||
vm.new_exception(exc_type, err.to_string())
|
||||
}
|
||||
nix::Error::Sys(errno) => {
|
||||
let exc_type = convert_nix_errno(vm, errno);
|
||||
vm.new_exception(exc_type, err.to_string())
|
||||
}
|
||||
};
|
||||
|
||||
if let nix::Error::Sys(errno) = err {
|
||||
vm.set_attr(&nix_error, "errno", vm.ctx.new_int(errno as i32))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
nix_error
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn convert_nix_errno(vm: &VirtualMachine, errno: Errno) -> PyClassRef {
|
||||
match errno {
|
||||
Errno::EPERM => vm.ctx.exceptions.permission_error.clone(),
|
||||
_ => vm.ctx.exceptions.os_error.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn os_error(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(
|
||||
vm,
|
||||
@@ -709,6 +750,105 @@ fn os_rename(src: PyStringRef, dst: PyStringRef, vm: &VirtualMachine) -> PyResul
|
||||
fs::rename(&src.value, &dst.value).map_err(|err| convert_io_error(vm, err))
|
||||
}
|
||||
|
||||
fn os_getpid(vm: &VirtualMachine) -> PyObjectRef {
|
||||
let pid = std::process::id();
|
||||
vm.new_int(pid)
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn os_getppid(vm: &VirtualMachine) -> PyObjectRef {
|
||||
let ppid = unistd::getppid().as_raw();
|
||||
vm.new_int(ppid)
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn os_getgid(vm: &VirtualMachine) -> PyObjectRef {
|
||||
let gid = unistd::getgid().as_raw();
|
||||
vm.new_int(gid)
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn os_getegid(vm: &VirtualMachine) -> PyObjectRef {
|
||||
let egid = unistd::getegid().as_raw();
|
||||
vm.new_int(egid)
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn os_getpgid(pid: PyIntRef, vm: &VirtualMachine) -> PyObjectRef {
|
||||
let pid = pid.as_bigint().to_u32().unwrap();
|
||||
|
||||
match unistd::getpgid(Some(Pid::from_raw(pid as i32))) {
|
||||
Ok(pgid) => vm.new_int(pgid.as_raw()),
|
||||
Err(err) => convert_nix_error(vm, err),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn os_getsid(pid: PyIntRef, vm: &VirtualMachine) -> PyObjectRef {
|
||||
let pid = pid.as_bigint().to_u32().unwrap();
|
||||
|
||||
match unistd::getsid(Some(Pid::from_raw(pid as i32))) {
|
||||
Ok(sid) => vm.new_int(sid.as_raw()),
|
||||
Err(err) => convert_nix_error(vm, err),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn os_getuid(vm: &VirtualMachine) -> PyObjectRef {
|
||||
let uid = unistd::getuid().as_raw();
|
||||
vm.new_int(uid)
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn os_geteuid(vm: &VirtualMachine) -> PyObjectRef {
|
||||
let euid = unistd::geteuid().as_raw();
|
||||
vm.new_int(euid)
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn os_setgid(gid: PyIntRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let gid = gid.as_bigint().to_u32().unwrap();
|
||||
|
||||
unistd::setgid(Gid::from_raw(gid)).map_err(|err| convert_nix_error(vm, err))
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn os_setegid(egid: PyIntRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let egid = egid.as_bigint().to_u32().unwrap();
|
||||
|
||||
unistd::setegid(Gid::from_raw(egid)).map_err(|err| convert_nix_error(vm, err))
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn os_setpgid(pid: PyIntRef, pgid: PyIntRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let pid = pid.as_bigint().to_u32().unwrap();
|
||||
let pgid = pgid.as_bigint().to_u32().unwrap();
|
||||
|
||||
unistd::setpgid(Pid::from_raw(pid as i32), Pid::from_raw(pgid as i32))
|
||||
.map_err(|err| convert_nix_error(vm, err))
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn os_setsid(vm: &VirtualMachine) -> PyResult<()> {
|
||||
unistd::setsid()
|
||||
.map(|_ok| ())
|
||||
.map_err(|err| convert_nix_error(vm, err))
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn os_setuid(uid: PyIntRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let uid = uid.as_bigint().to_u32().unwrap();
|
||||
|
||||
unistd::setuid(Uid::from_raw(uid)).map_err(|err| convert_nix_error(vm, err))
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn os_seteuid(euid: PyIntRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let euid = euid.as_bigint().to_u32().unwrap();
|
||||
|
||||
unistd::seteuid(Uid::from_raw(euid)).map_err(|err| convert_nix_error(vm, err))
|
||||
}
|
||||
|
||||
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
let ctx = &vm.ctx;
|
||||
|
||||
@@ -832,6 +972,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
"R_OK" => ctx.new_int(4),
|
||||
"W_OK" => ctx.new_int(2),
|
||||
"X_OK" => ctx.new_int(1),
|
||||
"getpid" => ctx.new_rustfunc(os_getpid)
|
||||
});
|
||||
|
||||
for support in support_funcs {
|
||||
@@ -863,5 +1004,33 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
"supports_follow_symlinks" => supports_follow_symlinks.into_object(),
|
||||
});
|
||||
|
||||
extend_module_platform_specific(&vm, module)
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn extend_module_platform_specific(vm: &VirtualMachine, module: PyObjectRef) -> PyObjectRef {
|
||||
let ctx = &vm.ctx;
|
||||
|
||||
extend_module!(vm, module, {
|
||||
"getppid" => ctx.new_rustfunc(os_getppid),
|
||||
"getgid" => ctx.new_rustfunc(os_getgid),
|
||||
"getegid" => ctx.new_rustfunc(os_getegid),
|
||||
"getpgid" => ctx.new_rustfunc(os_getpgid),
|
||||
"getsid" => ctx.new_rustfunc(os_getsid),
|
||||
"getuid" => ctx.new_rustfunc(os_getuid),
|
||||
"geteuid" => ctx.new_rustfunc(os_geteuid),
|
||||
"setgid" => ctx.new_rustfunc(os_setgid),
|
||||
"setegid" => ctx.new_rustfunc(os_setegid),
|
||||
"setpgid" => ctx.new_rustfunc(os_setpgid),
|
||||
"setsid" => ctx.new_rustfunc(os_setsid),
|
||||
"setuid" => ctx.new_rustfunc(os_setuid),
|
||||
"seteuid" => ctx.new_rustfunc(os_seteuid),
|
||||
});
|
||||
|
||||
module
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
fn extend_module_platform_specific(_vm: &VirtualMachine, module: PyObjectRef) -> PyObjectRef {
|
||||
module
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user