c - 在虚拟 shell 中处理 CTRL-C

标签 c shell signals signal-handling control-c

我正在编写一个虚拟 shell,当用户键入 ctrl-C 时,它不应终止,而应生成一个新的提示行。目前,当我键入 ctrl-C 时,我的 shell 不会终止,但它仍然不会打印新的提示行。您知道为什么会出现这种情况以及如何解决这个问题吗?

我的代码如下:

#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(stdout);

- 但这是不需要的,因为 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.

(请参阅man stdio。)

关于c - 在虚拟 shell 中处理 CTRL-C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20109424/

相关文章:

c - 简单链表代码出错

c - 定义的宏 '__CCP_H__' 保留给编译器 [MISRA 2012 规则 21.1,必需]

java - 从 Java 9 向进程发送信号

python - 使用 SWIG 在 Python 中访问结构

c - 按位运算帮助/建议

mysql - 如何将值直接插入到zabbix Mysql数据库中

python - 如何使用 Shelex 将变量传递给curl 命令

shell - 有没有一种快速的方法来读取 dd 中的备用字节

c++ - c++14 中的静态 thread_local 内存异步信号安全吗?

c - 处理SIGCHLD,如何记录 child 死亡时的返回值