我编写了自己的外壳程序(下面列出了源代码),并将用户的默认外壳程序设置为该外壳程序。
我用该用户登录并键入ctrl-C,即使捕获了此信号,该外壳也被杀死。但是,我直接从bash
运行此shell,它按预期运行。有什么区别。
使用默认外壳程序设置为我自己的外壳程序的用户登录:
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;
}
答案 0 :(得分:0)
我想知道ash
或其他bash为何可以工作,所以请深入研究ash
的源代码。我尝试了这个snippets。
它有效。
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);