Моя оболочка не может помешать Ctrl + C убить себя - PullRequest
7 голосов
/ 15 марта 2019

Я пишу свою собственную оболочку (исходный код указан ниже) и устанавливаю для нее оболочку пользователя по умолчанию.

Я вхожу в систему с этим пользователем и набираю ctrl-C, и эта оболочка уничтожается, даже если этот сигнал перехвачен. Однако я запускаю эту оболочку непосредственно из bash, она работает, как я и ожидал. Что имеет значение.

Результат

Войдите в систему с пользователем, для которого по умолчанию установлена ​​оболочка для моей собственной оболочки:

BMC login:
BMC login: naroot
Password:
BMC > signal = 2
BMC login:

Непосредственно запустить его под bash:

~# /tmp/systemshell
BMC > signal = 2
BMC > signal = 2
BMC > signal = 2
BMC >

исходный код

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <readline/readline.h>
#include <readline/history.h>

#include <signal.h> // sigaction(), sigsuspend(), sig*()

void signalHandler(int signum) {
    signal(SIGINT, signalHandler);
    signal(SIGTSTP, signalHandler);
    signal(SIGQUIT, SIG_IGN);
    signal(SIGTTIN, SIG_IGN);
    signal(SIGTTOU, SIG_IGN);
    signal(SIGCHLD, SIG_IGN);

    printf("signal = %d\n", signum);
}

int main()
{
    signal(SIGINT, signalHandler);
    signal(SIGTSTP, signalHandler);
    signal(SIGQUIT, SIG_IGN);
    signal(SIGTTIN, SIG_IGN);
    signal(SIGTTOU, SIG_IGN);
    signal(SIGCHLD, SIG_IGN);

    char *input;

    while (1) {
        input = readline("BMC > ");
        if (input) {
            printf("%s\n", input);
            free(input);
        }
    }
    return 0;
}

1 Ответ

0 голосов
/ 18 марта 2019

Интересно, почему ash или другой bash может работать, так что покопайтесь в исходном коде ash.Я пытаюсь это фрагменты .

Это работает .

    int ofd;
    ofd = fd = open(_PATH_TTY, O_RDWR);
    if (fd < 0) {
/* BTW, bash will try to open(ttyname(0)) if open("/dev/tty") fails.
 * That sometimes helps to acquire controlling tty.
 * Obviously, a workaround for bugs when someone
 * failed to provide a controlling tty to bash! :) */
        fd = 2;
        while (!isatty(fd))
            if (--fd < 0)
                goto out;
    }
    /* fd is a tty at this point */
    fd = fcntl(fd, F_DUPFD, 10);
    if (ofd >= 0) /* if it is "/dev/tty", close. If 0/1/2, dont */
        close(ofd);
    if (fd < 0)
        goto out; /* F_DUPFD failed */
    close_on_exec_on(fd);
    while (1) { /* while we are in the background */
        pgrp = tcgetpgrp(fd);
        if (pgrp < 0) {
out:
            ash_msg("can't access tty; job control turned off");
            mflag = on = 0;
            goto close;
        }
        if (pgrp == getpgrp())
            break;
        killpg(0, SIGTTIN);
    }
    initialpgrp = pgrp;

    setsignal(SIGTSTP);
    setsignal(SIGTTOU);
    setsignal(SIGTTIN);
    pgrp = rootpid;
    setpgid(0, pgrp);
    xtcsetpgrp(fd, pgrp);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...