2013-03-01 100 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(;;)獲得無限循環)