Live data from Hacker News

Fixing Ctrl+C in Rust terminal apps: Child process management

fiveonefour.com

51–60 of 62 posts

Re: Fixing Ctrl+C in Rust terminal apps: Child process management

#51
post #37
post #35

It seems wrong that the app would be responsible for cleanup... Shouldn't this be solved in the shell / terminal ? What if kill -9?

When you use ctrl+c, you are not killing the program, you are sending it a SIGTERM signal which essentially means « could you please stop yourself ? » so the program have a chance to clean things before exiting. kill -9 is sending a SIGKILL signal which, well, kills the program immediately.

ctrl-c sends SIGINT.

Re: Fixing Ctrl+C in Rust terminal apps: Child process management

#52
post #37
post #35

It seems wrong that the app would be responsible for cleanup... Shouldn't this be solved in the shell / terminal ? What if kill -9?

When you use ctrl+c, you are not killing the program, you are sending it a SIGTERM signal which essentially means « could you please stop yourself ? » so the program have a chance to clean things before exiting. kill -9 is sending a SIGKILL signal which, well, kills the program immediately.

SIGINT, not SIGTERM.

Re: Fixing Ctrl+C in Rust terminal apps: Child process management

#53
post #38

Earlier quoted context omitted.

Child processes are created using, generally, 2 syscalls: fork, then exec. When you fork, all file descriptors the main process has open are copied, and are now open in two places. Then, when the child calls exec (to transform itself into the target program), all file descriptors stay open in the new process (unless a specific fd is explicitly configured otherwise, FD_CLOEXEC). Standard output are just file descripto…

> Conceptually, you think of "spawning a child" as something that is in some kind of container (the parent process), but the underlying mechanics are not like this at all, That is not quite right either, the newly created child processes generally go to the same process group as the parent, the process groups (and sessions) forming those "containers". Tbh this is one of the many murky areas of UNIX.

My explanation definitely glosses over some details, but a process group isn't really a "container" in any meaningful sense, either. It can be left by any member (who can form a new process group completely unrelated to its old one, setsid), which resets the "controlling terminal" but isn't related to the standard output channels at all.

Re: Fixing Ctrl+C in Rust terminal apps: Child process management

#54

Earlier quoted context omitted.

Are you suggesting that the examples, source, libraries, and references for Rust make these mistakes, but other languages don't?

the title: "fixing ... in rust". The problems aren't necessarily rust only problems, the solutions are rust solutions.

I don't think any of the solutions are specific to Rust though? Just like the mistakes you can make hosting child processes can be made in many languages, the solution of e.g. "don't give the child processes your stdout, give it a pipe that you read from" isn't a Rust solution.

Re: Fixing Ctrl+C in Rust terminal apps: Child process management

#55

Handling SIGINT (ctrl-c) with child processes is tricky, but a more pervasive problem for Rust CLI programs is handling SIGPIPE. For historical reasons the compiler adds a signal handler before calling main() which ignores SIGPIPE. It means when you pipe your Rust CLI program's output to something like head, instead of being killed by the signal sent when head closes the pipe, you get a write error and usually print…

That's good to know; ysh[1] will treat pipelines with a SIGPIPE indicative exit code as successful to allow e.g.

  foo |head -n2
to be treated as successful. I haven't seen anyone complaining yet about rust programs breaking this idiom, but I'll keep an eye out for it.

1: https://oils.pub/release/latest/doc/ysh-tour.html

Re: Fixing Ctrl+C in Rust terminal apps: Child process management

#56
post #55

Handling SIGINT (ctrl-c) with child processes is tricky, but a more pervasive problem for Rust CLI programs is handling SIGPIPE. For historical reasons the compiler adds a signal handler before calling main() which ignores SIGPIPE. It means when you pipe your Rust CLI program's output to something like head, instead of being killed by the signal sent when head closes the pipe, you get a write error and usually print…

That's good to know; ysh[1] will treat pipelines with a SIGPIPE indicative exit code as successful to allow e.g. foo |head -n2 to be treated as successful. I haven't seen anyone complaining yet about rust programs breaking this idiom, but I'll keep an eye out for it. 1: https://oils.pub/release/latest/doc/ysh-tour.html

In other shells, the status of the pipeline is the exit status of the last process, so in this case that would be head which exits with 0.

Re: Fixing Ctrl+C in Rust terminal apps: Child process management

#57

Earlier quoted context omitted.

the title: "fixing ... in rust". The problems aren't necessarily rust only problems, the solutions are rust solutions.

I don't think any of the solutions are specific to Rust though? Just like the mistakes you can make hosting child processes can be made in many languages, the solution of e.g. "don't give the child processes your stdout, give it a pipe that you read from" isn't a Rust solution.

I believe @stonogo is saying Rust code is specific to Rust.

Re: Fixing Ctrl+C in Rust terminal apps: Child process management

#58
post #55

Earlier quoted context omitted.

That's good to know; ysh[1] will treat pipelines with a SIGPIPE indicative exit code as successful to allow e.g. foo |head -n2 to be treated as successful. I haven't seen anyone complaining yet about rust programs breaking this idiom, but I'll keep an eye out for it. 1: https://oils.pub/release/latest/doc/ysh-tour.html

In other shells, the status of the pipeline is the exit status of the last process, so in this case that would be head which exits with 0.

Not in e.g. bash with "pipefail" set. However the pipefail option in bash will choke on my previous example, hence treating a SIGPIPE the same as success in ysh.

Re: Fixing Ctrl+C in Rust terminal apps: Child process management

#59
post #12

Fearless concurrency with Rust unless you are worried about lifecycle management, threads/co-operation and general ergonomics. Even modern c++ might be better at this (gasp!) with std::jthread

Ok, but I am literally getting filtered by installing C++ libraries. I haven't accomplished anything in the last 5 days other than determine that the previous libraries are not usable.

Re: Fixing Ctrl+C in Rust terminal apps: Child process management

#60
post #58

Earlier quoted context omitted.

In other shells, the status of the pipeline is the exit status of the last process, so in this case that would be head which exits with 0.

Not in e.g. bash with "pipefail" set. However the pipefail option in bash will choke on my previous example, hence treating a SIGPIPE the same as success in ysh.

Yes well, the pipefail option configures bash to do the opposite of its usual behaviour.
Post reply on HN