|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
[C] Comunicazione tra padre e figlio
Ciao.
Devo scrivere un programma che legge dal proprio standard input quello che il figlio ha scritto sullo standard output. Il codice che ho scritto io è il seguente: Codice:
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int main(){
pid_t pid;
int len;
ssize_t nread;
ssize_t nwrite;
int status;
if( (pid = fork()) < 0)
perror("fork failed");
else if( pid == 0){
char *stringa="Sono il figlio e ho scritto qualcosa";
len=strlen(stringa);
if( (nwrite = write(STDOUT_FILENO,stringa,len)) != len){
if(stringa != NULL){
free(stringa);
stringa=NULL;
}
perror("write error");
}
if(stringa != NULL){
free(stringa);
stringa=NULL;
}
exit(0);
}
else{
if ( wait(&status) != pid )
perror("waitpid error");
char *buf=(char *)malloc(sizeof(char)*100);
if( (nread = read(STDIN_FILENO,buf,100)) <= 0)
perror("read failed");
printf("Adesso dovrei scrivere quello che ha scritto il figlio: ");
printf("%s", buf);
if(buf != NULL){
free(buf);
buf=NULL;
}
}
printf("Ho finito!!!\n");
exit(0);
}
Grazie |
|
|
|
|
|
#2 | |
|
Senior Member
Iscritto dal: Oct 2006
Messaggi: 1105
|
Quote:
ora, se questo non fosse possbile (non ricordo) dovresti usare una pipe Ultima modifica di mad_hhatter : 08-12-2006 alle 19:15. |
|
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
Ho provato a leggere STDOUT ma il risultato è lo stesso. A questo punto del programma non sono ancora arrivato alle pipe, quindi se un esercizio del genere mi viene messo ora che ancora non ho fatto le pipe, sicuramente c'è un metodo per risolverlo senza l'uso delle pipe.
|
|
|
|
|
|
#4 | |
|
Senior Member
Iscritto dal: Oct 2006
Messaggi: 1105
|
Quote:
quando fai un fork, il figlio eredita lo stdin e stdout dal padre... forse vanno risettati opportunamente, in modo da risultare scambiati |
|
|
|
|
|
|
#5 | |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
Ma scusa me l'hai detto tu che la read del padre dovrebbe leggere da STDOUT
Quote:
|
|
|
|
|
|
|
#6 | |
|
Senior Member
Iscritto dal: Oct 2006
Messaggi: 1105
|
Quote:
tu hai detto che leggendo stdout sicomporta allo stesso modo che leggendo stdin... questo non capivo, ora deduco (come è ovvio) che leggendo stdout NON si comporta ESATTAMENTE come quando legge stdin ma appunto, se gli fai leggere lo stdin non beccherà mai l'output del figlio... se invece nel figlio riesci a invertire i file stdin e stdout sei a posto |
|
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
In che senso invertirli?
|
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Oct 2006
Messaggi: 1105
|
nel senso che per il processo figlio lo stdout dovrebbe essere rimappato sullo stdin del padre.
quando fai il fork il figlio eredita dal padre lo stdin e lo stdout... se ci fosse un modo per dire al figlio che quello che lui chiama stdout in realtà è lo stdout saremmo aposto... ma leggendo due righe in rete mi par di capire che solo il sistema operativo può scambiare gli IOstream... non so, magari sipuò fare, ma non so come |
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
Nessuno?
|
|
|
|
|
|
#10 |
|
Member
Iscritto dal: Apr 2004
Messaggi: 130
|
Codice:
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int fd[2];
pid_t pid;
if (pipe(fd) < 0) {
perror("pipe");
exit(EXIT_FAILURE);
}
pid = fork();
if (pid < 0) {
perror("fork()");
exit(EXIT_FAILURE);
}
if (pid == 0) {
char *stringa = "Sono il figlio e ho scritto qualcosa";
int len = strlen(stringa);
close(fd[0]); //non leggo
dup2(fd[1], STDOUT_FILENO);
close(fd[1]);
if (write(STDOUT_FILENO, stringa, len) < 0) {
perror("write()");
}
_exit(0);
} else {
int status;
char *buf = malloc(100);
if (! buf) {
perror("malloc()");
exit(EXIT_FAILURE);
}
close(fd[1]); //non scrivo
dup2(fd[0], STDIN_FILENO);
close(fd[0]);
if (read(STDIN_FILENO, buf, 100) < 0)
perror("read()");
printf("Messaggio dal figlio: \'%s\'\n", buf);
free(buf);
if (wait(&status) != pid)
perror("waitpid()");
}
puts("Ho finito!!!");
return 0;
}
|
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Oct 2006
Messaggi: 1105
|
scusa, non conosco benissimo il c... hai usato una pipe? se sì, Manugal diceva che non può usarle perchè, credo, al corso che frequenta non gliele hanno introdotte... altre soluzioni?
|
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
Devo ancora provarlo per vedere se funziona, però ho trovato una soluzione. Praticamente usando la dup2() faccio una copia STDOUT_FILENO su un nuovo file descriptor in modo da riuscire a leggere con il padre quello che ha scritto il figlio. Ecco il codice:
Codice:
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
int main(){
pid_t pid;
int len;
ssize_t nread;
ssize_t nwrite;
int status;
int fd;
if ( (fd = open("temp", O_WRONLY | O_CREAT | O_TRUNC)) == -1)
perror("open failed");
if( (pid = fork()) < 0)
perror("fork failed");
else if( pid == 0){
char *stringa="Sono il figlio e ho scritto qualcosa";
len=strlen(stringa);
if( (nwrite = write(STDOUT_FILENO,stringa,len)) != len){
if(stringa != NULL){
free(stringa);
stringa=NULL;
}
dup2(fd,STDOUT_FILENO);
close(fd);
perror("write error");
}
if(stringa != NULL){
free(stringa);
stringa=NULL;
}
lseek(fd,0,SEEK_SET);
exit(0);
}
else{
if ( wait(&status) != pid )
perror("waitpid error");
char *buf=(char *)malloc(sizeof(char)*100);
if( (nread = read(fd,buf,100)) <= 0)
perror("read failed");
printf("Adesso dovrei scrivere quello che ha scritto il figlio: ");
printf("%s", buf);
if(buf != NULL){
free(buf);
buf=NULL;
}
close(fd);
}
printf("Ho finito!!!\n");
exit(0);
}
|
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
Ah neanche l'avevo letta la soluzione sopra
In pratica non so se funziona senza pipe. |
|
|
|
|
|
#14 | |
|
Senior Member
Iscritto dal: Oct 2006
Messaggi: 1105
|
Quote:
|
|
|
|
|
|
|
#15 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
Si in un certo senso si è comunicazione tra processi. Però l'uso delle pipe ancora non l'ho introdotto. Ora lo proverò e vedrò se funziona.
|
|
|
|
|
|
#16 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
Niente da fare anche con quel codice scritto da me poco fa, il programma ha lo stesso comportamento cioè attende che io gli scriva qualcosa (invece di leggere quello che ha scritto il figlio).
|
|
|
|
|
|
#17 | |
|
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
Un pipe è la soluzione corretta. Anche usando dup2 correttamente non puoi avere l'effetto desiderato, per come sono fatti stdin/out. L'utilizzo di un file temporaneo potrebbe funzionare, ammesso che prima correggi tutti i bug che hai introdotto
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|
|
|
|
|
|
#18 |
|
Senior Member
Iscritto dal: Oct 2006
Messaggi: 1105
|
ecco, speravo proprio in un intervento di ilsensine... mi stavo giusto chiedendo come funzionano stdin/out in linux... hai voglia di illuminarmi perfavore?
grazie mille! |
|
|
|
|
|
#19 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
ls -l /proc/self/fd
Sono in genere connessi a uno (pseudo)terminale. Quello che ci scrivi, viene letto da chi gestisce il terminale (kernel o programma - tipo console per X - che sia).
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|
|
|
|
|
#20 | |
|
Senior Member
Iscritto dal: Oct 2006
Messaggi: 1105
|
Quote:
grazie mille per le info! |
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 20:19.



















