1

私はUNIXが初めてで、C言語を使用したプログラミングは初めてです。

私がやりたいのは、 の簡単な実装ですtelnet

両側(サーバーとクライアント)で必要なすべての接続を行いました。

サーバー上: 受け取ったすべてのリクエストをfork処理するための新しいプロセス

void createProcess() {
    int pid = fork();
    if( pid == CHILD ) {
        transferHandling(s);
        close(s);
        _exit(0);
    }
}

クライアント側からのコマンドを処理するためのこのメソッド:

int transferHandling(int socket) {
    char buf[20];
    char command[1024];
    int n, pid, fd[2];
    char *shell, *ps1;
    if( checkLogin(socket) == 0 ) { // Used to check user account
        send(socket, "Login Succeeded\n", 16, 0);
        if( setupENV(info->name) == 0 ) {  // setuid and setgid for the user
            if( pipe(fd) == ERROR ) {
                send(socket, "Server Busy\n", 12, 0);
                return 1;
            }
                    // Here I make a process to run the default shell for the user
                    // and make pipe between them
            if((pid = fork()) > 0) {
                dup2(fd[0], STDOUT_FILENO);
                close(fd[1]);

                //read commands from socket
                while(1) {
                    n = recv(socket, command, 1024, 0);
                                    // send the commands received to the child which contains the default shell
                    write(fd[0], command, n);
                }
            } else {
                dup2(fd[1], STDIN_FILENO);
                dup2(socket, STDOUT_FILENO);
                dup2(socket, STDERR_FILENO);
                close(fd[0]);

                //run default shell
                shell = getpwnam(info->name)->pw_shell;
                execlp(shell, shell, NULL);
            }
        } else {
            return 1; // setup ENV error
        }
    } else {
        send(socket, "Login Failed\n", 13, 0);
    }
}

このプログラムはどのコマンドでも正常に実行されますが、クライアントが次のようなコマンドを書き込むと、wc, cd, bash (to run any other shell). プログラムが停止しています。

これは、接続がセットアップされた後のクライアント側です。

if(login(soc)) { // send the user information for the server
        char cmd[2024], cc[1024];
        int n;
        while(1) {
            printf("Reading\n");
            write(1, "username@hostname> ", 19);
            n = read(0, cmd, 2024);  // read the command from the STDIN, and send it to server
            send(soc, cmd, n, 0);

            printf("Receiving Now\n");
            n = recv(soc, cmd, 2024, 0); // getting back the command output
            write(1, cmd, n);
        }
    }
4

1 に答える 1

0

パイプ ファイル記述子が間違っています。あなたがすべき:

write(fd[1], ...);

と:

dup2(fd[0], STDIN_FILENO);

ところで、中間プロセスがソケットからコマンドを読み取り、パイプを介してシェルに送信する必要はありません。シェルの入力をソケットから直接リダイレクトできます。dup2()また、パイプに直接書き込む場合は必要ありません。最後に、これを行うための無限ループは、シェルが死ぬとスピンするため、非常に悪い考えのようです。

于 2013-03-15T09:14:36.817 に答える