bytecodealliance / rustix

Safe Rust bindings to POSIX-ish APIs
Other
1.45k stars 150 forks source link

Support for execveat #490

Open kpcyrd opened 1 year ago

kpcyrd commented 1 year ago

The crate has a really impressive list of syscalls. Since it wraps many *at functions, any chance that execveat (or execve) could be added to the api?

Thanks!

sunfishcode commented 1 year ago

Rustix does have an internal implementation of execveat. It isn't public yet because I was unsure about the implications for I/O safety with exexcve etc. being able to implicitly capture non-CLOEXEC file descriptors. One option I've been considering is to make it a rule that all safe functions that produce new file descriptors must set CLOEXEC on them. Everything in std already does this, to the extent possible, so it's not unreasonable. It's not entirely watertight, because some OS's can't always do this atomically, but it might be good enough and we might be able to explain the gaps by saying that exexve can have some debugger-like behavior in some cases. I'm open to ideas here.

SUPERCILEX commented 1 year ago

I've been considering is to make it a rule that all safe functions that produce new file descriptors must set CLOEXEC on them

What would the API look like if someone actually wants to keep the fd around after exec? That'd be my main concern with the proposed approach.

sunfishcode commented 1 year ago

I've been considering is to make it a rule that all safe functions that produce new file descriptors must set CLOEXEC on them

What would the API look like if someone actually wants to keep the fd around after exec? That'd be my main concern with the proposed approach.

fcntl_setfd can clear the CLOEXEC flag. Or you can dup etc. to get a non-CLOEXEC file descriptor. If we did the above scheme, we'd add unsafe APIs for those, but they:d be available.

SUPERCILEX commented 1 year ago

Gotya, sounds reasonable. :+1:

sunfishcode commented 1 year ago

Making non-CLOEXEC APIs unsafe will be a semver break, so we'll need to do some planning, but I'm now thinking it makes sense to do.

sunfishcode commented 1 year ago

As an update here, with https://github.com/bytecodealliance/rustix/issues/495#issuecomment-1408602386, I no longer think it makes sense to use safety for CLOEXEC.

Looking at the code, the current execveat implementation only supports the linux_raw backend. Rustix aims to keep the linux_raw and libc backends in sync, and it appears the libc crate doesn't yet have bindings for execveat. So the first step here is to add execveat to the libc crate.

valpackett commented 1 year ago

Hmm execveat?? Oh huh, Linux made that unusual syscall and implemented fexecve (POSIX.1-2008) on top of it as a libc function only, instead of directly having an fexecve syscall like FreeBSD does for example:

the execveat() system call is also needed to allow fexecve(3) to be implemented on systems that do not have the /proc filesystem mounted

The libc crate has fexecve bindings on fuchsia, linux_like, freebsdlike, solaris, and newlib already!

rustix should implement fexecve on all supported platforms, and execveat should just be an implementation detail of it in the linux_raw backend, I think.