-
Notifications
You must be signed in to change notification settings - Fork 71
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
Add low-level process support to eio_linux #435
Conversation
Just as a confirmation that using |
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.
Comments in-line.
I'd still like proper clone3
support at some point, but using spawn is fine for now (just not in eio.unix
).
Note that I'm changing the way FDs work a bit in #440, so you might want to rebase on that before changing anything.
Regarding PATH, I'd leave that out of the low-level API (which should just export what the OS provides). |
e7e4d52
to
f5aeb5d
Compare
W.r.t this comment:
We now vendor spawn so have a little more control over what we can do on the C-side of things, did you mean to just mark it as calling |
Yes. |
67e3ae5
to
f38ecdf
Compare
string -> | ||
string list -> | ||
t | ||
(** Spawns a subprocess. If the process has not finished when the switch is released, the process |
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.
This diff is looking really good! Just one thing about the documentation though: there is quite a lot of useful information in the underlying spawn ocamldoc that is worth propagating here, now that the underlying library is no longer exposed. For example, it answers: "what happens if [env] is None" in that documentation, which is quite important to know.
has finished. *) | ||
|
||
val signal : t -> int -> unit | ||
(** [signal t s] send a signal [s] to process [t]. For example to stop a process you could use |
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.
(** [signal t s] send a signal [s] to process [t]. For example to stop a process you could use | |
(** [signal t s] sends a signal [s] to process [t]. For example, to terminate a process use |
confusingly, SIGSTOPing a process is different from SIGTERMing a process :-)
(** [wait t] waits for the process [t] to exit. This blocks the fiber until the process | ||
has finished. *) |
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.
(** [wait t] waits for the process [t] to exit. This blocks the fiber until the process | |
has finished. *) | |
(** [wait t] blocks the fiber until process [t] has terminated, either by | |
exiting or receiving a signal. *) |
The spawn library has a single function that does a lot of stuff, and different platforms will want to provide different features. I'm wondering if it would be better to make it more modular. The basic problem we have is that we can't call OCaml code after forking. However, we can make a list of C functions to call. Here's an experiment that defines a https://github.com/ocaml-multicore/eio/compare/main...talex5:eio:spawn?expand=1 e.g. (I put this in eio_posix, but it's demonstrating the Linux-specific open Eio.Std
module L = Eio_posix.Low_level
let () =
Eio_posix.run @@ fun _env ->
Switch.run @@ fun sw ->
let exe = L.openat ~sw ~mode:0 "/bin/ls" L.Open_flags.(rdonly + excl) in
let dir = L.openat ~sw ~mode:0 "/etc" L.Open_flags.(rdonly + directory + excl) in
let pid = L.spawn ~sw L.Fork_action.[
fchdir dir;
execat exe [| "ls"; "-l" |];
] in
traceln "spawned PID %d" pid Probably some of this could go in Eio_unix and be shared between the various backends. |
|
Cool API. The idea here is that you can have arbitrarily complicated lists of actions right? The example is a simple case that I think (at least in my mind) is easier to understand/code with something like what we have i.e. Do you think the Not quite sure where to go from here, experiment with this API first porting more of the spawn code to this modular approach? |
Yes, I'd expect the high-level API to build this up for you.
You can't do anything after
And being able to do this with
I think that would be built on top. This API is just for stuff that can only happen after forking, where we can't use OCaml.
Yes, I think so. I can try to clean it up over the next couple of days. Do you want to try putting the higher-level API on top after that? |
I currently have a problem where there are some syscalls I need to make after forking but before execing. This is to set up a PTY for the child process. I've got a branch using this PR at the moment, but without the PTY setup. While writing a C wrapper could work, I think @talex5's proposal would provide a good solution for this. |
Sounds good to me :)) |
Closing in favour of #472 :)) |
The next instalment for #330. This adds initial low-level process support to
Eio_linux
using the spawn library which has no dependencies. I started implementing it and realised they already had, and it supports windows and has a lot of signal and error handling built-in that I otherwise would have ended up copying. It is also released under MIT so presumably we could reuse their code to avoid the dependency.I put it under
Eio_unix
because I envisaged reusing spawn with other backends like IOCP/kqueue I think that means we have to addoptional
or something to theeio_unix
library?It doesn't do program resolution so I tried to do that in OCaml, I also default to the paths
[ "/usr/bin"; "/usr/local/bin" ]
if we can't findPATH
-- I don't know if that's reasonable. Also I'm not sure on what error we should raise if we cannot find the program.