Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将新行字符发送到c中的stdin并允许fgets(cmdline、MAXLINE、stdin)接收它?_C_Linux_Shell - Fatal编程技术网

如何将新行字符发送到c中的stdin并允许fgets(cmdline、MAXLINE、stdin)接收它?

如何将新行字符发送到c中的stdin并允许fgets(cmdline、MAXLINE、stdin)接收它?,c,linux,shell,C,Linux,Shell,我目前正在用c语言构建一个shell程序。 我需要使用signals来捕获CTRL-C信号,并输出use-exit来请求用户使用我的内置命令exit离开myshell。 我已将信号处理程序添加到输出Use exit,但无法使shell在Use exit后输出[/]> 预期成果: [assignment2] > ^C Use exit [assignment2] > ^C Use exit [assignment2] > ^C Use exit [assignment2] >

我目前正在用c语言构建一个shell程序。 我需要使用signals来捕获CTRL-C信号,并输出use-exit来请求用户使用我的内置命令exit离开myshell。 我已将信号处理程序添加到输出Use exit,但无法使shell在Use exit后输出[/]>

预期成果:

[assignment2] > ^C
Use exit
[assignment2] > ^C
Use exit
[assignment2] > ^C
Use exit
[assignment2] > exit
但是,我的程序的输出没有[assignment2]>输出。每次退出^C Use后,我必须按键盘上的enter键才能显示[assignment2]>:

[assignment2] > ^C
Use exit
^C
Use exit
^C
Use exit
[assignment2] > exit
我怀疑在处理信号后,程序仍然卡在fgetscmdline、MAXLINE、stdin中,因此程序不会继续到while循环的开头打印出[assignment2]>,如下代码所示:

myshell和handle信号函数的代码:

// Signal handler funciton
void handler(int signal){
   switch(signal) {
      case SIGINT:
        write(STDOUT_FILENO, "\nUse exit\n", 10);
        break;
      case SIGTSTP:
        write(STDOUT_FILENO, "\nUse exit\n", 10);
        break;
      case SIGQUIT:
        write(STDOUT_FILENO, "\nUse exit\n", 10);
        break;
}

int main(){
   // Add signal handler
   if (signal(SIGINT, handler) == SIG_ERR) {
      perror("signal");
    } else if (signal(SIGTSTP, handler) == SIG_ERR){
      perror("signal");
    } else if (signal(SIGQUIT, handler) == SIG_ERR){
      perror("signal");
    }

    // ...... init cmdline and cwd char

    while(1){
       char dir[MAXPATH];
       getcwd(cwd, sizeof(cwd));
       printf("[%s] > ", parsecwd(cwd));

       if (get_cmd_line(cmdline) == -1) // The program is stuck inside this funciton
            continue; /* empty line handling */

        eval(cmdline); /* Evaluate and process the cmd input*/
    }
}


int get_cmd_line(char *cmdline)
{
    int i;
    int n;
    if (!fgets(cmdline, MAXLINE, stdin))  // The program is stuck in this fgets
        return -1;
    // Ignore the newline character
    n = strlen(cmdline);
    cmdline[--n] = '\0';
    i = 0;
    while (i < n && cmdline[i] == ' ') {
        ++i;
    }
    if (i == n) {
        // Empty command
        return -1;
    }
    return 0;
}

但这并不能解决问题,它只是在终端中打印出一行新行

你知道怎么解决这个问题吗?
谢谢。

的标准库glibc实现使用BSD语义,这意味着系统调用将在信号出现时重新启动而不是失败

此行为使FGET等在信号处理程序完成时不返回

要控制此行为,请改用建议的函数。更具体地说,确保未设置SA_重启标志:

struct sigaction action = { 0 };  // Initialize all members to zero or null

action.sa_handler = &handler;
sigaction(SIGINT, &action, NULL);

这样,fgets函数将返回一个空指针,errno应等于EINTR。

的标准库glibc实现使用BSD语义,这意味着系统调用将在信号发生时重新启动而不是失败

此行为使FGET等在信号处理程序完成时不返回

要控制此行为,请改用建议的函数。更具体地说,确保未设置SA_重启标志:

struct sigaction action = { 0 };  // Initialize all members to zero or null

action.sa_handler = &handler;
sigaction(SIGINT, &action, NULL);
这样,fgets函数将返回一个空指针,errno应该等于EINTR