Jump to content

Escrever/Ler inteiros de um pipe


Dioguex
 Share

Recommended Posts

Boa tarde a todos,

Estou a desenvolver um programa em que, em determinado momento tenho que escrever alguns dados num pipe.

Quando envio, num processo, para o pipe uma string, o outro processo consegue ler sem problemas, mas quando envio um inteiro, o outro processo recebe sempre 0.

O código que tenho para escrever e ler o inteiro é o seguinte:

Escrever para o pipe (neste caso o num_dir é 3):

if((write(1, &num_dir, sizeof(num_dir)) != sizeof(num_dir))){
   perror("Erro na escrita no pipe!\n");
   return errno;

Ler do pipe (aqui o num_dir é sempre 0):

read(0, &num_dir, sizeof(num_dir));

Que poderei estar a fazer mal?

Obrigado.

Dioguex

Edited by Dioguex
Link to comment
Share on other sites

Eu no processo que escrever tenho:

//fechar a posição de escrita
close(1);

//redireciona o fds para a posição de escrita
dup(fds[1]);

//fecha os que não são usados
close(fds[0]);
close(fds[1]);

No processo que leio tenho:

//fecha o descritor para leitura
close(0);

//duplica o descritor de leitura
dup(fds[0]);

//fecha os que não são usados
close(fds[0]);
close(fds[1]);

Era isto que dizias?

Obrigado.

Cumprimentos,

Edited by Dioguex
Link to comment
Share on other sites

Agradeço a tua resposta.

Mas não estou a entender o problema.

Os file descriptors do pipe estão a ser criados:

if (pipe (fds) < 0){
    perror("Erro na criação do pipe!\n");
    exit (-1);
}

Liberto o stdout no processo de escrita e duplico o descritor de escrita que fica no stdout e de seguida fecho os descritores de leitura e escrita:

close(1);
dup(fds[1]);
close(fds[0]);
close(fds[1]);

Faço o mesmo no processo de leitura:

close(0);
dup(fds[0]);
close(fds[0]);
close(fds[1]);

E por ultimo uso o stdout para escrita e o stdin para leitura:

write(1, &num_dir, sizeof(num_dir));
read(0, &num_dir, sizeof(num_dir));

Tenho exactamente o mesmo procedimento para uma string e funciona correctamente, só não funciona com inteiros.

Cumprimentos,

Link to comment
Share on other sites

Obrigado pelas respostas.

Segui as tuas indicações e retirei o fecho do stdout e stdin e utilizei os file descriptors nas funções write e read e já funcionou.

Segue o código completo (estou a fazer o código por partes ainda não está tudo completo e revisto, deve conter alguns erros):

#include <stdio.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <dirent.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>
#define TAM 500
char comparestr (char text[], char *sub_text);
int main(int argc, const char * argv[]) {
char tmp[TAM];
pid_t pid, *child_pid;
int fds[2];
DIR *cdir;
struct dirent *dit;
struct stat statbuf;
char currentPath[MAXPATHLEN];
size_t num_dir = 0;
char buff[999];
char *array_path[TAM];
int fp = 0;
long n = 0;
int tam = 0;
char *str;
int i = 0;

//verficar se os argumentos passados ao programa estão correctos
if (argc != 3){
	perror("Falta o nome do ficheiro ou a string a pesquisar!\n");
	exit (1);
}

//criar o pipe que vai ser partilhado por pai e filhos
if (pipe (fds) < 0){
	perror("Erro na criação do pipe!\n");
	exit (-1);
}

//duplicar processo

if ((pid = fork()) < 0){
	perror("Erro na duplicação de processos!\n");
	exit (1);
}

//codigo do filho e do pai
if (pid == 0){ //codigo filho

	//fechar a posição de escrita
	//close(1);

	//redireciona o fds para a posição de escrita
	//dup(fds[1]);

	//fecha os que não são usados
	//close(fds[0]);
	//close(fds[1]);

	while(1){
		//abrir o directorio
		if ((cdir = opendir(argv[1])) == NULL){
			perror ("Erro a abrir o directorio!\n");
			return errno;
		}


		//vai percorrer o directorio aberto
		while ((dit = readdir(cdir)) != NULL){
			if(strcmp(dit->d_name, ".") == 0 || strcmp(dit->d_name, "..") == 0 || strcmp(dit->d_name, ".DS_Store") ==0) //ignora os directorios . e ..
				continue;

			strcat (currentPath, argv[1]); //coloca o caminho passado ao programa no currentPath

			// se o ultimo caracter do currentPath nao for / acrescentamos
			if (currentPath[strlen(currentPath) - 1] != '/'){
				strcat(currentPath,"/");
			}

			strcat(currentPath, dit->d_name); //adicionamos o nome do directorio em que estamos

			//verificamos se as informações do directorio são carregas
			if(stat(currentPath, &statbuf) == -1){
				perror("stat");
				return errno;
			}

			//verificamos se é directorio
			if(S_ISDIR(statbuf.st_mode)){
				num_dir++;
				array_path[i] = (char*)malloc(strlen(currentPath) + 1 * sizeof(char));
				strcpy(*(array_path + i), currentPath);
				i++;
				currentPath[0]='\0';
				continue;
			}

			//copiar argv 2 para str
			tam = sizeof(argv[2]);
			str = (char*)malloc(sizeof(str) * tam);
			strcpy(str, argv[2]);

			//verificamos se é ficheiro
			if(S_ISREG(statbuf.st_mode)){
				//abrir ficheiro e comparar a string
				fp = open(currentPath, O_RDWR); // Abertura do ficheiro

				if (fp == -1){
					perror("Erro abrir o ficheiro!\n");
					return errno;
				}

				n = read(fp, buff, sizeof(buff));
					if ((comparestr(buff, str)) == 1){

						//escreve no pipe
						write(1, currentPath, sizeof(currentPath) + 1);
						close(1);

						//envia o sinal ao pai
						//kill(pid, SIGSTOP);

						currentPath[0]='\0';
						exit(0);

					}else{
						write(fds[1], &num_dir, sizeof(num_dir));
						close(fds[1]);
						exit(0);
					}
			}
		}
		buff[0] = '\0';
		closedir(cdir);
	}
}else{
	//espera que o filho termine
	waitpid(pid, 0, 0);

	//fecha o descritor para leitura
	//close(0);

	//duplica o descritor de leitura
	//dup(fds[0]);

	//fecha os que não são usados
	//close(fds[0]);
	//close(fds[1]);

	//le do pipe
	//read (0, tmp, sizeof(tmp) + 1);

	read(fds[0], &num_dir, sizeof(num_dir));

	if (num_dir != 0){
		printf("%ld\n", num_dir);
	}else{
		printf ("O caminho do ficheiro é: %s\n", tmp);
	}

	child_pid = (int*)malloc (sizeof(int) * num_dir);
	for (i = 0; i < num_dir; i++){
		if((child_pid[i] = fork()) == 0){ //código dos filhos
			while(1){
				//abrir o directorio
				if ((cdir = opendir(array_path[i])) == NULL){
					perror ("Erro a abrir o directorio!\n");
					return errno;
				}

				//vai percorrer o directorio aberto
				while ((dit = readdir(cdir)) != NULL){
					if(strcmp(dit->d_name, ".") == 0 || strcmp(dit->d_name, "..") == 0 || strcmp(dit->d_name, ".DS_Store") ==0)
					continue;


				}

			}

		}

	}
}
return 0;
}
char comparestr (char text[], char *sub_text){
int n = sizeof(sub_text);
int m = sizeof(*text);
int i = 0;
int j = 0;

for (i = 0; i < n-m; i++) {
	j = 0;
	while (j < m && text[i + j] == sub_text[j]) {
		j++;
	}
	if (j == m) return 1;
}
return -1;
}

Neste código já estou a usar os descritores nas funções.

Obrigado.

Cumprimentos.

Edited by Dioguex
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.