gpt4 book ai didi

linux - `SIGWINCH` 如何通过 Bash?

转载 作者:行者123 更新时间:2023-12-03 09:49:50 30 4
gpt4 key购买 nike

如果我在 Bash 中运行一个程序来监听 SIGWINCH ,然后我调整运行 Bash 的终端的大小,然后程序将收到 SIGWINCH .我想知道这个信号是如何传递给在 Bash 下运行的程序的。
这是我对发生的事情的理解,使用示例 catch_sig我在本文末尾列出的程序:

  • 终端模拟器将在 PTY 的接收端后面运行 Bash。因此,Bash 的“STDIN”和“STDOUT”将是 TTY。
  • Bash 运行 catch_sig作为 fork 的子进程。 catch_sig process 继承了 Bash 的 I/O FD,也就是上面提到的 TTY。
  • 当终端模拟器的大小改变时,它应该调用 ioctl(pty_fd, TIOCSWINSZ, &size) ,其中 pty_fd是上述PTY的发送端。本次调用 ioctl将更新接收 TTY 的大小并尝试发送 SIGWINCH TTY 的进程组。
  • Bash 和 catch_sig是上述进程组的一部分,所以 SIGWINCH分别发送给他们两个。

  • 然而,我在上面遇到的一个困难是,如果我尝试发送 SIGWINCH使用 kill 手动添加到 Bash 的进程组然后 catch_sig没有收到信号。例如,如果 Bash 的 PID(和进程组)是 123我跑 catch_sig在里面,然后我运行 kill -WINCH -123在单独的 Pane 中,然后 catch_sig没有收到信号。为什么会这样?
    以下是演示 catch_sig 的源代码程序,如上所述:
    #include <signal.h>
    #include <stdio.h>
    #include <unistd.h>

    static void sigwinch_handler(int sig) {
    printf("got signal: %d\n", sig);
    }

    int main() {
    signal(SIGWINCH, sigwinch_handler);
    printf("waiting for signal...\n");
    pause();
    return 0;
    }

    最佳答案

    For example, if the PID (and process group) for Bash is 123 and I run catch_sig in it, and then I run kill -WINCH -123 in a separate pane, then catch_sig doesn't receive the signal. Why is this this the case?


    终端发送 SIGWINCH仅限前台(即控制)进程组。当 Bash 是 interactive ,每个作业——前台或后台——都被放置在一个单独的进程组中,前台作业临时获得终端的控制权。例如:
    1号航站楼:
    $ tty
    /dev/pts/0
    $ echo $$
    123
    $ ./catch_sig
    waiting for signal...
    2 号航站楼:
    $ ps -t /dev/pts/0 -o pid,pgid,stat,comm
    PID PGID STAT COMMAND
    123 123 S<s bash
    124 124 S<+ catch_sig

    The plus sign (+) in the STAT field means that the process is a member of the foreground process group, see ps(1).

    So, when you resize the terminal window while catch_sig is running in the foreground (i.e. its process group was made the foreground process group by Bash, and it hasn't completed yet), SIGWINCH is sent to catch_sig's process group only. Then Bash reattains the control of the terminal as catch_sig terminates.

    Which can be reproduced using kill as shown below.

    Terminal #2:

    $ kill -WINCH -124
    1号航站楼:
    got signal: 28
    如需更多信息,请参阅 how job control is implemented in POSIX shells .

    关于linux - `SIGWINCH` 如何通过 Bash?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63230001/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com