[英]Handling CTRL-C in dummy shell
I'm writing a dummy shell that should not terminate when the user types ctrl-C but should just generate a new prompt line. 我正在编写一个虚拟外壳,当用户键入ctrl-C时该外壳不应终止,而应仅生成一个新的提示行。 Currently, my shell does not terminate when I type ctrl-C but it still does not print the new prompt line.
当前,当我键入ctrl-C时,我的外壳并没有终止,但是它仍然不显示新的提示行。 Do you know why this is the case and how I can fix this?
您知道为什么会这样吗,我该如何解决?
My code is below: 我的代码如下:
#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;
}
but what would I pass through fflush()?
但是我将通过fflush()通过什么呢?
It would be 这将是
fflush(stdout);
- but that is not needed because of the fgets(buffer, BUFFER_SIZE, stdin)
. -但这不是必需的,因为有
fgets(buffer, BUFFER_SIZE, stdin)
。
Output streams that refer to terminal devices are always line buffered by default;
默认情况下,引用终端设备的输出流始终是行缓冲的。 pending output to such streams is written automatically whenever an input stream that refers to a terminal device is read.
每当读取指向终端设备的输入流时,这些流的未决输出都会自动写入。
(See man stdio
.) (请参阅
man stdio
。)
I'm assuming you want the interrupt handler to jump into the while loop in your main
function, instead of printing "\\>"
. 我假设您希望中断处理程序跳入
main
函数的while循环中,而不是打印"\\>"
。
You can use sigsetjmp
and siglongjmp
for this. 您可以
sigsetjmp
使用sigsetjmp
和siglongjmp
。 You might want to take at [1] for an example. 您可能想以[1]为例。
#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);
}
This was adapted from [2]. 改编自[2]。 If you use
sigaction()
, sigprocmask()
, or sigsuspend()
you need to use the siglongjmp
and sigsetjmp
functions, respectively [3]. 如果使用
sigaction()
, sigprocmask()
或sigsuspend()
,则需要分别使用siglongjmp
和sigsetjmp
函数[3]。
Sources : 资料来源 :
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.