Estou tentando construir um pequeno programa c que estude variáveis de ambiente. Quando executo o programa com um parâmetro, ele deve imitar
printenv | lista de parâmetros grep | sort | menos
Então, eu uso tubos para conectar todas essas saídas, masagora o problema é que quando eu insiro uma variável de ambiente que não existe, o programa ainda executa tudo e, idealmente, eu quero que ele saia após o grep.
Aqui está o código onde executo grep com execvp e perror, mas perror é apenas quando execvp não funciona.
Eu sei das páginas de manual que grep dá 0 quandouma ou mais linhas selecionadas e 1 quando Nenhuma linha foi selecionada e> 1 quando ocorreu um erro. Como faço para controlar quando o grep não seleciona nenhuma linha e sai do programa sem continuar com a classificação e menos?
execvp( "grep", argv); /* runs grep */
perror( "Cannot exec grep" ); exit( 1 );
/* CHILD that handles grep function.
This child executes grep.
*/
if(pid == 0)
{
if(-1 == dup2(pipa[READ],STDIN_FILENO)) /* redirect pipe1 to stdin */
{perror("Cannot dup"); exit(EXIT_FAILURE);}
if(-1 == dup2(pipa2[WRITE],STDOUT_FILENO)) /* redirect stdout to pipe2 */
{perror("Cannot dup"); exit(EXIT_FAILURE);}
if(-1 == close(pipa[WRITE])) /* Close write, we dont need it */
{perror("Cannot close pipe (write-end)[GREP]"); exit(EXIT_FAILURE);}
if(-1 == close(pipa[READ])) /* Close read on pipe1 */
{perror("Cannot close pipe (read-end)[GREP]"); exit(EXIT_FAILURE);}
if(-1 == close(pipa2[READ])) /* Close read on pipe2, we dont need it */
{perror("Cannot close pipe2 (read-end)[GREP]"); exit(EXIT_FAILURE);}
if(-1 == close(pipa2[WRITE])) /* Close write on pipe2, we we have it on stdout now */
{perror("Cannot close pipe2 (read-end)[GREP]"); exit(EXIT_FAILURE);}
if(argc > 1) /* filter or no */
{
argv[0] = "grep";
printf("%s",argv[0]);
execvp( "grep", argv); /* runs grep */
perror( "Cannot exec grep" ); exit( 1 );
}
exit(0);
}
/* PARENT */
if(argc < 2) /* No arguments? */
{
if(-1 == dup2(pipa2[WRITE],pipa[WRITE])) /* Redirect stdin to pipe2 write (which is in STDOUT_FILENO) */
{perror("Cannot dup"); exit(EXIT_FAILURE);}
}
/* Sends enivomrent data to grep */
for(i=0; envp[i] != 0; i++)
{
write(pipa[WRITE],envp[i],strlen(envp[i]));
write(pipa[WRITE],"n",1);
}
nchildren++;
/* Create 3rd pipe */
if(pipe(pipa3) == -1)
{exit(EXIT_FAILURE);}
/* Close 1st pipe */
if(-1 == close(pipa[WRITE]))
{perror("Cannot close pipe (write-end)"); exit(EXIT_FAILURE);}
if(-1 == close(pipa[READ]))
{perror("Cannot close pipe (read-end)"); exit(EXIT_FAILURE);}
/* Close write from second pipe */
if(-1 == close(pipa2[WRITE]))
{perror("Cannot close pipe (read-end)"); exit(EXIT_FAILURE);}
/* fork again */
if((pid = fork()) == -1) /* ERROR */
{exit(EXIT_FAILURE);}
/* CHILD that handles sort function.
This child executes sort.
*/
if(pid == 0)
{
if(-1 == dup2(pipa2[READ],STDIN_FILENO)) /* redirect pipe2 read to stdin */
{perror("Cannot dup"); exit(EXIT_FAILURE);}
if(-1 == dup2(pipa3[WRITE],STDOUT_FILENO)) /* redirect stdout to pipe3 write */
{perror("Cannot dup"); exit(EXIT_FAILURE);}
if(-1 == close(pipa2[READ])) /* Close write, we have it on stdin now */
{perror("Cannot close pipe (write-end)[SORT]"); exit(EXIT_FAILURE);}
if(-1 == close(pipa3[READ])) /* Close read on pipe3, we dont need it */
{perror("Cannot close pipe (write-end)[SORT]"); exit(EXIT_FAILURE);}
if(-1 == close(pipa3[WRITE])) /* Close write on pipe3, we have it on stdout now*/
{perror("Cannot close pipe (write-end)[SORT]"); exit(EXIT_FAILURE);}
(void) execlp( "sort", "", NULL ); /* runs sort */
perror( "Cannot exec sort" ); exit( 1 );
}
/* PARENT */
if(-1 == close(pipa2[READ])) /* Close read from pipe2 */
{perror("Cannot close pipe (read-end)[PARENT]"); exit(1);}
if(-1 == close(pipa3[WRITE])) /* Close write from pipe3*/
{perror("Cannot close pipe (write-end)[PARENT]"); exit(1);}
Respostas:
1 para resposta № 1Se execvp falhar, _exit será chamado.
Página de manual do execvp:
Valor de retorno Se qualquer uma das funções da família exec () retornar, um erro terá ocorrido. O valor de retorno é -1, e a variável global errno será definida para indicar o erro.