Does _exit in Rust work like in C?

In C, I am used to calling _exit instead of exit when dealing with errors during forks or when doing a double fork to prevent zombies. I see that the libc crate contains _exit so I can still use it. But will the effect be exactly the same in Rust as in C? It seems possible that Rust could arrange for exit handlers to run in ways that C cannot. Will calling libc::_exit in Rust in a forked child prevent all potential interference between the exiting child and its parent?

Is there a reason you don't want to propagate errors up to main then return them?

The libc function should behave the same.

I don't think Rust does anything special with libc's atexit. static resources are never cleaned up in Rust.

At a minimum, that hasn't always been true. I don't know how true it is today. But I'd be surprised if the teams agreed to guarantee it.

I don't see how this (or the opposite) could possibly be true. Rust can call into C and C can call into Rust. Both can access libraries (including the system libc) as if they were C. What could Rust do with exit handlers that C couldn't?

1 Like

I was thinking that Rust could arrange to run certain exit handlers prior to calling a function that doesn't return (a -> ! function) under certain circumstances.

That couldn't work, -> ! means diverges, not exits. An infinite loop that never breaks also diverges (and that is also really common in embedded where main can't return). That infinite loop can still do useful work, it can be the main loop of the program for example. And then there is threading: one thread can diverge while another doesn't.

1 Like

I was speculating that Rust could in principle do at-exit work associated with values that a divergent function cannot access before that function is called - it would know which those values were based on tracking ownership and borrowing. It would be very difficult to test on my own, so I asked. I'm very sorry if you think the question was not worth asking.

I didn't say the question wasn't worth asking, just explaining why it can't work.

Your clarified suggestion wouldn't really work well in practise either: There are just too many ways to smuggle values: thread locals, mutable globals, channels etc.

It could however almost work for locals in the calling function that the escape analysis pass determines never escapes. I believe that it is an LLVM pass (not rust specific). But what about panics (with panic unwinding)? That is a way to return from a diverging function. So Drop still has to be called at the right time in such a situation.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.