Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much

Re^14: CPAN failed install

by afoken (Chancellor)
on Nov 19, 2016 at 12:58 UTC ( #1176148=note: print w/replies, xml ) Need Help??

in reply to Re^13: CPAN failed install
in thread CPAN failed install

it seems the only two distros that haven't adopted it as the default yet are Slackware and Gentoo

There is a debian fork called Devuan. The reason for the fork was the decision to use systemd instead of a sane init. (via

While searching that, I found You may guess what content is hosted there. ;.-)


From there, I followed a link to A history of modern init systems featuring a really compact init implementation in less than 100 lines:

# MIT license. #include <sys/types.h> #include <sys/wait.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #define LEN(x) (sizeof (x) / sizeof *(x)) static void sigpoweroff(void); static void sigreap(void); static void sigreboot(void); static void spawn(char *const []); static struct { int sig; void (*handler)(void); } sigmap[] = { { SIGUSR1, sigpoweroff }, { SIGCHLD, sigreap }, { SIGINT, sigreboot }, }; static char *const rcinitcmd[] = { "/bin/rc.init", NULL }; static char *const rcrebootcmd[] = { "/bin/rc.shutdown", "reboot", N +ULL }; static char *const rcpoweroffcmd[] = { "/bin/rc.shutdown", "poweroff", + NULL }; static sigset_t set; int main(void) { int sig; size_t i; if (getpid() != 1) return 1; chdir("/"); sigfillset(&set); sigprocmask(SIG_BLOCK, &set, NULL); spawn(rcinitcmd); while (1) { sigwait(&set, &sig); for (i = 0; i < LEN(sigmap); i++) { if (sigmap[i].sig == sig) { sigmap[i].handler(); break; } } } /* not reachable */ return 0; } static void sigpoweroff(void) { spawn(rcpoweroffcmd); } static void sigreap(void) { while (waitpid(-1, NULL, WNOHANG) > 0) ; } static void sigreboot(void) { spawn(rcrebootcmd); } static void spawn(char *const argv[]) { pid_t pid; pid = fork(); if (pid < 0) { perror("fork"); } else if (pid == 0) { sigprocmask(SIG_UNBLOCK, &set, NULL); setsid(); execvp(argv[0], argv); perror("execvp"); _exit(1); } }

I think it looks quite good, there are only two things I'm missing here:

  • Sanitising of the output: This init relies on the kernel to provide a sane set of stdin, stdout, stderr. Technically, setting up the standard handles could be done in rc.init and rc.shutdown, but errors this init wants to report via perror() are written to whatever the kernel has set up as handle 2. Compare with busybox init: It calls console_init() and set_sane_term() as first actions.
  • Handling for all kernel signals. Keyboard request (usually mapped to Alt+UpArrow) results in a SIGWINCH signal sent to init. Easy to add to the sigmap[] variable, add a new handler that starts yet another program.

rc.shutdown is started by two signals, you have to look at the command line parameters to get the difference. I would have prefered one program per signal. For the reboot and shutdown signals, I could either use two different tiny scripts that would execute the same shutdown script with the two command lines, or I could just symlink one to the other and use argv[0] to decide what to do.

Everything else could be done by other programs, as explained in the second part of Re^14: CPAN failed install.


Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1176148]
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (3)
As of 2023-12-10 07:28 GMT
Find Nodes?
    Voting Booth?
    What's your preferred 'use VERSION' for new CPAN modules in 2023?

    Results (38 votes). Check out past polls.