-
Notifications
You must be signed in to change notification settings - Fork 1.4k
add support for os.fork and related functions #4877
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 16 commits
c5ff3f5
c2dd77d
bd25a54
2efe9bd
3ee4da8
c6da379
d51daaf
9fc8952
137fd29
f98c005
a58e429
cb5166f
ddcae23
63a881c
abce797
7aa1311
5779c89
37b73f3
eaa3e63
e041cbd
ae634d2
e0a2228
f54f715
e27e9e9
6199f76
9ebdf0b
9c525af
84fda43
8918617
123bc2d
844365e
d69426b
20f5abf
3bfe8c8
e2e6844
e5d9bb5
0fd1a9f
47f13b2
35f23be
e19c8fd
c79e2fd
f237e5e
870ef53
fdaefd0
eb01160
669ff59
76b89ce
68a78e4
a854bb6
110fc33
0a2c6fd
af28311
dc087c3
511a448
e4aacf9
72b53a9
f8b966d
9963280
6cd534b
0b8f237
a85ac15
68fc959
90b472b
7b52282
898e084
5ab1706
0b61077
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1127,6 +1127,87 @@ pub(super) mod _os { | |
| OutputMode::String.process_path(curdir_inner(vm)?, vm) | ||
| } | ||
|
|
||
| #[cfg(unix)] | ||
| #[pyfunction] | ||
| fn register_at_fork(kwargs: crate::function::KwArgs, vm: &VirtualMachine) -> PyResult<()> { | ||
| let mut match_found = false; // better way to handle this? | ||
| for (key, value) in kwargs.into_iter() { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no error when key matches none of 3 keys?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For this reason I was using
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If no errors raised for wrong keys, adding a useless KwArgs will be helpful e.g. fn register_at_fork(args: RegisterAtForkArgs, _ignored: Kwargs, vm: ..) -> ...
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I used this but I am getting |
||
| if key == "before" { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. rust conventions prefer
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this be rewritten using a struct with
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rewriting using |
||
| match_found = true; | ||
| vm.state.before_forkers.lock().push(value.clone()); | ||
| } | ||
| if key == "after_in_parent" { | ||
| match_found = true; | ||
| vm.state.after_forkers_parent.lock().push(value.clone()); | ||
| } | ||
| if key == "after_in_child" { | ||
| match_found = true; | ||
| vm.state.after_forkers_child.lock().push(value.clone()); | ||
| } | ||
| } | ||
|
|
||
| if !match_found { | ||
| return Err(vm.new_value_error("At least one argument is required.".to_owned())); | ||
| } | ||
|
|
||
| Ok(()) | ||
| } | ||
|
|
||
| #[cfg(unix)] | ||
| fn run_at_forkers(funcs: Vec<PyObjectRef>, vm: &VirtualMachine) { | ||
| if !funcs.is_empty() { | ||
| for func in funcs.into_iter().rev() { | ||
| if let Err(e) = func.call((), vm) { | ||
| let exit = e.fast_isinstance(vm.ctx.exceptions.system_exit); | ||
| vm.run_unraisable(e, Some("Exception ignored in".to_owned()), func); | ||
| if exit { | ||
| // Do nothing! | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #[cfg(unix)] | ||
| fn py_os_before_fork(vm: &VirtualMachine) -> PyResult<()> { | ||
| let before_forkers: Vec<PyObjectRef> = std::mem::take(&mut *vm.state.before_forkers.lock()); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this not clone but take? So that second run of fork doesn't be affect by it?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually you are right. import os
def a():
print('a')
def b():
print('b')
def c():
os.register_at_fork(before=a)
os.fork()
os.register_at_fork(before=b)
os.fork()
c()yields in cpython. I have remove take operation and now rustpython as same results.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cpython PR: python/cpython#103759 |
||
| run_at_forkers(before_forkers, vm); | ||
|
|
||
| Ok(()) | ||
| } | ||
|
|
||
| #[cfg(unix)] | ||
| fn py_os_after_fork_child(vm: &VirtualMachine) -> PyResult<()> { | ||
| let after_forkers_child: Vec<PyObjectRef> = | ||
| std::mem::take(&mut *vm.state.after_forkers_child.lock()); | ||
| run_at_forkers(after_forkers_child, vm); | ||
| Ok(()) | ||
| } | ||
|
|
||
| #[cfg(unix)] | ||
| fn py_os_after_fork_parent(vm: &VirtualMachine) -> PyResult<()> { | ||
| let after_forkers_parent: Vec<PyObjectRef> = | ||
| std::mem::take(&mut *vm.state.after_forkers_parent.lock()); | ||
| run_at_forkers(after_forkers_parent, vm); | ||
| Ok(()) | ||
| } | ||
|
|
||
| #[cfg(unix)] | ||
| #[pyfunction] | ||
| fn fork(vm: &VirtualMachine) -> PyResult { | ||
|
itsankitkp marked this conversation as resolved.
Outdated
|
||
| let pid: i32; | ||
| py_os_before_fork(vm)?; | ||
| unsafe { | ||
| pid = libc::fork(); | ||
| } | ||
| if pid == 0 { | ||
| py_os_after_fork_child(vm)?; | ||
| } else { | ||
| py_os_after_fork_parent(vm)?; | ||
| } | ||
| Ok(vm.ctx.new_int(pid).into()) | ||
| } | ||
|
|
||
| #[pyfunction] | ||
| fn getcwdb(vm: &VirtualMachine) -> PyResult { | ||
| OutputMode::Bytes.process_path(curdir_inner(vm)?, vm) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this originated from CPython source code?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, got it. it came from later then 3.11.