首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >读行与子printf的冲突?

读行与子printf的冲突?
EN

Stack Overflow用户
提问于 2010-09-28 19:49:15
回答 3查看 849关注 0票数 0

在Linux中,无限循环中的readline()重复读取文本\n。然而,一旦子进程开始打印到屏幕上,readline就不再读取新行。即使重复按enter键,readline()也不会返回。

有人知道怎么回事吗?

所要求的代码示例:

代码语言:javascript
复制
char* input;
int cpid;
while(1)
{
     input = readline(">>>");
     strcpy(tempInput, input); //...does some stuff w/ tempInput
     //....
     cpid = fork();
     if(cpid == 0){
           printf("..."); printf("...");
           execl("ls", "ls", "-l", (char*) NULL); //sample execl parameters
     }
     else{
           //do some stuff...
           printf("...");
     }
     free(input);
}

    //readline(">>>") works the first time and doesn't return on subsequent calls

代码挂起位置的堆栈跟踪(永久):

代码语言:javascript
复制
Thread [1] (Suspended : Signal : SIGINT:Interrupt)  
    __read_nocancel() at ../sysdeps/unix/syscall-template.S:82 0x7ffff78f0490   
    rl_getc() at 0x7ffff7bc3727 
    rl_read_key() at 0x7ffff7bc3c90 
    readline_internal_char() at 0x7ffff7baf25f  
    readline() at 0x7ffff7baf795    
    main() at /home/.../.../xxx.c:95 0x4010a1   

编辑:对于经验丰富的unix开发人员来说,这可能听起来完全是技术上的空谈,但子进程会不会以某种方式“捕获”了stdin,却未能以某种方式发布?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-09-29 05:48:21

您的子进程,即使在执行之后,仍然有它的标准输入连接到您的终端。使用wait()等待子进程完成,或者重新打开作为/dev/null的子进程的标准输入

代码语言:javascript
复制
close(STDIN_FILENO) && open("/dev/null", "O_WRONLY");
票数 1
EN

Stack Overflow用户

发布于 2010-09-28 20:30:38

在fork()之后,您的子进程执行2个printf调用,然后继续执行while(1)循环,所以您要做的是在每一行换行符之后创建一个额外的进程。

你需要做的是,在孩子打印两个椭圆(...)后立即杀死它。

将代码更改为:

代码语言:javascript
复制
  if(cpid == 0){
        printf("..."); printf("..."); exec(...); exit(0); 
    }

请记住,只有在exec()失败时才调用exit()。

编辑:

如果您打算接受某种命令行解释器的输入,那么readline不是一个很好的选择。它的官方手册页说:

代码语言:javascript
复制
BUGS:

    It’s too big and too slow.

我可以建议另一种获取输入字符串的方法:

代码语言:javascript
复制
char c;
inputString = calloc(0,sizeof(char));
inputLength = 0;

c = getchar();
    while(c!='\n')
    {
        inputString = realloc(inputString,(inputLength+1)*sizeof(char));
        inputString[inputLength++] = c;
        c = getchar();
    }
    inputString[inputLength] = '\0';

现在有了inputString中的字符串&它的长度在inputLength中。你可以做得很好:

代码语言:javascript
复制
execlp(inputString,inputString,0);

以执行所需的功能。

票数 1
EN

Stack Overflow用户

发布于 2011-01-06 15:46:31

这段代码无法工作,因为您对execl()的调用失败了,因此子进程将在循环代码处恢复,循环代码也将使用readline()。

在使用execl()时,必须将完整路径传递给可执行文件,或者使用execlp()变量(搜索路径环境变量)使其工作。

即使对于最简单的系统,始终检查它们的返回代码也是一种很好的做法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3816490

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档