Frage

Ich versuche, eine einfache Shell in C für Unix zu erstellen. Ich konnte die gesamte Parsen von Befehlen und Ausführung machen, aber ich habe ein Problem mit Rohrleitungen. Ich denke, das Problem ist, dass ich mich nicht in das richtige Rohr für die Eingabe des zweiten Befehls anschließe.

Wenn ich beispielsweise "ls | wc" eingeben werde, wird es nach dem Befehl "WC" innehalten, was meiner Meinung nach darauf zurückzuführen ist, dass es auf Eingaben wartet. Ich denke, das Problem ist, wenn ich DUP2 (lese [i], 0) verwende und es nicht in das richtige Rohr einbaut.

Ich weiß, dass dies eine weite Frage ist, aber wenn es irgendwelche Zeiger gibt, die ich bekommen könnte, würde ich es schätzen. Hier ist der Code, der neue Prozesse erstellt und versucht, sie zu leiten.

    int fileds[2];
    int reading[num_cmds];
    int writing[num_cmds];

    int p;
    for(p=0; p < num_cmds; p++)
    {
        reading[p] = -1;
        writing[p] = -1;
    }

    int j;
    for(j=0; j < num_cmds-1; j++)    //Create pipes for commands
    {
        int fileds[2];
        pipe(fileds);
        reading[j+1] = fileds[0];
        writing[j] = fileds[1];
    }

    int i = 0;
    for(i = 0; i < num_cmds;i++)
    {           
        cmd_args = parse_cmd(cmds[i],output_file,input_file,&run_bg); //Get command and args

        pid_t childpid;
        int status;
        childpid=fork();

        if (childpid >= 0) 
        {
            if (childpid == 0) 
            {               
                if(writing[i] != -1)
                {
                    dup2(writing[i],1);
                    close(writing[i]);
                }

                if(reading[i] != -1)
                {
                    dup2(reading[i],0);
                    close(reading[i]);
                }

                int h;
                for(h = 0; h < num_cmds; h++)
                {
                    close(writing[h]);
                    close(reading[h]);
                }

                if(execvp(cmd_args[0],cmd_args) == -1) 
                {
                    perror("Problem with command");
                    exit(0);
                }
            }
            else 
            {
                wait(&status);
                int m;
                for(m = 0; m < num_cmds; m++)
                {
                    if( writing[m] != -1) close(writing[m]);
                    if( reading[m] != -1) close(reading[m]);
                }
            }
        }
        else 
        {
             perror("fork"); 
             continue;
        }


        input_file[0] = 0;
        output_file[0] = 0;
        run_bg = 0;
    }

}



Update: Ich konnte es dank Richard herausfinden. Es war eine Kombination, die Dateideskriptoren in der falschen Reihenfolge zu schließen und einige überhaupt nicht zu schließen. Hier ist der Arbeitscode.

int fileds[2];
    int reading[num_cmds];
    int writing[num_cmds];

    int p;
    for(p=0; p < num_cmds; p++)
    {
        reading[p] = -1;
        writing[p] = -1;
    }

    int j;
    for(j=0; j < num_cmds-1; j++)
    {
        int fileds[2];
        pipe(fileds);
        reading[j+1] = fileds[0];
        writing[j] = fileds[1];
    }

    int i = 0;
    for(i = 0; i < num_cmds;i++)
    {           
        cmd_args = parse_cmd(cmds[i],output_file,input_file,&run_bg);

        pid_t childpid;
        int status;
        childpid=fork();

        if (childpid >= 0) 
        {
            if (childpid == 0) 
            {               
                if(writing[i] != -1)
                {
                    close(1);
                    dup2(writing[i],1);
                }

                if(reading[i] != -1)
                {
                    close(0);
                    dup2(reading[i],0);
                }

                if(execvp(cmd_args[0],cmd_args) == -1) 
                {
                    perror("Problem with command");
                    exit(0);
                }
            }
            else 
            {

                wait(&status);
                close(writing[i]);

                if(i > 0) 
                {
                    close(reading[i]);
                }
            }
        }
        else 
        {
             perror("fork");
        }


        input_file[0] = 0;
        output_file[0] = 0;
        run_bg = 0;
    }
War es hilfreich?

Lösung

Ich denke, Ihr Problem kann sein, dass Sie auf jeden Prozess in der Schleife warten und dann alle Dateideskriptoren schließen. Dies macht die Dateideskriptoren für den nächsten Anruf bei DUP2 () ungültig und führt zu Stdin für den nächsten Prozess, der unverändert bleibt.

Nur eine Vermutung, ich habe den Code nicht ausgeführt.

Andere Tipps

Wenn ich "ls | wc" eingeben würde, funktioniert WC wie erwartet und druckt die Anzahl der Wörter aus, die vom LS -Befehl ausgeben. Denken Sie daran, dass Sie mit "|" Befehle mit Rohrbefehlern verfolgen. Sie müssen keine Rohre in Ihrer Anwendung erstellen. Der erste Befehl muss in STDOut ausgegeben werden, und der zweite Befehl muss diese Ausgabe von Standard IN lesen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top