I'm trying to write an init, but can't figure out the reboot\poweroff thing. apparently reboot is just a link to systemctl? (I'm using arch) So how does this work? init poweroff works and stuff, but reboot/poweroff just seems to be linked to systemctl
1 Answer
Many programs behave differently depending on the name with which they are called. Something like systemctl inspects the value of argv[0] and behaves differently if it is reboot vs if it is systemctl. You can see this taken to the extreme with busybox, which is a single binary that provides almost an entire (minimal) userspace by symlinking all the commands to the single busybox binary.
You can do exactly the same thing with a shell script:
#!/bin/bash if [[ $0 =~ foo ]]; then echo "running foo action" elif [[ $0 =~ bar ]]; then echo "running bar action" else echo "running default action" fi Assuming this is multicall.sh, if we set things up like this:
ln -s multicall.sh foo ln -s multicall.sh bar And then see:
$ ./foo running foo action $ ./bar running bar action $ ./multicall.sh running default action For systemctl in particular, the logic is implemented here:
int systemctl_dispatch_parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); if (invoked_as(argv, "halt")) { arg_action = ACTION_HALT; return halt_parse_argv(argc, argv); } else if (invoked_as(argv, "poweroff")) { arg_action = ACTION_POWEROFF; return halt_parse_argv(argc, argv); } else if (invoked_as(argv, "reboot")) { if (kexec_loaded()) arg_action = ACTION_KEXEC; else arg_action = ACTION_REBOOT; return halt_parse_argv(argc, argv); . . . - That's a great explanation. Thanks a lot!sef sf– sef sf2022-12-25 16:32:34 +00:00Commented Dec 25, 2022 at 16:32