Click here to Skip to main content
15,881,248 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I get segmentation fault when i read for the second time from the fifo in the infinite loop.I don't understand why and if i don't call the function servi(...) that creat a new that send data to client i don't get a segmentation fault.I really don't understand why.
This is the code.
#include <pthread.h>//serve per il multithreading
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h> 
#include <string.h>
#include <stdio.h>

#include <errno.h>//serve per gestione errori
#include <fcntl.h>//serve per le fifo
#define MAX_BYTES (300);

//VARIABILI GLOBALI
int lung_max_msg = 30;
int lung_min_chiave = 3;
int lung_max_chiave = 10;
char nome_server[30];

void* servi(char* nome_client,char* input_messaggio,char* input_chiave,char codec);
//void codificatore(char codec,char* msg,char* chiave,char* risultato);
int main()
{	
	pthread_t pid;
	//pthread_t pid2,pid3;
	char* nome_client;
	int buf = MAX_BYTES;
	char buffer[buf];
	char* tmpcodec;
	char codec;
    char* input_messaggio;
	char* input_chiave;
	int numread;
	int fd ;
	strcpy(nome_server,"miafifo");
	//strcpy(nome_client,"fifo_lettura");
	
	printf("Programma avviato......\n");
	printf("Attesa dei client......\n");

		
	 //CREAO LA FIFO PER LEGGERE LE RICHIESTE DAI CLIENT
		int ret_val = mkfifo(nome_server,0777);
		if((ret_val == -1) && (errno != EEXIST))
		 {
			 perror("Errore durante la creazione della fifo!");
			 exit(1);
		 }
		 printf("Ho creato la FIFO\n");
		 //apro la fifo
		
		
		
		 fd = open("miafifo",O_RDONLY);
		 printf("------Ho aperto la FIFO SERVER-------- \n");
		 
		 
		
		 
	 int i = 0;
while(1)//continuo a cercare di leggere la fifo per vedere se ci sono altri client da servire
{ 		
		printf("Ciclo: %d , sto per leggere...\n",i);
		i++;
		 numread = read(fd,&buffer,buf); // <----- THERE IS THE PROBLEM

		 if(numread < 0)
		 {
			 perror("Errore lettura buffer!\n");
			 exit(1);
		 }
		 printf("\nIl buffer contiene :  \"%s\"\n",buffer);
		
if(strcmp(buffer,"") !=  0)
{
	
		printf("nuovo client..\n");
		//prelevo nome_client,messaggio,chiave e codec
		nome_client = strtok(buffer,"$");
		input_messaggio = strtok(NULL,"$");
		input_chiave = strtok(NULL,"$");
		tmpcodec = strtok(NULL,"$");
		
		codec = tmpcodec[0];
		printf("Ho prelevato i dati...\n");
		printf("Nome client = %s \n",nome_client);
		printf("Ho letto tutti i dati\n");
		//creao un thread per gestire il client

//IF I DON'T CALL THIS FUNCTION THE READ WORKS.....             pthread_create(&pid,NULL,servi(nome_client,input_messaggio,input_chiave,codec),NULL);
		//printf("Ho finito l'esecuzione del thread....\n");
		//pthread_join(pid,NULL);
		//printf("Ho chiuso la fifo del server....\n");
		//strcpy(buffer,"");
		//close(fd);//chiudo la fifo del  server
		printf("Primo client servito..\n");
		
}	   
	   
	   
	  // memset(buffer,0,sizeof(buffer));
	 strcpy(buffer,"");
}//fine while(1)


	printf("Sto chiudendo il server.....\n");
	
	
	//unlink(fd);
	exit(0);
}
void codificatore(char codec,char* msg,char* chiave,char* ris,int lung_msg,int lung_chiave)
{
	printf("Entro nella procedura codificatore()\n");
	printf("\ncodec = %c ,msg = %s ,chiave = %s ,ris = %s ,lung_msg = %d ,lung_chiave = %d \n\n\n",codec,msg,chiave,ris,lung_msg,lung_chiave);
	
	
	int maiuscolo;
	int i,j;
   for(i = 0,j=0; i < lung_msg;i++)
	{
		//controllo se nel risultato la letterA sara maiuscola o minuscola 
		//printf("ciclo for i = %d \n",i);
	    if(isupper(msg[i]))
	    {
			maiuscolo = 1;
		}
		else
		{
			maiuscolo = 0;
		}
		//trasformo tutto in minuscolo per fare piu semplicemente le operazioni di calcolo e traslitterazione
		//printf("Trasformo tutto in minuscolo\n");
		msg[i] = tolower(msg[i]);
		chiave[i] = tolower(chiave[i]);
		//printf("Ho fatto una trasformazione...\n");
		if( msg[i] == ' ') 
		{
		   ris[i] = ' ';
		   //printf("  ");
		}
		else
		{	
			//printf("Stampo dei valoti per il testing...\n");
			//printf("%d,",msg[i] - 96);
			//printf("ho stampato un valore...\n");
			//printf("%d",chiave[j] - 96);  //<----- segmentation fault!!!!!!!!!!!
			//printf("Ho finito di stampare...\n");
			
			
			//printf("controllo chiave\n");
			if(chiave[j] != ' ')
			{
				//printf("entro nel ciclo...\n");
				if(codec == '1')
				{
					//printf("Inzio la codificazione di una lettera\n");
					//questa trasformazione deve funzionare anche su codifiche diverse
				   ris[i] = ( ((msg[i] - 96 ) + (chiave[j] - 96 )) % 26) + 96; 
				   //printf("Ho fatto la codifica di una lettere!\n"); 
				}
				else
				{
					
					ris[i] = ( ((msg[i] - 96 ) - (chiave[j] - 96 )));//+ 96;
					if(ris[i] < 1)
					{
						ris[i] = 26 + ris[i];
						
					}
					printf(" : %d,",ris[i] );
					ris[i]+= 96;
				}
				
				
			}
			else
			{
					ris[i] = ' ';
			}
			   
			if(maiuscolo)
			{
				ris[i] = toupper(ris[i]);
			}
				
			j = (j + 1) % lung_chiave;
		}	
	//printf("\n\n");
	}
	
	ris[lung_msg] = '\0';
	//stampa RISULTATO
	
}
void* servi(char* nome_client,char* input_messaggio,char* input_chiave,char codec)
{
	
	printf("Etro in servi()\n");
	char msg[31];
	char chiave[11];
    char ris[30];
	int m;
    char errore_input = '0';
    char msg_errore[300];

	//creao la fifo per mandare dati al client
	
     int fb = open(nome_client,O_WRONLY);	
	 printf("Ho aperto la FIFO per la scrittura.....\n");

	//CONTROLLO DATI IN INPUT
	int lung_chiave = strlen(input_chiave);
	int lung_msg = strlen(input_messaggio);
	char* tmperror[10];
	strcpy(msg_errore,"");
	if(lung_msg > lung_max_msg)
	{
		sprintf(tmperror,"%d",lung_max_msg);
		strcat(msg_errore,"\n\nLunghezza massima messaggio  = ");
		strcat(msg_errore,tmperror);
		errore_input = '1';
	}
	if(lung_chiave < lung_min_chiave)
	{
		sprintf(tmperror,"%d",lung_min_chiave);
		strcat(msg_errore,"\n\nLunghezza minima chiave = ");
		strcat(msg_errore,tmperror);
		errore_input = '1';		
	}
	if(lung_chiave > lung_max_chiave)
	{
		sprintf(tmperror,"%d",lung_max_chiave);
		strcat(msg_errore,"\n\nLunghezza massima chiave = ");
		strcat(msg_errore,tmperror);
		errore_input = '1';		
	}	
	strcpy(msg,input_messaggio);
	strcpy(chiave,input_chiave);

//funzione che codifica il messaggio
//char ascii ->stampabili iniziano dal numero  32 al 126
if(errore_input == '0')
{
	printf("\nSto elaborando il msg!\n\n");
	sleep(1);
	
	//INVIO TUTTI I DATI ALLA FUNZIONE CHE CODIFICA DECODIFICA
//void codificatore(char codec,char* msg,char* chiave,char* ris,int lung_msg,int lung_chiave)

	codificatore(codec,msg,chiave,ris,lung_msg,lung_chiave);
	
	printf("Risultato :  ");
	for(m = 0;m < lung_msg; m++)
	{
		printf("%c ",ris[m]);
	}
}//fine controllo errore input


//ORA INVIO IL RISULTATO AL CLIENT    
if(errore_input == '1')
{
	printf("\nERRORE:%s\n",msg_errore);
	
	write(fb,"34$",3);//indico al client che c'è stato un errore
	write(fb,msg_errore,strlen(msg_errore));
	write(fb,"$",1);
	
}	
else//invio il risultato al client
{
	
	write(fb,"27$",3);//indico al cient che il risultato è corretto e no ci sono errori
	write(fb,ris,strlen(ris));
	write(fb,"$",1);
	
	printf("\nRisultato inviato al client\n");
}


//chiusura fifo

//close(fb);
printf("\n-------------------------------------------------------------------------\n");

	sleep(1);
}
Posted

1 solution

I am stunned that code even compiles ... can I ask what compiler allows this?

Lets start with what won't even compile and shouldn't compile on most compilers and maybe compiles on your compiler but I am not sure what the hell it would compile and may be the source of your error. I have stripped it down to the three lines in sequence removing everything in between.
#define MAX_BYTES (300);
int buf = MAX_BYTES;
char buffer[buf];


Line by line analyze the code

#define MAX_BYTES (300); => This defines a constant of 300 and its wrong in most cases because of ";"
int buf = MAX_BYTES; => This defines a memory location at runtime with the above value
char buffer[buf]; => This line should NOT COMPILE ON ANY GOOD COMPILER

buf is only valid at runtime when the memory is allocated at compile time it's completely undefined there is no way for the compiler to know how big to make buffer.

The code should be
C#
#define MAX_BYTES 300
char buffer[MAX_BYTES];


*** PLEASE NOTE ***
#define lines should not have ";" at the end they are literal text substitutes for the precompiler not commands to the compiler. Running the text substitution from your above code the second line actually becomes "int buf = (300);;" because MAX_BYTES is a simple text substitute by the precompiler ... you are lucky the ";;" is not a fatal error


*** THE FIX FOR THIS PROBLEM ***
Everywhere you are using the value buf it should be replaced with sizeof(buffer)

So the line you had trouble with
numread = read(fd,&buffer,buf); // <----- THERE IS THE PROBLEM

should have been
numread = read(fd,&buffer,sizeof(buffer));
 
Share this answer
 
v12
Comments
Member 10870699 8-Jun-14 6:59am    
Thank you for the answer.Well I use gcc as a compiler.I changed the code but there is still the same error.Why?
leon de boer 8-Jun-14 9:04am    
Are you sure the file actually opened you don't check the return from the open?

fd = open("miafifo",O_RDONLY);

fd may or may not be valid you never check the return value of the file handle.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900