Newsgroup: it.comp.lang.c
Titolo: [Help!] Uso dei pipe

Ciao a tutti... Sto preparando un progettino per un esame, e mi trovo a
dover gestire un paio di pipe. Ora, il problema e' che le dispense
forniscon un aiuto mooooolto marginale, e siccome devo far comunicare un
server ed un client via pipe (risiedono sulla stessa macchina), ho
riscontrato qualche piccolo problema. Detto che il mkfifo dovrebbe
funzionare (il make di prova non da errori alla corrispondente riga di
codice), ho dei seri problemi sulla gestione delle pipe: ovvero come apro
e chiudo una pipe? come ci scrivo? Soprattutto, mi potete indicare un sito
o una pergamena del mar morto dove si spiega chiaramente l'uso delle pipe?
Grazie a tutti :)
-- 
---
Blackstorm
*Con due angeli ed un'amica al seguito*
Datemene uno con un browser testuale, un eroe fuori dal cinema alle tre di
notte. Datemelo che ti accompagni sempre a casa, anche se piove, anche se
fa
freddo, anche se un passo più in là finisce il mondo. Datemelo che scriva
lettere belle non a me, e se poi le leggo va be', mica è colpa
mia.{Angelus}
[ICQ #116647346]
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 dove si spiega chiaramente l'uso delle pipe? Grazie a tutti :)
info libc 'Pipes and FIFOS'
 Ciao
 Federico

 Grazie a tutti :)
Allora se ricordo bene la pipe la si fa in questo modo:
#include <unistd.h>
int pipe(int fd[2]);
return: 0 se OK, -1 se errore.
Ora, in fd[1] avrai il f.d. aperto in scrittura e in fd[0] avrai il f.d. 
aperto il lettura, giusto?
Per connettere due processi ci vuole una bella fork().
Ora devi decidere a quale processo (se il padre o il figlio) dare l'fd 
aperto il scrittura o aperto in lettura.
Ad esempio, diamo ad processo padre il pid aperto il scrittura, quindi 
dalla parte del padre chiudiamo fd[0], e simmetricamente chiudiamo fd[1] 
dalla parte del figlio per lasciare aperto solo il canale in lettura.
#include <unistd.h>
#include <sys/types.h>
int main(){
	int n, fd[2];
	pid_t pid;
	char line[2048], buf[2048];
	if( pipe(fd) ) < 0 perror("Errore nella pipe!\n");
	if( (pid = fork()) < 0 ) perror("fork error!\n");
	else if(pid > 0){
		close(fd[0]); //pipe chiusa in lettura da parte del processo padre!
		write(fd[1], "Ciao sono il padre!", 19);
	} else {
		close(fd[1]); //pipe chiusa in scrittura da parte del processo figlio!
		n = read(fd[0], line, 2048);
		snprintf(buf, 2048, "PID %5d - Ho ricevuto dal padre: %s", getpid(), 
line);
		printf("%s\n", buf);
	}
	sleep(1);
}
Se ho scritto tutto bene dovrebbe andare.

EHEHE mi sono reso conto di aver cannato argomento :)
Allora tu parlavi di MKFIFO :)
vabbč cerco di riparare :)
ok vediamo un pň...
Un pň di teoria: quella che ti ho fatto vedere prima ( la pipe ) 
prevedeva l'utilizzo della fork per la comunicazione tra 2 processi...e 
guistamente tu hai chiesto mkfifo che prevede la comunicazione tra 2 o 
piů processi qualsiasi. Ora vediamo come si fa.
Si crea una FIFO con FILE* mkfifo(const char *pathname, mode_t mode);
e poi si utilizza la fifo come un file normale (read, write, ecc...).
Cosa importante č che client e server devono mettersi daccordo sul file 
(comune) da utilizzare per la comunicazione.
Quindi, ad esempio, possiamo usare informazioni comuni, come il pid che 
il client invia a server.
Esempio:
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
(LATO SERVER)
const char *infifo = "FIFO_IN"; //FIFO comune sia al server che al client
char outfifo[128];
struct mymsg{
	pid_t pid;
	char msg[100];
}
int main(){
	struct mymsg msg;
	int fin, fout;
	char risposta = "BANG!";
	mkfifo(infifo, S_IRUSR | S_IWUSR); //creiamo la FIFO
 
	while(1){
		fin = open(infifo, O_RDONLY); //apriamo la FIFO creata in precedenza
		read(fin, &msg, sizeof(msg)); //leggiamo il messaggio del client
		sprintf(outfifo, "FIFO_%d", msg.pid); //veniamo a conoscenza della 
FIFO di output grazie al pid inviato da client
		mkfifo(outfifo, S_IRUSR | S_IWUSR); //creiamo la FIFO
		fout = open(fout, O_WRONLY); //apriamo la FIFO in scrittura
		write(fout, &risposta, sizeof(risposta)); //scriamo il messaggio di output
		sleep(3); //rimaniamo in attesa di 3 sec. prima di chiudere la FIFO
		kill(msg.pid, SIGKILL);
		unlink(outfifo);
		close(fout);
	}
}
(LATO CLIENT) (descrizione simmetrica del server)
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
const char *outfifo = "FIFO_IN";
char infifo[128];
struct mymsg{
	pid_t pid;
	char msg[100];
}
int main(){
	struct mymsg msg;
	int fin, fout;
	char risposta[100];
	if((fout = open(outfifo, O_WRONLY)) < 0) {
		perror("Errore di apertura outfifo!");
		exit(1);
	}
	msg.pid = getpid();
	printf("Inserisci il messaggio:\n");
	scanf("%s", &msg.msg);
	write(fout, &msg, sizeof(msg));
	close(fout);
 
	sprintf(infifo, "FIFO_%d", msg.pid);
	while(1){
		if((fin = open(infifo, O_RDONLY)) < 0) {
			sleep(1)
		}
		else break;
	}
	read(fin, &risposta, sizeof(risposta));
	printf("La risposta del server č: %s\n", risposta);
	pause();
}

 	sprintf(infifo, "FIFO_%d", msg.pid);
Queste due righe mi piacciono... ma non funzionano... :(
Mi spiego: teoricamente, io, ottenuto il pid del processo con getpid,
avendo un array caratteri nel quale memorizzo il neme della pipe, se
scrivo, appunto, sprintf(infifo, "FIFO_%d", msg.pid), lui mi dovrebbe
creare un file di nome "FIFO_xyz", con xyz numero a piacere, giusto?
Invece a me capita che mi crea si un file di nome "FIFO_" il problema e'
che non mi ci mette il pid...


 che non mi ci mette il pid...
Allora sprintf dovrebbe mettere in infifo la stringa "FIFO_" concatenato 
con l'id del processo. Se non ti aggiunge il pid, allora vuol dire che 
c'è un errore in getpid. Ma cmq non ti preoccupare troppo, perchè puoi 
utilizzare una qualsiasi stringa a tuo piacimento, purchè sia uguale sia 
nel client che ne server. Utilizzare il pid era solo un esempio, 
potresti pure utilizzare una stringa passata in input da tastiera sia al 
client che al server.

 client che al server.
Si, ma casualmente a me serviva esattamente quello... cmq ho risolto... un
paio di sprintf messe al posto giusto e via... Ora ho un altro prob, se
potete darmi una mano anche su qst... Adesso non riesco ad aprire in
nessun modo il pipe del server. Ovvero, ho un file "clientserver" che e'
la pipe che il server crea e sulla quale devo scrivere... solo che se gli
faccio una 
while(((fd_server=open("clientserver", O_WRONLY))==-1);
che mi serve per aprire appunto la pipe, il makefile si pianta di brutto e
continua a tentare di aprire il pipe. Ora il prob e' che il server per
testare il file e' fatto dalla prof, e funziona, ergo il file clientserver
ha permessi di lettura e scrittura, pero continua anon aprirmelo...
Qualche soluzione? Il pipe clientserver e' creato dal server, il client e'
codice scritto da me...
Il prob e' che non riesco ad individuare l'errore, dato che sembra non
volerlo aprire... 


 volerlo aprire...
Ciao,
 perche' insisti a voler aprire un file se ha gia' fallito una volta? Se
per caso vuoi controllare se il file esiste, almeno mettici una sleep ...  
e controlla errno!
Anche adesso errno ti sarebbe molto utile; se non conosci il problema, e'
difficile trovare la soluzione ;-)
 Ciao
 Federico

 e controlla errno!
Allora, per due motivi: primo non posso usare la sleep, perche' non e' fra
le istruzioni consentite per il progetto, secondo, ho bisogno che il file
venga aperto, per forza....
Giusto per curiosita', come la uso errno? attualmente nel codice ci sono
un paio di perror(), senza contare che usando la errno con lo switch, che
ne so io gli errori che mi da? 


 usando la errno con lo switch, che ne so io gli errori che mi da?
Non capisco cosa vuoi dire ... uno switch sulla errno e' spesso la cosa 
migliore che puoi fare per gestire gli errori.
 Ciao
 Federico

riscontrato qualche piccolo problema. (...)
Studi a Verona o è il tema della settimana, dare progettini con le
named pipes? :-)
MarKco (ICQ #228664405 - MSN 
ilsecondo...@hotmail.it
)
 
http://sole-luna.splinder.com
Triste e' l'uomo
che ama le cose
solo quando si allontanano.
(Baolian, libro dei pensieri Baol, I, vv. 1240-1242)