Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

_Isis_

Pipe e bad file descriptot

Recommended Posts

#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

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

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.