Control: reassign -1 apt

[ Adding some context. ]

On Thu, 2019-07-04 at 10:05:31 +0200, Harald Dunkel wrote:
> Package: dpkg
> Version: 1.18.25

> On the upgrade from Stretch to Buster there was a config
> file conflict (with /etc/issue, but that doesn't matter).
> dpkg allowed me to examine the conflict ("Z"). I could
> adjust the old file using the mg editor, I could save the
> config file using Ctrl-X Ctrl-S, but I could not leave mg
> using Ctrl-X Ctrl-C. The Ctrl-C did not work.
> 
> AFAICT dpkg's "Z" session should set the terminal back to a
> reasonable state before starting a new shell.

On Sun, 2021-02-28 at 10:06:30 -0800, Norman Rasmussen wrote:
> Package: dpkg
> Version: 1.20.7.1
> Followup-For: Bug #931402

> I can reproduce this in just the shell that's started. Ctrl-C doesn't
> seem to have any immediate effect. However once the shell is exited, the
> Ctrl-C causes dpkg to terminate early.
> 
> I suspect that dpkg isn't creating a new foreground process group, so
> the SIGINT from Ctrl-C is being delivered to dpkg instead of the shell
> (or relevant sub-process like the editor).
> 
> Adding a setsid or setpgid call somewhere in spawn_shell and/or
> show_diff would probably fix it.

So AFAICT, the problem seems to be with apt? It sets the process dpkg
is running on as session leader (setsid()), and sets the terminal as the
controlling terminal of that process in pkgDPkgPM::SetupSlavePtyMagic().

Then in pkgDPkgPM::Go() it has the following:

      /* Mask off sig int/quit. We do this because dpkg also does when
         it forks scripts. What happens is that when you hit ctrl-c it sends
         it to all processes in the group. Since dpkg ignores the signal
         it doesn't die but we do! So we must also ignore it */
      sighandler_t old_SIGQUIT = signal(SIGQUIT,SIG_IGN);
      sighandler_t old_SIGINT = signal(SIGINT,SigINT);

The code ignoring these signals is very very old, and the setsid() and
TIOCSCTTY ioctl() are more recent, which I think would have made the
former signal ignoring code irrelevant now.

I've only tested this in dpkg (w/o apt involved it works fine), and I
don't think this can be fixed sanely in dpkg, as I'd need to make dpkg
steal the controlling terminal, and force the signal disposition,
which the caller might have set for some reason, etc. But I think
getting rid of those SIG_IGN sets in apt might fix the issue at hand?

If I've misread the situation, I'm happy to fix dpkg if there's a sane
way to do that though.

Thanks,
Guillem

Reply via email to