Merge pull request #1191 from mpajkowski/os_module

Implement several methods - os module
This commit is contained in:
Noah
2019-07-31 09:11:53 -05:00
committed by GitHub
5 changed files with 208 additions and 0 deletions

14
Cargo.lock generated
View File

@@ -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"

View File

@@ -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))

View File

@@ -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 }

View File

@@ -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(),

View File

@@ -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
}