FIFO прочитано в c, чтобы получить ошибку сегментации
Я получаю ошибку сегментации, когда я использую read во второй раз в цикле inifite. Я не понимаю почему.
Есть код.
#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
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
//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 = 1000;
char buffer[300];
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(nome_server, O_RDWR);
printf("------Ho aperto la FIFO SERVER-------- \n");
while (1) //continuo a cercare di leggere la fifo per vedere se ci sono altri client da servire
{
printf("sto per leggere...\n");
numread = read(fd, &buffer, buf); // <----- PROBLEMA al secondo ciclo siccome esegue la servi().....
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
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);
}
1 ответ
В соответствии
numread = read(fd,&buffer,buf);
buffer
имеет место для 300 байт, но buf
просит скопировать на него 1000 байт.
Вам либо нужно увеличить емкость buffer
#define MAX_BYTES (1000)
int buf = MAX_BYTES;
char buffer[MAX_BYTES];
или уменьшить значение buf
#define MAX_BYTES (300)
int buf = MAX_BYTES;
char buffer[MAX_BYTES];