_Isis_ 202 Denunciar post Postado Agosto 30, 2008 #include "leitura.h" #include <signal.h> #include <sys/wait.h> #include <sys/types.h> #include <unistd.h> #define ERRARG "\nArgumentos inválidos." #define ERRPIP "\nErro ao criar o pipe." #include <errno.h> extern char **listaArquivos; extern int contadorArquivos; int pipeDesc[2]; char *entradaPalavras; int main(int argc,char *argv[]) { const char *opcoes[]={"-np","-f"}; if(argc != 5) { printf("Uso:%s -np <numero_de_processos> -f <arquivo>\n",argv[0]); exit(1); } if (strcmp(argv[1],opcoes[0]) || strcmp(argv[3],opcoes[1])) { puts(ERRARG); exit(1); } listaArquivos = (char **)malloc(0); hasErrorMem(&listaArquivos); leStdin(); if(pipe(pipeDesc) == -1) { puts(ERRPIP); exit(3); }; int processos = atoi(argv[2]); // Necessário para que o getline opere corretamente,já que a especificação da função diz que ele // pára de ler a string quando encontra um \n ou EOF. Se o pipe for lido cru,lixo vai aparecer. entradaPalavras = (char *)malloc(strlen(argv[4])+1); strcpy(entradaPalavras,argv[4]); entradaPalavras[strlen(argv[4])] = '\n'; entradaPalavras[strlen(argv[4])+1] = '\0'; pid_t pid; int status; for(;processos > 0;processos--) { pid = fork(); if( pid == 0 ) break; else if (pid > 0) { // Escrever nome do arquivo de strings no pipe write(pipeDesc[1],entradaPalavras,strlen(entradaPalavras)); // Escrever nome do arquivo a pesquisar write(pipeDesc[1],listaArquivos[contadorArquivos-1],strlen(listaArquivos[contadorArquivos-1])); contadorArquivos--; } } if (pid == 0) { int ch_stat; FILE *tp; size_t lidos; char *arquivoFonte = NULL; char *arquivoPesquisa = NULL; char **palavrasAPesquisar = NULL; int contadorPalavras = 0; // Declarar uma struct que vai conter uma string procurada, um contador de ocorrencias e o nome do arquivo. // Declarar um array dessa struct // Le arquivo de strings tp = fdopen(pipeDesc[0],"r"); getline(&arquivoFonte,&lidos,tp); fclose(tp); // A SEGUIR EM LOOP ATE SIGKILL //puts("FILHO"); tp = fdopen(pipeDesc[0],"r"); printf("%x\n",tp); getline(&arquivoPesquisa,&lidos,tp); puts("LI"); fclose(tp); printf("FILHO %d : %s",getpid(),arquivoPesquisa); // Lê palavras a buscar // Função aqui //Codigo de contagem // Escrever resultados no pipe // Assinalar SIGUSR2 ao pai exit(0); } else if (pid > 0) { pid_t ch_pid; puts("--------"); while ((ch_pid = wait(NULL)) && ch_pid != -1) { printf("FILHO:%d\n",ch_pid); } exit(0); } } leitura.c #include "leitura.h" char ** listaArquivos; int contadorArquivos = 0; void hasErrorMem(void *F) { if (F == NULL) { puts(ERRALC); exit(2); } } void leStdin() { char *temp = (char *)malloc(sizeof(char)); size_t lidos; while(getline(&temp,&lidos,stdin) >-1){ listaArquivos = (char **)realloc(listaArquivos,(contadorArquivos+1)*sizeof(temp)); hasErrorMem(&listaArquivos); listaArquivos[contadorArquivos] = (char *)malloc(sizeof(temp)); hasErrorMem(&listaArquivos[contadorArquivos]); strcpy(listaArquivos[contadorArquivos],temp); contadorArquivos++; } } char ** lePalavras(const char* filename,int *cont) { char ** listaPalavras = (char**)malloc(0); hasErrorMem(&listaPalavras); char *tmp = NULL; FILE *fp = fopen(filename,"r"); size_t lidos; while(getline(&tmp,&lidos,fp) > -1){ listaPalavras = (char **)realloc(listaPalavras,( (*cont)+1)*sizeof(char *)); listaPalavras[ (*cont)] = (char *)malloc(sizeof(char)*strlen(tmp)); strcpy(listaPalavras[(*cont)],tmp); *cont++; free(tmp); tmp = NULL; } fclose(fp); return listaPalavras; } leitura.h #define _GNU_SOURCE #include <stdlib.h> #include <stdio.h> #include <string.h> #define ERRALC "\nErro na alocação de memória." void leStdin(void); char ** lePalavras(const char *,int *); void hasErrorMem(void *); O segundo fdopen retorna 0 como FILE * e a variável errno é setada com 9, que é bad file descriptor. A princípio não posso fechar o pipe de leitura (se eu reabrir ele com popen,o shell vai forkar e não é isso que eu quero). Eu sei que o processo pai continua vivo,mas vou me preocupar com isso depois que conseguir ler do pipe. O problema é que a manpage do errno.h não é muito explicativa. Compartilhar este post Link para o post Compartilhar em outros sites
_Isis_ 202 Denunciar post Postado Agosto 31, 2008 Coisa porca... No mínimo o FILE * é associado (entenda-se "grudado") com o pipe e se eu fecho o arquivo fecho o pipe de leitura também... tp = fdopen(pipeDesc[0],"r"); getline(&arquivoFonte,&lidos,tp); arquivoFonte[strlen(arquivoFonte)-1] = '\0'; // A SEGUIR EM LOOP ATE SIGKILL getline(&arquivoPesquisa,&lidos,tp); arquivoPesquisa[strlen(arquivoPesquisa)-1] = '\0'; printf("FILHO %d : %s \t%s\n:",getpid(),arquivoPesquisa); Isso funciona...praticamente tenho que manter aberto o FILE * durante todo o programa enquanto o processo filho executar... Compartilhar este post Link para o post Compartilhar em outros sites