Newsgroup: it.comp.os.linux.development
Titolo: pipe con nome

Ho un problemino con le pipe con nome.
La mia domanda é:
Se creo una pipe con nome tramite mknod, e poi tramite essa faccio
comunicare due processi (uno in lettura e uno in scrittura) tramite
fgets ed fputs...
fgets ed fputs sono bloccanti? Ovvero, sono bloccanti come read e
write? Come nel caso delle pipe anonime si preoccupa il kernel di
gestire la sincronizzazione?
Mi faccio questa domanda perchè mi succede una cosa un pò strana con
il codice che riporto sotto (un client ed un server; il client legge
continuamente dei numeri dall'utente e li invia al server, il quale
stampa il quadrato dei numeri ricevuti e la somma progressiva).
Se mando in esecuzione il client in una shell ed il server in un'altra
shell, sembra tutto funzionare;
CLIENT:Inserisci un numero: 1
CLIENT:Inserisci un numero: 2
CLIENT:Inserisci un numero: 3
CLIENT:Inserisci un numero: 4
CLIENT:Inserisci un numero: 5
CLIENT:Inserisci un numero: 6
CLIENT:Inserisci un numero:
[mary@localhost pipe]$ ./fifoserver1
SERVER:Il quadrato di 1 è 1
SERVER:La somma progressiva fino a questo momento è 1
SERVER:Il quadrato di 2 è 4
SERVER:La somma progressiva fino a questo momento è 3
SERVER:Il quadrato di 3 è 9
SERVER:La somma progressiva fino a questo momento è 6
SERVER:Il quadrato di 4 è 16
SERVER:La somma progressiva fino a questo momento è 10
SERVER:Il quadrato di 5 è 25
SERVER:La somma progressiva fino a questo momento è 15
SERVER:Il quadrato di 6 è 36
SERVER:La somma progressiva fino a questo momento è 21
 se li mando in esecuzione nella stessa shell (il server in background)
ho questo errore:
[mary@localhost pipe]$ ./fifoserver1&
[1] 6364
[mary@localhost pipe]$ ./fifoclient1
CLIENT:Inserisci un numero: 1
SERVER:Il quadrato di 1 è 1
SERVER:La somma progressiva fino a questo momento è 1
Server:fgets() fallita: Invalid or incomplete multibyte or wide char
Da cosa dipende?
Proprio non lo riesco a capire :(
Invece, se sostituisco la fgets(dell'input) nel client con la scanf
commentata, se eseguo i due processi nella stessa shell, sembra
funzionare tutto bene per i primi numeri inseriti, poi il server sembra
prendere i numeri solo da 8 cifre;ovvero io inserisco un numero alla
volta, ma il server è come se li bufferizzasse.
...
CLIENT:Inserisci un numero: 567
SERVER:Il quadrato di 567 è 321489
SERVER:La somma progressiva fino a questo momento è 4641
CLIENT:Inserisci un numero: 567
SERVER:Il quadrato di 567 è 321489
SERVER:La somma progressiva fino a questo momento è 5208
CLIENT:Inserisci un numero: 567
CLIENT:Inserisci un numero: 56
CLIENT:Inserisci un numero: 6
CLIENT:Inserisci un numero: 6
CLIENT:Inserisci un numero: 6
CLIENT:Inserisci un numero: 6
CLIENT:Inserisci un numero: SERVER:Il quadrato di 567566666 è
1535715684
SERVER:La somma progressiva fino a questo momento è 567571874
Invece se li eseguo in due shell separate, fin dall'inizio il server
sembra "bufferizzare":
CLIENT:Inserisci un numero: 2
CLIENT:Inserisci un numero: 2
CLIENT:Inserisci un numero: 2
CLIENT:Inserisci un numero: 2
CLIENT:Inserisci un numero: 2
CLIENT:Inserisci un numero: 2
CLIENT:Inserisci un numero: 2
CLIENT:Inserisci un numero: 2
CLIENT:Inserisci un numero: 2
CLIENT:Inserisci un numero:
SERVER:Il quadrato di 222222222 è -1975004476
SERVER:La somma progressiva fino a questo momento è 222222222
Come mai questi strani comportamenti?
Ho provato di tutto...ma non riesco proprio a capire.
Il codice:
/* client */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#define SIZE 10
#define FIFOFILENAME1 "myfifo1"
int main(int argc, char** argv){
char buf[10];
FILE* fp;
while(1){
	if( (fp=fopen(FIFOFILENAME1,"w"))==NULL){
		perror("C:fopen() fallita");
		exit(-1);
	}
	printf("CLIENT:Inserisci un numero: ");
	//scanf("%s",buf);
	if (fgets(buf,SIZE,stdin)==NULL){
	perror("S:fgets() fallita");
	exit(-2);
	}
	if(fputs(buf,fp)==EOF){
		perror("C:fputs() fallita");
		exit(-2);
	}
	fclose(fp);
	}
exit(0);
}
/* server */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
//#include <linux/stat.h>
#define SIZE 10
#define FIFOFILENAME1 "myfifo1"
int main(int argc, char** argv){
long int somma=0;
FILE* fp;
long int num;
char buf[10];
umask(0);
mknod(FIFOFILENAME1,S_IFIFO|0777,0);
while(1){
if ( (fp=fopen(FIFOFILENAME1,"r"))==NULL){
	perror("S:fopen() fallita");
	exit(-1);
}
//fp=fopen(FIFOFILENAME1,"r");
if (fgets(buf,SIZE,fp)==NULL){
	perror("Server:fgets() fallita");
	exit(-2);
}
//fgets(buf,SIZE,fp);
num=atoi(buf);
somma += num;
printf("SERVER:Il quadrato di %li è %li\nSERVER:La somma progressiva
fino a questo momento è %li\n\n", num,num*num,somma);
fclose(fp);
}
exit(0);
}
Mary

 ha scritto nel messaggio 
news:1117395687.8...@g14g2000cwa.googlegroups.com...


Prima di provare a fare come dici tu, secondo me il problema non è
quello, perchè:
* nel client leggo da stdin con una fgets, che legge fino ad un
ritorno a capo (che c'è sicuramente perchè premo invio per immettere
l'input) e termina la stringa con in carattere di terminazione.
* poi per inviare i dati al server uso, sempre nel client, una fputs,
che scrive la stringa fino al carattere di terminazione nullo
escluso(da manuale);
* nel server leggo i dati dalla pipe con una fgets, che va a buon fine
perchè anche se la fputs nel client non ha terminato la stringa con
'\0', tanto fgets legge fino a '\n'( sempre da manuale).
 Quindi il problema a me non sembra questo, anche perchè se lancio i
due processi in due shell distinte tutto funziona.
Se invece li lancio nella stessa shell, si verificano (a seconda di
fgets o scanf come dicevo nel post precedente) diversi errori.
Ma che cambia?? :(
Comunque ho provato a fare come dicevi tu, usando un ulteriore
carattere di terminazione.
Ugualmente, se li lancio in due shell distinte tutto funziona; nella
stessa shell, invece, mi chiede solo il primo numero e poi si blocca...
Mary

 ha scritto nel messaggio 
news:1117446312.2...@g49g2000cwa.googlegroups.com...
Prima di provare a fare come dici tu, secondo me il problema non č
quello, perchč:
* nel client leggo da stdin con una fgets, che legge fino ad un
ritorno a capo (che c'č sicuramente perchč premo invio per immettere
l'input) e termina la stringa con in carattere di terminazione.
* poi per inviare i dati al server uso, sempre nel client, una fputs,
che scrive la stringa fino al carattere di terminazione nullo
escluso(da manuale);
* nel server leggo i dati dalla pipe con una fgets, che va a buon fine
perchč anche se la fputs nel client non ha terminato la stringa con
'\0', tanto fgets legge fino a '\n'( sempre da manuale).
 Quindi il problema a me non sembra questo, anche perchč se lancio i
