> OK, I tried dtruss'ing psql on macOS.  What I see is that with
> Apple's libedit, the response to SIGINT includes this:
> kill(0, 2)               = 0 0

OK, so it's libedit who does this. I should've tried drtuss instead of not
quite working lldb. I'll try to dig further.

Thank you, Tom!



> How did you install this and can you install other, supported, versions?
...

> I was wondering about that.  Are you using libedit or libreadline?
>

I did not build psql, I use the version delivered by brew on MacOS.

I think Tom already found out that it's libedit who is guilty. But for the
sake of history, posting the following below.

I just wrote a small C wrapper which prints, WHO is sending that SIGINT to
the parent processes, and it was indeed the psql process:

================

bash-3.2$ ./0-build.sh && ./1-run.sh
+ gcc my0.c -o my0
+ ./my0
my0 pid is 45710
psql (16.0, server 13.5 (Debian 13.5-1.pgdg110+1))
Type "help" for help.
postgres=#
int in my2
int in my1
my0 got signal 2 from process *45723* running as user 501
postgres=#

bash-3.2$ ./2-watch.sh
Every 0.5s: pstree | grep -E "bash
|yarn|psql|vim|sleep|lldb|my.pl|perl|debugserver|my0|my1|my2"
| grep dmitry | grep -v grep
 |   |     \-+= 36468 dmitry bash -rcfile .bashrc
 |   |       \-+= 45709 dmitry /bin/bash ./1-run.sh
 |   |         \-+- 45710 dmitry ./my0
 |   |           \-+- 45711 dmitry /usr/bin/perl -w ./my1.pl
 |   |             \-+- 45712 dmitry /usr/bin/perl -w /tmp/my2.pl
 |   |               \--- *45723* dmitry psql
 |   |   \-+= 44170 dmitry /bin/bash ./2-watch.sh

bash-3.2$ ./3-kill.sh
+ perl -e 'kill("INT", `pgrep psql`)'

bash-3.2$ cat ./my0.c
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>

void handler(int signal, siginfo_t *info, void *data) {
  printf("my0 got signal %d from process %d running as user %d\n",
         signal, info->si_pid, info->si_uid);
}

int main(void) {
  printf("my0 pid is %d\n", getpid());
  if (fork()) {
    struct sigaction sa;
    sigset_t mask;
    sigemptyset(&mask);
    sa.sa_sigaction = &handler;
    sa.sa_mask = mask;
    sa.sa_flags = SA_SIGINFO;
    sigaction(SIGINT, &sa, NULL);
    while (wait(NULL) == -1);
  } else {
    if (execl("./my1.pl", "my1", NULL) == -1) {
      perror("execl");
    }
  }
  return 0;
}

================



On Sat, Apr 13, 2024 at 4:49 PM Tom Lane <t...@sss.pgh.pa.us> wrote:

> Dmitry Koterov <dmitry.kote...@gmail.com> writes:
> > I wish it was zsh... I tested it with zsh, but with bash (and with
> > low-level kill syscall), I observed the same effect unfortunately.
>
> > So it's still a puzzle.
>
> > 1. Even more, when I send a kill() low-level syscall using e.g. Perl -
> perl
> > -e 'kill("INT", 16107)' - it is the same.
> > 2. If any other program but psql is used (e.g. vim or my custom Perl
> script
> > which ignores SIGINT), the effect is not reproducible.
>
> > Can it be e.g. readline? Or something related to tty or session settings
> > which psql could modify (I did not find any in the source code though).
>
> OK, I tried dtruss'ing psql on macOS.  What I see is that with
> Apple's libedit, the response to SIGINT includes this:
>
> kill(0, 2)               = 0 0
>
> that is, "SIGINT my whole process group".  If I build with libreadline
> from MacPorts, I just see
>
> kill(30902, 2)           = 0 0
>
> (30902 being the process's own PID).  I'm not real sure why either
> library finds it necessary to re-signal the process --- maybe they
> trap SIGINT and then try to hide that by reinstalling the app's
> normal SIGINT handler and re-delivering the signal.  But anyway,
> libedit seems to be vastly exceeding its authority here.  If
> signaling the whole process group were wanted, it would have been
> the responsibility of the original signaller to do that.
>
>                         regards, tom lane
>

Reply via email to