2 Stimmen

Fragen zur Verwendung von forkpty zur Erstellung eines Pseudo-Terminals für ssh in C

pid = forkpty (&pty,0,0,0);
if (pid == 0) {
    execl ("/usr/bin/ssh", "ssh", hostname, NULL);
    exit (0);
} else if (pid > 0) {
    ssh_pid = pid;
    ssh_pty = pty;
    if(child_ssh_success()) {
        get_user_input();
        send_user_input_to_child_ssh_and_child_forword_it_to_remote_server();
        get_remote_server_response_from_child();
        display_response_to_stdout();
    }
}

Wie kann ich feststellen, ob ssh Erfolg oder nicht?

Wie können Eltern wissen, dass ihr Kind erfolgreich ssh-ed an einen entfernten Server, damit die Eltern etwas an den entfernten Server senden können?

0voto

Pavan Manjunath Punkte 26281

Verwenden Sie die Funktion waitpid in der übergeordneten Datei ( d.h. innerhalb Ihrer else if ( pid>0) Bedingung ), um den Status des Kindes zu erhalten

#include   <sys/wait.h>
pid_t waitpid(pid_t pid, int *stat_loc, int options);

Zitat IBM DeveloperWorks

stat_loc

Ein Zeiger auf eine Ganzzahl, an die die Wait-Funktion den Status zurückgibt des Kindprozesses zurückgibt. Wenn die waitpid-Funktion zurückkehrt, weil ein Prozess beendet wurde, ist der Rückgabewert gleich der pid des beendeten Prozesses. Dazu muss der Wert von stat_loc nicht NULL sein, wird die Information an dem Ort gespeichert, auf den stat_loc zeigt. Wenn Status von einem beendeten Kindprozess zurückgegeben wird, der einen Wert von 0 zurückgegeben hat, ist der Wert, der an der Stelle gespeichert ist, auf die stat_loc verweist 0. Wenn der Rückgabewert größer als 0 ist, können Sie diese Informationen mit den folgenden Makros auswerten: WEXITSTATUS WIFEXITED WIFSIGNALED WTERMSIG.

Wenn also stat_loc Null ist, müssen Sie Mai davon ausgehen, dass SSH normal beendet wurde

EDIT1

Wenn Sie nicht möchten, dass der Elternteil blockiert wird, müssen Sie einen Signalhandler für SIGCHLD und dasselbe tun waitpid dort. Dieses Mal, da das Kind bereits abgebrochen hat, waitpid wird sofort zurückkehren

Etwas in dieser Richtung

pid_t pid;
int main ()
{
struct sigaction action;

memset (&action, 0, sizeof(action));
action.sa_handler = sigchld_handler;

if (sigaction(SIGCHLD, &action, 0)) 
    {
    perror ("sigaction");
    return 1;
}

pid = forkpty (&pty,0,0,0);
if (pid == 0) 
{
    execl ("/usr/bin/ssh", "ssh", hostname, NULL);
    exit (0);
} 
else if (pid > 0) 
{
    ssh_pid = pid;
    ssh_pty = pty;
}
}

/* SIGCHLD handler. */
static void sigchld_handler (int sig)
{
    int chld_state;

    while (waitpid(pid,&child_state,options) > 0) 
    {
       if (WIFEXITED(chld_state)) 
       {
           printf("Child exited with RC=%d\n",WEXITSTATUS(chld_state));
       }
    }

}

Machen Sie pid global, so dass Sie darauf von sigchld_handler zu. Im Allgemeinen ssh gibt zurück. 0 für ERFOLG und 255 (oder einen anderen positiven Wert) für das Scheitern, obwohl ich mir da nicht ganz sicher bin.

EDIT2

Aus unserer Diskussion geht hervor, dass Sie auch auf dem entfernten Server Befehle ausführen möchten. Ich schlage vor, Sie führen ssh ce

ssh root@remoteserver.com 'ls -l'

Sie können diese Argumente von ssh über execl() und wie erklärt in EDIT1 können Sie den Rückgabewert überprüfen, um zu sehen, ob alles gut gelaufen ist. Außerdem, da Sie ssh vom Code aus, möchten Sie das Passwort vielleicht nicht manuell eingeben. Hier ist, wie Sie tun Anmeldung ohne Passwort

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X