Subject: [bug#53063] [PATCH wip-harden-installer 00/14] General improvements to the installer

From: Ludovic Courtès <[email-masked]>
Date: Fri, 07 Jan 2022 14:47:28 +0100

Hello Josselin,

Josselin Poiret <[email-masked]> skribis:

> +(define* (run-external-command-with-handler handler command)
> +    "Run command specified by the list COMMAND in a child with output handler
> +HANDLER.  HANDLER is a procedure taking an input port, to which the command
> +will write its standard output and error.  Returns the integer status value of
> +the child process as returned by waitpid."
> +  (match-let (((input . output) (pipe)))
> +    (match (primitive-fork)
> +      (0 ;; We're in the child
> +       (close-port input)
> +       (reset-fds
> +        (open-fdes "/dev/null" O_WRONLY)
> +        ;; Avoid port GC'ing closing the fd by increasing its revealed count.
> +        (port->fdes output)
> +        (fileno output))
> +       (with-exception-handler
> +           (lambda (exn)
> +             ((@@ (ice-9 exceptions) format-exception) (current-error-port)
> +              exn)
> +             (primitive-_exit 1))
> +         (lambda ()
> +           (apply execlp (car command) command)
> +           (primitive-_exit 1))))
> +      (pid
> +       (close-port output)
> +       (handler input)
> +       (close-port input)
> +       (cdr (waitpid pid))))))

In general, I recommend using (ice-9 popen) instead of raw
‘primitive-fork’.  It provides primitives that do fork+exec at once,
which avoids shenanigans with the finalization threads such as what you
work around in patch #6.

I haven’t looked in detail, but could the ‘pipeline’ procedure from
(ice-9 popen) be of any help?

If you really really do need to fiddle with finalization, I’d recommend
exporting ‘without-automatic-finalization’ from (guix build syscalls)
and using it, so that the hack is factorized.

HTH,
Ludo’.