La shell del juguete no funciona correctamente.

No voy a mentir. Esta es una pregunta de tarea. Sin embargo, en lo que a mí respecta, los puntos han desaparecido. En este momento, solo estoy buscando una respuesta, porque creo que podría estar loco.

El objective de este progtwig es ejecutar el comando ps -A | grep (inputstring) | wc -l ps -A | grep (inputstring) | wc -l ps -A | grep (inputstring) | wc -l de una manera similar a como lo hace el shell. Entonces, yo engendro los procesos y hago que se esperen unos a otros. El proceso más nuevo, el bisnieto, execlp("ps","ps","-A",NULL) que se reemplaza a sí mismo con el proceso ps -A . Antes de que se execlp , me aseguro de que su salida estándar vaya a la salida de la tubería. El siguiente proceso en línea es wait() , y ya se ha configurado de modo que el conducto de entrada se ajusta a la entrada estándar, y la salida estándar va al conducto de salida, y ejecutará grep, y así sucesivamente.

Estoy casi seguro de que lo tengo configurado correctamente. Y sin embargo … el progtwig lo hace. No. Trabajo.

 #include  #include  #include  #define MAXLINE 1500 #define READ 0 #define WRITE 1 using namespace std; int main( int argc, char** argv ) { //* start of input block if ( argc != 2 ) { cout << "Usage: ./a.out arg1" << endl; return 0; } string in = argv[1]; // end of input block */ int pipeA[2], pipeB[2], pid, stat; // get our first set of pipes if ( pipe(pipeA) < 0 ) { cerr << "Pipe error.\n"; exit(-1); } if ( pipe(pipeB) < 0 ) { cerr << "Pipe error.\n"; exit(-1); } // make the first fork if ( (pid = fork() ) < 0 ) { cerr < 0 ) { // parent case wait(&stat); } else { // child case if ( (pid = fork()) < 0 ) { cerr < 0 ) { // child wait(&stat); dup2(pipeA[READ],READ); execlp("wc","wc","-l",NULL); } else { // grand-child if ( (pid = fork()) < 0 ) { cerr < 0 ) { // still grand-child wait(&stat); dup2(pipeB[READ],READ); dup2(pipeA[WRITE],WRITE); close(pipeB[READ]); execlp("grep","grep",in.c_str(),NULL); } else { // great grand-child dup2(pipeB[WRITE],WRITE); // t now goes to pipeB[1] close(READ); close(pipeB[READ]); execlp("ps", "ps", "-A", NULL); } } } return 0; } 

EDITAR: Cambiado a la variante de dos tubos de mi código.

Estoy prácticamente seguro de que esto es lo que estás tratando de hacer. Disculpas de antemano por la encoding descuidada. Es un poco tarde aquí y debería estar durmiendo ahora mismo:

 #include  #include  #include  #include  #include  #define READ 0 #define WRITE 1 // ps -A | grep argv[1] | wc -l int main( int argc, char** argv ) { //* start of input block if ( argc != 2 ) { std::cout << "Usage: ./a.out arg1" << std::endl; return 0; } // make local copy of argument std::string in = argv[1]; int fd1[2], fd2[2], pid; // allocate two pipe sets if (pipe(fd1) < 0 || pipe(fd2) < 0) { perror("Failed to create pipe."); return EXIT_FAILURE; } // launch first child process. if ((pid = fork()) < 0) { perror("Failed to fork child(1)"); return EXIT_FAILURE; } if (pid == 0) { // wc -l process. // stdin = fd2(read) close(fd1[READ]); close(fd1[WRITE]); close(fd2[WRITE]); dup2(fd2[READ],STDIN_FILENO); execlp("wc","wc","-l",NULL); } // fork again. this time for grep if ((pid = fork()) < 0) { perror("Failed to fork child(2)"); return EXIT_FAILURE; } if (pid == 0) { // grep argv[1] process. // stdin = fd1(read) // stdout = fd2(write) close(fd1[WRITE]); close(fd2[READ]); dup2(fd2[WRITE], STDOUT_FILENO); dup2(fd1[READ], STDIN_FILENO); execlp("grep", "grep", in.c_str(), NULL); } // fork once more. this time for ps -A if ((pid = fork()) < 0) { perror("Failed to fork child(3)"); return EXIT_FAILURE; } if (pid == 0) { // ps -A process. // stdout = fd1(write) close(fd2[WRITE]); close(fd2[READ]); close(fd1[READ]); dup2(fd1[WRITE], STDOUT_FILENO); execlp("ps", "ps", "-A", NULL); } int stat=0; wait(&stat); return EXIT_SUCCESS; } 

En mi sistema, ps -A reporta 141 líneas, de las cuales 41 tienen la palabra System algún lugar dentro, verificada simplemente ejecutando ps -A | grep System | wc -l ps -A | grep System | wc -l ps -A | grep System | wc -l . El código anterior genera precisamente la misma salida.

Espero que te ayude.

No estoy seguro, pero tal vez llamar a dup2 antes de esperar al niño solucionaría el problema de la tubería.

La razón por la que no estoy seguro es que normalmente la entrada estándar y la salida estándar están en búfer, por lo que supongo que incluso si conectas tu pipa con ellos una vez que el niño termina de correr, deberías obtener los mismos resultados, pero tal vez (si alguien sabe la respuesta). esto, por favor, corríjame) los buffers para stdin y stdout se borran con el final del proceso hijo.

Además, ¿podría actualizar el código de su pregunta para que contenga el código modificado con dos conjuntos de tuberías?