2015-04-16 11 views
6

Sagen wir, ich habe zwei Programme - input.c & output.c Alles, was ich tun möchte, ist einige Nutzlast/Zeichen im "Halbpyramide" -Format in ein anderes mit execl() -Funktion zu senden .C - Junk Zeichen am Ausgang

input.c

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/wait.h> 

#define SIZE 1024 

int length; 

int main(int argc, char *argv[]) 
{ 
    pid_t pid; 
    char *target; 
    //char payload[length+1]; 
    char payload[SIZE + 1]; 
    int status; 
    int i = 0; 

    if(argc < 2) 
    { 
     printf("Usage %s <length> <target>\n", argv[0]); 
     exit(EXIT_FAILURE); 
    } 

    length = atoi(argv[1]); 
    target = argv[2]; 

    while(i < length) 
    { 
     pid = fork(); 

     if(pid != 0) 
     { 
      waitpid(-1, &status, 0); 
      //exit(0); 
     } 

     if(pid == 0) 
     { 
      payload[i] = 'A'; 
      payload[i + 1] = '\0'; 
      execl(target, target, payload, NULL); 
      //printf("%s\n", payload); 
     } 
     ++i; 
    } 
    return 0; 
} 

kommentiert Passagen sind nur für Debugging-Zwecke. Denn wie Sie sehen können (während Sie es versuchen), wenn Sie es nur drucken möchten, funktioniert alles einwandfrei.

output.c (oder wenn Sie wollen 'target.c')

#include <stdio.h> 
#include <string.h> 

int main(int argc, char *argv[]) 
{ 
    char buffer[30]; 
    strncpy(buffer, argv[1], sizeof(buffer)); 
    printf("Output: %s\n", buffer); 

    return 0; 
} 

Wenn ich kompilieren input.c wie:

gcc input.c -o input 

& output.c :

gcc output.c -o output 

Ok. Jetzt ist alles vorbereitet. Sagen wir mal, ich möchte eine Nutzlast senden - Länge 6

./input 6 ./output 

aber alles, was ich auf die Produktion bekommen, ist nur diese (oder einfach mit einem anderen Dschunken Zeichen):

Output: A 
Output: 0A 
Output: 0,A 
Output: 0,�A 
Output: 0,�8A 
Output: 0,�8�A 

ich so viele versucht Dinge, aber alle von ihnen scheiterten und die Ausgabe war immer noch die gleiche, wie Sie oben sehen können.

Ich wäre sehr dankbar, wenn mir jemand helfen könnte und mir vielleicht zeigen könnte, wo das Problem ist. Kann es Probleme geben, die Funktionen fork() und execl() zusammen zu verwenden?

Antwort

5

Verstanden, Sie nicht payloadin das Kind Blockcode ...

Hier ist ein Update (kann es jetzt nicht testen) aktualisieren sollte:

while(i < length) 
    { 
     pid = fork(); 
     payload[i] = 'A'; 
     payload[i + 1] = '\0'; 

     if(pid != 0) 
     { 
      waitpid(-1, &status, 0); 
      //exit(0); 
     } 

     if(pid == 0) 
     { 
      execl(target, target, payload, NULL); 
      //printf("%s\n", payload); 
     } 
     ++i; 
    } 

[removed unabhängigen Satz]

EDIT (zusätzliche Erklärungen): payload Aktualisierung muss in sowohl Eltern- und Kind-Code sein. Wenn Sie nicht verstehen, warum, kann ich weitere Erklärungen hinzufügen.

EDIT2 (wie angefordert). Sie möchten die Aktualisierungsnutzlast für den nächsten gegabelten untergeordneten Prozess aktualisieren. In Ihrem Code wird der gesamte Kindercode durch execl() in target ersetzt. So wird die fork()nur durch den ersten übergeordneten Prozess (der Stamm) ausgeführt.

Sie müssen Payload durch das erste Elternteil aktualisieren und es auch allen Kindern zugänglich machen.es in diesem Block setzen entweder nicht:

// block only executed by the first parent. 
if(pid != 0) 
{ 
    waitpid(-1, &status, 0); 
} 

Daher müssen Sie es an einem Ort sowohl zugänglich von den Eltern und dem Kind aktualisieren: nach dem fork(), bevor if(pid == 0) Block.

In Ihrem Code erhöhen Sie i im allgemeinen Block, aber die payload des übergeordneten Elements wird nie aktualisiert. So in dem Kind Block, kurz vor den execl(), geben Sie Ihre A\0' am Ende eines uninitialized C-String '.

+0

Du bist ein Mann! Ja, es funktioniert wie ein Charme . vielen Dank für Ihre Hilfe. und ja, wenn es für Sie nicht Problem ist, würde ich für einige detailliertere Erklärung dankbar sein, denn ich glaube nicht, dass ich es auf 100% zu verstehen und ich will nicht etwas tun ähnlicher Fehler in der Zukunft. – Yeez

+0

Ok, ich füge ein paar Erklärungen hinzu. Es war ein guter "Refresh h "Training für mich. – Amessihel

+0

Hehe, ich bin froh, dass es so war. Wie auch immer, jetzt überprüfe ich es noch einmal und ich habe eine zusätzliche Frage - wenn du antworten kannst. Falls ich strncpy durch strcpy ersetze und "./input 80 ./output" mache, warum sehe ich dann irgendwo auf der Ausgabe "Segmentation fault"? Ich bin nur Neugierig. – Yeez

2

Wenn Ihr Programm Gabeln, es einen neuen Prozess erstellt. Dieses neue Verfahren, nach if(pid == 0), ändert die payload und läuft exec (dh führt output, die dann stirbt. Das heißt, Ihre Änderung der Nutzlast in dem Kind bleibt, und hat keinen Einfluss auf den übergeordneten Prozess. Nur ++i der Fall ist, weshalb Sie sind unitialized Daten zu sehen.

Verschieben Nutzlast Änderung vor Gabel (oder zumindest aus Kindern nur Block), so ist es in den Eltern auch.