2

プログラムをロードしてソケットioをこれらにリダイレクトするソケットを作成しようとしています。inetd のように聞こえますが、私が知る限り、inetd はポートが要求されたときにプログラムをロードします。永久にロードしたい。

ここまでは順調ですね。ソケットサーバーを書くのはそれほど難しいことではありませんが、残りはうまくいきませんでした。私は基本的にパイプ()、dup2()を開き、それをstdinとstdout、およびexecv()プログラムに開きたいと思っています。

問題は、呼び出されたプログラムが入力を取得しないことです。テスト プログラムで表示してみます。誰か教えてください、何が悪いのですか?

int create_program_fork(int *ios, char const *program) { 
// create pipes to program 
if (pipe(ios) != 0) { 
    return -1; 
} 

// fork to new process 
int f = fork(); 
if (f < 0) { 
    // fork didn't work 
    close(ios[0]); 
    close(ios[1]); 
    return(-1); 
} 
if (f > 0) { 
    // master hasn't much to do here 
    return f; 
} 
// *** Child Process 
// close std** file descriptors 
printf ("executing program"); 
close(STDIN_FILENO); 
close(STDOUT_FILENO); 
// duplicate pipes as std** 
dup2(ios[0], STDIN_FILENO); 
dup2(ios[1], STDOUT_FILENO); 
// close pipes 
close(ios[0]); 
close(ios[1]); 
// call program 
return execvp(program, NULL ); 
} 

int main(int argc, char *argv[]) { 
int ios[2]; 

// call program 
int pid = create_program_fork(ios, "/bin/bash"); 
if (0 != pid){ 
    exit(EXIT_FAILURE); 
} 

char const exit_order[] = "exit\0"; 
char const order[] = ">/tmp/test.txt\0"; 
// do something 
write(ios[1], order, strlen(order)); 
// bash should stop then.. 
write(ios[1], exit_order, strlen(exit_order));   
return 0; 
}
4

1 に答える 1

1

問題の原因が 2 つ考えられます。

1) パイプの書き込み部分が子の stdout にリダイレクトされるため、新しいプロセスの出力が入力に送り返されます。子側でパイプの読み取り部分のみを複製することをお勧めします。子の出力を傍受したい場合は、別のチャネルが必要です (つまり、新しいパイプ、または単に親と子の両方が同じ stdout を共有できるようにする)。

2) 送信した文字列には、行指向のコマンドが含まれているようです。子プロセスが文字列の末尾に改行を期待している可能性があります。これは非常に一般的な問題の原因です。子供が入力を読む方法を確認することをお勧めします。文字列の末尾に "\n" があると役立ちます (ちなみに、C 文字列の末尾に明示的に "\0" を追加する必要はありません。コンパイラが自動的に追加してくれるからです。とにかく、strlen はそうしません。 "\0" を数えます)。

于 2012-11-08T09:05:22.120 に答える