Problemi con comandi tubazioni in C
Domanda
Sto cercando di creare un semplice shell in C per Unix. Sono stato in grado di fare tutte le analisi di comandi e l'esecuzione, ma sto avendo un problema con le tubazioni. Credo che il problema è che non sto agganciando nel tubo corretto per l'ingresso del secondo comando.
Per esempio, se si digita "ls | wc", per mettere in pausa dopo il comando "wc", che credo sia perché la sua attesa di input. Credo che il problema è quando uso dup2 (lettura [i], 0), e la sua non agganciando nel tubo corretto.
So che questo è un po 'di un'ampia domanda, ma se ci sono dei puntatori ho potuto ottenere, lo apprezzerei. Ecco il codice che crea nuovi processi e cerca di tubazione loro.
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: sono stato in grado di capirlo, grazie a Richard. E 'stata una combinazione di chiusura dei descrittori di file nell'ordine sbagliato e non chiudendo un po' a tutti. Ecco il codice di lavoro.
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;
}
Soluzione
Credo che il problema può essere che si attende per ogni processo all'interno del ciclo e quindi chiudere tutti i descrittori di file. Questo rende i descrittori di file non validi per la chiamata successiva a dup2 () e si traduce in stdin per il processo successivo rimanendo invariata.
Solo una supposizione, non ho eseguito il codice.
Altri suggerimenti
Quando digito "ls | wc" wc fa come previsto e stampa il numero di parole in uscita dal comando ls. Ricordate che quando si è i comandi di tubazioni utilizzando "|" non è necessario creare tubi nell'applicazione. Le prime necessità comando per l'output stdout e il secondo ha bisogno di comando per leggere che output standard.