分叉进程的子进程中的std in / out / err重定向

时间:2013-03-01 19:48:54

标签: c bash io-redirection fork

我在C中写了一个基本的反向shell:

if(-1 ==  (myShell->pid = fork()))
{
    PipeSet_close(&myShell->pipeSet);
    return RS_ERROR;
}

if(myShell->pid == 0)
{
    /* close pipe ends child doesn't need */
    close(myShell->pipeSet.stdInPipe[1]);
    close(myShell->pipeSet.stdOutPipe[0]);
    close(myShell->pipeSet.stdErrPipe[0]);

    /* dupe 2 the pipes we DO need frm their originals */
    dup2(myShell->pipeSet.stdInPipe[0], fileno(stdin));
    dup2(myShell->pipeSet.stdOutPipe[1],fileno(stdout));
    dup2(myShell->pipeSet.stdErrPipe[1],fileno(stderr));

    /* bash now replaces child process. only returns after bash terminates */
    execl(getenv("SHELL"),NULL,NULL);
    return RS_SUCCESS;
}

我可以使用我的父进程从我的3个管道中读取和写入。这允许我通过子进程执行基本的shell命令。 ls -l,ps,chmod + x等我遇到的问题是当我使用shell运行一个需要用户输入的简单程序时。我使用以下程序来测试这个:

int main()
{
int opt;
while (1==1)
{
    printf("-----Remote Shell Menu test:------\n");
    printf("   1. print 1\n");
    printf("   2. print 2\n");
    printf("   3. exit\n");
    fflush(stdin);
    scanf("%d",&opt);

    switch (opt)
    {
    case 1: printf("Pressed 1\n"); break;
    case 2: printf("Pressed 2\n"); break;
    case 3: return 0;
    default: printf("unknown menu option %d\n",opt);
    }
}
}

我能够与这个子程序进行交互,因为我通常会通过我的反向shell,并按“1”“2”1“”3“但我没有得到菜单或看到任何输出通过我的stdout管道,直到整个菜单程序终止,我按3.任何人都可以告诉我为什么这是?

如果从我的分叉bash中生成另一个bash shell,则不是这种情况......

2 个答案:

答案 0 :(得分:1)

fflush(stdin)什么也没做。 fflush仅用于输出流。我相信如果你将其更改为fflush(stdout),它将解决你的缓冲问题。

答案 1 :(得分:1)

您还应该在close之后dup2重复的管道,以便进程有机会检测到EOF。

您可以在perror之后添加execl;更好地使用execlp;提供argv[0]代替NULL。 如果getenv("SHELL")NULL会怎样?你确定它是bash吗?

主要是return的东西;测试1==1while中无用(通常使用while(1) for(;;)获得无限循环