OVH Cloud OVH Cloud

explications pipe.

11 réponses
Avatar
Guillaume Desticourt
bonjour,

je suis coince sur pipe. j ai donc ecrit ce petit programme de test
qui est cense faire "echo pouet | wc", afficher exit main et
quitter. Mais a l execution, il m affiche deux fois "pouet\n", et me
rend la main. Et a l entree clavier suivante, j ai droit a ca:
guillaume@fallen:/tmp$ wc: : Input/output error
0 0 1

quelqu un voit il ou je me suis trompe?

merci d avance,

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(void)
{
int fd[2];
int pid_1;
int pid_2;
int status;

if ((pid_1 = fork()) == -1)
exit(EXIT_FAILURE);
pipe(fd);
/* fils */
if (!pid_1 )
{
close(fd[1]);
dup2(STDIN_FILENO, fd[0]);
system("wc");
exit(0);
}
close(fd[0]);
if ((pid_2 = fork() == -1))
exit(EXIT_FAILURE);
/* fils */
if (!pid_2)
{
dup2(STDOUT_FILENO, fd[1]);
system("exit main");
exit(0);
}
waitpid(pid_2, &status, 0);
waitpid(pid_1, &status, 0);
printf("pouet\n");
return 0;
}

--
Guillaume Desticourt

10 réponses

1 2
Avatar
Stephane Chazelas
2003-12-03, 20:27(+01), Guillaume Desticourt:
[...]
if ((pid_1 = fork()) == -1)
exit(EXIT_FAILURE);
pipe(fd);


Si tu fais le pipe après le fork, tu crées un pipe dans le père
et un autre dans le fils qui n'ont aucun rapport entre eux.

Si tu fais le pipe avant le fork, tu crées un seul pipe et le
fils hérite des fd du père, donc pourra écrire à un bout pour
que le père lise de l'autre bout.

--
Stéphane ["Stephane.Chazelas" arobase "free.fr"]

Avatar
Guillaume Desticourt
Stephane Chazelas writes:

2003-12-03, 20:27(+01), Guillaume Desticourt:
[...]
if ((pid_1 = fork()) == -1)
exit(EXIT_FAILURE);
pipe(fd);


Si tu fais le pipe après le fork, tu crées un pipe dans le père
et un autre dans le fils qui n'ont aucun rapport entre eux.

Si tu fais le pipe avant le fork, tu crées un seul pipe et le
fils hérite des fd du père, donc pourra écrire à un bout pour
que le père lise de l'autre bout.


heu oui. c'est une faute d inattention. par contre ca ne marche
toujours pas. ca affiche 2 2 12 au lieu de 1 1 6 et ca me rend pas la
main avant que j ai presse return.

sinon le man me dit:
int dup2(int oldfd, int newfd);
mais sur un site universitaire je lis ca:
int dup2(int newfd, int oldfd);
et sur une page je vois ca:
dup2(0, fd[0]);
et sur une autre:
dup2(fd[0], 0);
alors le bon c est lequel?

--
Guillaume Desticourt


Avatar
DINH Viêt Hoà

sinon le man me dit:
int dup2(int oldfd, int newfd);
mais sur un site universitaire je lis ca:
int dup2(int newfd, int oldfd);


The Open Group Base Specifications Issue 6
IEEE Std 1003.1, 2003 Edition
Copyright © 2001-2003 The IEEE and The Open Group, All Rights reserved.
-------------------------------------------------------------------------------

#include <unistd.h>

int dup(int fildes);
int dup2(int fildes, int fildes2);

...

The call:

fid = dup2(fildes, fildes2);

shall be equivalent to:

close(fildes2); (1)
fid = fcntl(fildes, F_DUPFD, fildes2); (2)

ce qui veut dire en clair que le fichier fildes2, s'il était ouvert est
fermé et donc, il ne référencera plus rien (1).

Dans un deuxième temps, on définit fildes2 comme référençant également
le fichier qui était déjà référencé par fildes.


<<
F_DUPFD
Return a new file descriptor which shall be the lowest numbered
available (that is, not already open) file descriptor greater than or
equal to the third argument, arg, taken as an integer of type int. The
new file descriptor shall refer to the same open file description as
the original file descriptor, and shall share any locks. The FD_CLOEXEC
flag associated with the new file descriptor shall be cleared to keep
the file open across calls to one of the exec functions.




--
DINH V. Hoa,

etPan! - newsreader, mail user agent -- http://libetpan.sf.net/etpan


Avatar
Guillaume Desticourt
DINH Viêt Hoà writes:

The Open Group Base Specifications Issue 6
IEEE Std 1003.1, 2003 Edition
Copyright © 2001-2003 The IEEE and The Open Group, All Rights reserved.
-------------------------------------------------------------------------------

#include <unistd.h>

int dup(int fildes);
int dup2(int fildes, int fildes2);

...

The call:

fid = dup2(fildes, fildes2);

shall be equivalent to:
ok donc je dois faire dup2(fd[0], STDIN_FILENO); mais alors pourquoi

mon prog ne marche pas. j ai pourtant bien ferme les fd[i] necessaires.
je vais continuer a chercher...

merci a vous pour les explications,

--
Guillaume Desticourt

Avatar
DINH Viêt Hoà
Allez, solution puisque tu ne trouves pas ... après tout, il faut bien
l'avoir vu écrit une fois dans sa vie. Pourtant Stéphane Chazelas avait
bien donné les indications.

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(void)
{
int fd[2];
int pid_1;
int pid_2;
int status;

pipe(fd); /* <=== il faut placer le pipe ici car s'il est après le
fork(), les deux processus créent chacun leur

pipe de leur côté et n'ont aucun moyen de les
relier entre eux. */
if ((pid_1 = fork()) == -1)
exit(EXIT_FAILURE);
/* fils */
if (!pid_1 )
{
close(fd[1]);
dup2(STDIN_FILENO, fd[0]); /* ici, j'aurai plus mis
dup2(fd[0], STDIN_FILENO); */

system("wc");
exit(0);
}
close(fd[0]);
if ((pid_2 = fork() == -1))
exit(EXIT_FAILURE);
/* fils */
if (!pid_2)
{
dup2(STDOUT_FILENO, fd[1]); /* et là, dup2(fd[1], STDOUT_FILENO) */
system("exit main");
exit(0);
}
waitpid(pid_2, &status, 0);
waitpid(pid_1, &status, 0);
printf("pouetn");
return 0;
}


Mouais, je n'ai pas bien vu ce que tu voulais faire sinon ...

--
DINH V. Hoa,

etPan! - newsreader, mail user agent -- http://libetpan.sf.net/etpan

Avatar
Laurent Wacrenier
Guillaume Desticourt écrit:
system("exit main");


C'est sensé faire quoi ?

Avatar
Arnaud Launay
Le Wed, 3 Dec 2003 23:05:13 +0000 (UTC), Laurent Wacrenier écrivit:
system("exit main");
C'est sensé faire quoi ?



La même chose que exit(3) je présume, mais en crade.

Arnaud.


Avatar
Guillaume Desticourt
DINH Viêt Hoà writes:

Allez, solution puisque tu ne trouves pas ... après tout, il faut bien
l'avoir vu écrit une fois dans sa vie. Pourtant Stéphane Chazelas avait
bien donné les indications.

snip le code...


Mouais, je n'ai pas bien vu ce que tu voulais faire sinon ...
forcement vu les con***ies que j ai ecrites.

en gros les erreurs etaient dues a des descripteurs de fichiers non
fermes et une mauvaise utilisation de execv.
voici un code en principe ok.
merci pour le coup de main.

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>

int main(void)
{
int fd[2];
int pid_1;
int pid_2;
int status;
char *args[3];

args[0] = NULL;
args[1] = NULL;
args[2] = NULL;

if (pipe(fd))
{
fprintf(stderr, "pipe kon");
exit(EXIT_FAILURE);
}

if ((pid_1 = fork()) < 0)
{
fprintf(stderr, "fork 1 kon");
exit(EXIT_FAILURE);
}
/* fils */
if (!pid_1 )
{
args[0] = strdup("wc");
args[1] = NULL;
args[2] = NULL;
close(fd[1]);
dup2(fd[0], STDIN_FILENO);
execvp("wc", args);
abort();
}

close(fd[0]);
if ((pid_2 = fork()) < 0)
{
fprintf(stderr, "fork 2 kon");
exit(EXIT_FAILURE);
}
/* fils */
if (!pid_2)
{
args[0] = strdup("echo");
args[1] = strdup("pouet");
args[2] = NULL;
dup2(fd[1], STDOUT_FILENO);
execvp("echo", args);
abort();
}
fprintf(stderr, "waiting for pid %dn", pid_2);
waitpid(pid_2, &status, 0);
assert(WIFEXITED(status));
close(fd[1]);
fprintf(stderr, "waiting for pid %dn", pid_1);
waitpid(pid_1, &status, 0);
assert(WIFEXITED(status));

fprintf(stderr, "exit mainn");
return 0;
}

--
Guillaume Desticourt

Avatar
Guillaume Desticourt
Arnaud Launay writes:

Le Wed, 3 Dec 2003 23:05:13 +0000 (UTC), Laurent Wacrenier écrivit:
system("exit main");
C'est sensé faire quoi ?



La même chose que exit(3) je présume, mais en crade.
non. c est cense prouver qu il etait l heure d aller se coucher.

le code poste en dessous devrait vous eclairer si besoin est.

--
Guillaume Desticourt



Avatar
Arnaud Launay
Le Thu, 04 Dec 2003 10:18:46 +0100, Guillaume Desticourt écrivit:
La même chose que exit(3) je présume, mais en crade.
non. c est cense prouver qu il etait l heure d aller se coucher.

le code poste en dessous devrait vous eclairer si besoin est.


Ah oui, il était temps que tu dormes, effectivement :)

Arnaud.


1 2