0

fork-server について助けが必要です。私がしたいのは、クライアントを受け入れ、フォークして他のクライアントが接続できるようにすると同時に、標準出力とエラーをクライアントにリダイレクトすることです。その後、クライアントは、孫にある execlp() によって実行されるべき文字列を送信できるはずです。

論理エラーを見つけることができません..

main() で:

    while (1) {

        t = sizeof(remote);

        printf("Waiting for connection.\n");

        s2 = accept(s, (struct sockaddr*)&remote, &t);

        if (s2 == -1) {
            perror("accept");
            exit(1);
        } else {

            printf("Client connected.\n");

            if(!fork()) {

                close(1);
                dup(s2);
                handle(s2);
                exit(0);               
            }
            close(s2);
        }
    }

ハンドル () で:

    char str[100];
    int n;

    while(1) {

        n = recv(client_socket, str, 100, 0);

        if(n <= 0) {

            perror("recv");
            exit(1);
        } else {

            if(!fork()) {

                execlp("/bin/sh", "sh","­-c", str, NULL);
                exit(1);
            } 
            wait(0);
        } 
    } 

execlp の結果はクライアントにリダイレクトされず、「sh: Can't open c」というエラーが発生します。

4

2 に答える 2

1

次のように書く必要があります:execlp("/bin/sh", "sh","-c", str, NULL);オプション '-c' をシェルに渡します。"c"次のように解釈されるオプションを渡しています:c存在しないと呼ばれるスクリプトを実行します。

参照: http://unixhelp.ed.ac.uk/CGI/man-cgi?sh

別のこと: 文字列から読み取った後、文字列を NUL で終了する必要があります。

if(n > 0)
    str[n] = '\0';

'\0'また、文字列の末尾に文字を書き込むため、99 文字のみを読み取る必要があります。

于 2013-03-01T14:01:26.180 に答える
0

考えられる理由の 1 つは、実行しようとしているコマンドがコマンド検索パスにないことです。

もう 1 つの理由は、取得した文字列にコマンドその引数が含まれており、それを単一の引数execlpとして に渡すと、シェルに単一の引数として渡されるため、文字列全体がコマンドであると見なされるためです。

それが最後の場合は、コマンドとその引数をargv同様の配列に分割し、execvp代わりに使用する必要があります。

文字列が適切に終了していることも非常に重要です。接続クライアントは終了'\0'文字を送信しますか? そうでない場合は、自分で追加する必要があります (その場合、99 文字しか受信できません)。

于 2013-03-01T14:14:47.670 に答える