代码之家  ›  专栏  ›  技术社区  ›  Gary

用C程序选择失败,但不选择shell

  •  3
  • Gary  · 技术社区  · 16 年前

    我有一个父进程和子进程,父进程可以从子进程中读取输出并发送到子进程的输入。到目前为止,shell脚本、输入和输出数据的命令的测试都运行良好。我刚用一个简单的C程序进行了测试,但无法使它正常工作。这是C程序:

    #include <stdio.h>
    
    int main( void ) {
      char stuff[80];
      printf("Enter some stuff:\n");
      scanf("%s", stuff);
    
      return 0;
    }
    

    C程序的问题是我的选择无法从子fd中读取,因此程序无法完成。下面是选择的部分。

    //wait till child is ready
    fd_set set;
    struct timeval timeout;
    
    FD_ZERO( &set ); // initialize fd set
    FD_SET( PARENT_READ, &set ); // add child in to set
    timeout.tv_sec = 3;
    timeout.tv_usec = 0;
    
    int r = select(FD_SETSIZE, &set, NULL, NULL, &timeout);
    if( r < 1 ) { // we didn't get any input
        exit(1);
    }
    

    有人知道为什么C程序而不是shell程序会发生这种情况吗?

    编辑:我应该指出,子进程调用了一个参数的exec,所以我没有权限访问它。

    2 回复  |  直到 11 年前
        1
  •  2
  •   Donal Fellows    16 年前

    问题是子进程正在完全缓冲输出,因为它正在写入管道而不是终端。使用 setvbuf 强制行缓冲或非缓冲模式,或添加显式 fflush 在那之后给孩子 printf 或使用 unbuffer 带有Expect的程序会欺骗子进程的libc,使其认为该程序正在交互工作。

        2
  •  1
  •   Charles Duffy    16 年前

    在阻止C程序中的输入之前刷新stdout。

    fflush(stdout);
    

    在shell中,这通常是隐式的。

    或者,您可以使用 setvbuf() 禁用缓冲(或启用线路缓冲)。在写入任何数据之前必须调用此函数:

    setvbuf(stdout, NULL, _IONBF, 0)