在虚拟外壳中处理CTRL-C [英] Handling CTRL-C in dummy shell
问题描述
我正在编写一个虚拟外壳程序,该外壳程序在用户键入ctrl-C时不应终止,而应仅生成一个新的提示行.当前,当我键入ctrl-C时,我的外壳并没有终止,但是它仍然不打印新的提示行.您知道为什么会这样吗,我该如何解决?
I'm writing a dummy shell that should not terminate when the user types ctrl-C but should just generate a new prompt line. Currently, my shell does not terminate when I type ctrl-C but it still does not print the new prompt line. Do you know why this is the case and how I can fix this?
我的代码如下:
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#define BUFFER_SIZE 1<<16
#define ARRAY_SIZE 1<<16
void INThandler(int);
static void parseCmdArgs(char *buffer, char** cmdArgs,
size_t cmdArgsSize, size_t *nargs)
{
char *bufCmdArgs[cmdArgsSize];
char **temp;
char *buf;
size_t n, p;
cmdArgs[0] = buf = bufCmdArgs[0] = buffer;
for(temp=bufCmdArgs; (*temp=strsep(&buf, " \n\t")) != NULL ;){
if ((*temp != '\0') && (++temp >= &bufCmdArgs[cmdArgsSize]))
break;
}
for (p=n=0; bufCmdArgs[n]!=NULL; n++){
if(strlen(bufCmdArgs[n])>0)
cmdArgs[p++]=bufCmdArgs[n];
}
*nargs=p;
cmdArgs[p]=NULL;
}
void INThandler(int sig)
{
printf("\n> ");
signal(sig, SIG_IGN);
}
int main(void)
{
char buffer[BUFFER_SIZE];
char *args[ARRAY_SIZE];
int retStatus;
size_t nargs;
pid_t pid;
printf("$dummyshell\n");
signal(SIGINT, INThandler);
while(1){
printf("> ");
fgets(buffer, BUFFER_SIZE, stdin);
parseCmdArgs(buffer, args, ARRAY_SIZE, &nargs);
if (nargs==0)
continue;
if (!strcmp(args[0], "help"))
{
printf("cat cd (absolute path references only\n");
printf("exit\n");
printf("help history\n");
printf("jobs kill\n");
printf("ls more\n");
printf("ps pwd\n");
continue;
}
if (!strcmp(args[0], "exit" ))
exit(0);
pid = fork();
if (pid){
wait(&retStatus);
}
else {
if( execvp(args[0], args)) {
fprintf(stderr, "%s\n", strerror(errno));
exit(127);
}
}
/* pid = fork();
if (pid == 0)
setpgrp();
else if (pid)
pid = wait(&retStatus);
else {
if (execvp(args[0], args)){
fprintf(stderr, "%s\n", strerror(errno));
exit(127);
}
}*/
}
return 0;
}
推荐答案
我假设您希望中断处理程序跳转到main
函数的while循环中,而不是打印"\>"
.
I'm assuming you want the interrupt handler to jump into the while loop in your main
function, instead of printing "\>"
.
您可以为此使用sigsetjmp
和siglongjmp
.您可能想以[1]为例.
You can use sigsetjmp
and siglongjmp
for this. You might want to take at [1] for an example.
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
jmp_buf JumpBuffer;
void INThandler(int);
void main(void)
{
signal(SIGINT, INThandler);
while (1) {
if (setjmp(JumpBuffer) == 0) {
printf(">");
/*...*/
}
}
}
void INThandler(int sig)
{
signal(sig, SIG_IGN);
signal(SIGINT, INThandler);
longjmp(JumpBuffer, 1);
}
此内容改编自[2].如果使用sigaction()
,sigprocmask()
或sigsuspend()
,则需要分别使用siglongjmp
和sigsetjmp
函数[3].
This was adapted from [2]. If you use sigaction()
, sigprocmask()
, or sigsuspend()
you need to use the siglongjmp
and sigsetjmp
functions, respectively [3].
来源:
- [1] https://publib.boulder.ibm.com/iseries/v5r2/ic2924/index.htm?info/apis/siglngj.htm
- [2] http ://www.csl.mtu.edu/cs4411.ck/www/NOTES/non-local-goto/sig-1.html
- [3] sigsetjmp-开放小组基本规范第6版,IEEE标准1003.1,2004年版
- [1] https://publib.boulder.ibm.com/iseries/v5r2/ic2924/index.htm?info/apis/siglngj.htm
- [2] http://www.csl.mtu.edu/cs4411.ck/www/NOTES/non-local-goto/sig-1.html
- [3] sigsetjmp - The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 Edition
这篇关于在虚拟外壳中处理CTRL-C的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!