2013-03-01 64 views
1

我在写C基本反向壳的子流程/出/ ERR重定向:STD在派生进程

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); 
    } 
} 
} 

我能够与本次节目互动,我通常会虽然我的反向外壳,然后按“1”“2” 1" ,‘3’,但我没有得到菜单或通过我的标准输出管道看到任何输出,直到整个菜单程序终止,我按3。谁能告诉我为什么这是?

这不是如果一个产卵另一个bash shell从我的分叉bash内...

+1

这是因为缓冲。如果stdout是tty,那么孩子最有可能行缓冲区输出,但当stdout是管道时,块缓冲区会被输出。 – 2013-03-01 19:52:15

+1

与你的问题不完全相关,但是'execl()'*如果成功则不会返回*。如果因为任何原因失败了,它会返回,但是你返回'RS_SUCCESS',这可能会掩盖道路上的某些东西...... – twalberg 2013-03-01 22:24:13

回答

1

你有fflush(stdin)它什么都不做。fflush只用于输出流。我相信如果你改变这个fflush(stdout),它会解决你的缓冲问题。

1

你也应该closedup2之后的复制管道,这样进程将有机会检测到EOF。

您可以在execl之后加perror;更好地使用execlp;给出argv[0]而不是NULL。 如果getenv("SHELL")NULL会发生什么情况?你确定它是bash

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