【问题标题】:C shell printing output infinitely without stopping at gets()C shell 无限打印输出而不会在 get() 处停止
【发布时间】:2013-02-23 04:10:42
【问题描述】:

我正在尝试使用 SIGCHLD 处理程序,但由于某种原因,它会打印出我无限发出的命令。如果我删除结构行为,它就可以正常工作。

任何人都可以看看它,我无法理解问题所在。 提前致谢!!

    /* Simplest dead child cleanup in a SIGCHLD handler. Prevent zombie processes
   but dont actually do anything with the information that a child died. */

#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

typedef char *string;

/* SIGCHLD handler. */
static void sigchld_hdl (int sig)
{
    /* Wait for all dead processes.
     * We use a non-blocking call to be sure this signal handler will not
     * block if a child was cleaned up in another part of the program. */
    while (waitpid(-1, NULL, WNOHANG) > 0) {
    }
}

int main (int argc, char *argv[])
{
    struct sigaction act;
    int i;
    int nbytes = 100;
    char my_string[nbytes];
    string arg_list[5];
    char *str;
    memset (&act, 0, sizeof(act));
    act.sa_handler = sigchld_hdl;

    if (sigaction(SIGCHLD, &act, 0)) {
        perror ("sigaction");
        return 1;
    }

while(1){

    printf("myshell>> ");
    gets(my_string);
    str=strtok(my_string," \n");
    arg_list[0]=str;
    i =1;
    while ( (str=strtok (NULL," \n")) != NULL){
            arg_list[i]= str;
            i++;
        }
    if (i==1)
        arg_list[i]=NULL;
    else
        arg_list[i+1]=NULL;

     pid_t child_pid;
    child_pid=fork();
    if (child_pid == (pid_t)-1){
        printf("ERROR OCCURED");
        exit(0);
        }

    if(child_pid!=0){
        printf("this is the parent process id is %d\n", (int) getpid());
        printf("the child's process ID is %d\n",(int)child_pid);

    }
    else{
        printf("this is the child process, with id %d\n", (int) getpid());
        execvp(arg_list[0],arg_list);
        printf("this should not print - ERROR occured");
        abort();
    }

    }
    return 0;
}

【问题讨论】:

  • 甚至 fgets() 给我同样的问题!!
  • gets 的使用不是您所看到症状的根源,但 gets 本质上是不安全的。它无法指定目标数组的大小。如果运行您的程序的人在一行中键入超过 100 个字符,您将遇到缓冲区溢出,从而导致未定义(即任意错误)的行为。

标签: shell unix operating-system


【解决方案1】:

我没有运行你的代码,只是假设:

SIGCHLD 到达并打断了fgets(我就假装你没有使用gets)。 fgets 在实际读取任何数据之前返回,my_string 包含它在上一个循环中的标记化列表,你再次 fork,输入 fgets,它在读取任何数据之前被中断,并无限重复。

也就是说,检查fgets 的返回值。如果它为 NULL 并且已将 errno 设置为 EINTR,则再次调用 fgets。 (或设置act.sa_flags = SA_RESTART。)

【讨论】:

    猜你喜欢
    • 2022-06-17
    • 2019-03-20
    • 1970-01-01
    • 2020-10-24
    • 1970-01-01
    • 2014-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多