Mar*_*tin 2 c unix linux shell system
我编写了一个从内部调用系统命令的程序:
#include <stdlib.h>
int main(void)
{
while(1)
{
system("ls 2>&1 1>/dev/null"); // comment this line out to enable ctrl+break
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是,当它运行时,CTRL + C和CTRL + BREAK不再起作用,似乎被忽略.
我正在尝试编写一个程序,在后台执行一些涉及shell的操作,但我也希望能够在用户想要破解时突破程序.
有没有办法让它按我想要的方式工作?我应该改变架构来执行某种fork/exec吗?
该系统()函数将忽略SIGINT和SIGQUIT信号,并阻止SIGCHLD信号,同时等待命令来终止.如果这可能导致应用程序错过可能已将其杀死的信号,则应用程序应检查system()的返回值,并在命令因接收到信号而终止时采取适合应用程序的任何操作.
因此,为了正确响应信号,您需要检查返回值system().
system()以waitpid()指定的格式返回命令语言解释器的终止状态
以及waitpid()参考文档的文档wait(),它们指示您使用以下宏来查找进程退出的原因:
- WIFEXITED(stat_val)
如果正常终止的子进程返回状态,则求值为非零值.- WEXITSTATUS(stat_val)
如果WIFEXITED(stat_val)的值不为零,则此宏计算为子进程传递给_exit()或exit()的状态参数的低8位,或者子进程的值从main()返回的进程.- WIFSIGNALED(stat_val)
如果由于收到未捕获的信号而终止的子进程返回状态,则求值为非零值(请参阅参考资料).- WTERMSIG(stat_val)
如果WIFSIGNALED(stat_val)的值不为零,则此宏将计算导致子进程终止的信号编号.- WIFSTOPPED(stat_val)
如果为当前停止的子进程返回状态,则求值为非零值.- WSTOPSIG(stat_val)
如果WIFSTOPPED(stat_val)的值不为零,则此宏将计算导致子进程停止的信号编号.- WIFCONTINUED(stat_val)
如果从作业控制停止继续的子进程返回状态,则求值为非零值.
以下是如何使用此信息的示例,而无需分叉单独的进程.请注意,您实际上不会在父进程中收到信号,但您可以确定发送到子进程的信号:
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
while(1)
{
int result = system("ls 2>&1 1>/dev/null");
if (WIFEXITED(result)) {
printf("Exited normally with status %d\n", WEXITSTATUS(result));
} else if (WIFSIGNALED(result)) {
printf("Exited with signal %d\n", WTERMSIG(result));
exit(1);
} else {
printf("Not sure how we exited.\n");
}
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果你运行它,你得到:
$ ./sys Exited normally with status 0 Exited normally with status 0 Exited normally with status 0 Exited normally with status 0 Exited normally with status 0 Exited normally with status 0 ^CExited with signal 2