Ik ben wat aan het prutsen met inter process communication. Ik heb het volgende eenvoudige proof of concept;
Het idee is eenvoudig. Ik heb een commandline app die 2 integers inleest via de commandline en daarna de uitkomst van de optelling teruggeeft.
Om dit commandline proggel heb ik een "wrapper" geschreven die het volgende zou moeten doen/doet:
er worden 2 pipes aangemaakt (1 voor input, 1 voor output). Daarna forkt het programma zich. De parent sluit vervolgens de kanten van de 2 pipes die hij niet gebruikt (de ene wordt naar geschreven en de andere wordt gelezen) en wacht daarna op keyboard input.
De child verbindt de kanten van de pipe die door de parent gesloten zijn met stdin/stdout en sluit daarna de kanten die de parent nog open heeft staan. Daarna wordt dmv de exec() call het proces vervangen voor de commandline app.
Doordat de 2 processen verbinden zijn dmv de pipes kan de parent naar de stdin van de app schrijven en van de stdout lezen.
Mijn probleem is het volgende: de eerste input en output gaat goed en werkt het zoals verwacht. Alles wat daarna komt is messed up. Om dit tegen te gaan flush ik dmv memset de character array voordat ik deze gebruik om naar toe te lezen of te schrijven. Maar ondanks dat ontstaat er ergens dirty input/output. Heeft iemand misschien een idee waar het mis gaat? Is het misschien nodig de pipe zelf ook te flushen voordat je deze gaat lezen/schrijven?
Voorbeeld output:
Ik heb wat gegoogled naar pipe communication en inter process communication maar dat leverde geen oplossing. M'n volgende stap is een boek kopen over dit onderwerp, maar omdat de boeken van Stevens nogal duur zijn (en ik maar een klein stukje van het IPC spectrum wil gebruiken) is dit een kostbare "oplossing".
De source van dit alles:
add.c
add_wrapper.c
Het idee is eenvoudig. Ik heb een commandline app die 2 integers inleest via de commandline en daarna de uitkomst van de optelling teruggeeft.
Om dit commandline proggel heb ik een "wrapper" geschreven die het volgende zou moeten doen/doet:
er worden 2 pipes aangemaakt (1 voor input, 1 voor output). Daarna forkt het programma zich. De parent sluit vervolgens de kanten van de 2 pipes die hij niet gebruikt (de ene wordt naar geschreven en de andere wordt gelezen) en wacht daarna op keyboard input.
De child verbindt de kanten van de pipe die door de parent gesloten zijn met stdin/stdout en sluit daarna de kanten die de parent nog open heeft staan. Daarna wordt dmv de exec() call het proces vervangen voor de commandline app.
Doordat de 2 processen verbinden zijn dmv de pipes kan de parent naar de stdin van de app schrijven en van de stdout lezen.
Mijn probleem is het volgende: de eerste input en output gaat goed en werkt het zoals verwacht. Alles wat daarna komt is messed up. Om dit tegen te gaan flush ik dmv memset de character array voordat ik deze gebruik om naar toe te lezen of te schrijven. Maar ondanks dat ontstaat er ergens dirty input/output. Heeft iemand misschien een idee waar het mis gaat? Is het misschien nodig de pipe zelf ook te flushen voordat je deze gaat lezen/schrijven?
Voorbeeld output:
code:
1
2
3
4
5
6
| $ ./add_wrapper 12 34 46 12 56 Input error Input error |
Ik heb wat gegoogled naar pipe communication en inter process communication maar dat leverde geen oplossing. M'n volgende stap is een boek kopen over dit onderwerp, maar omdat de boeken van Stevens nogal duur zijn (en ik maar een klein stukje van het IPC spectrum wil gebruiken) is dit een kostbare "oplossing".
De source van dit alles:
add.c
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| #include <stdio.h>
int main() {
char buff[32];
int arg1;
int arg2;
while (fgets(buff, sizeof(buff), stdin) != NULL) {
if (sscanf(buff, "%d%d", &arg1, &arg2) == 2) {
printf("%d\n", arg1 + arg2);
} else if (arg1 == 203) {
break;
} else {
printf("Input error\n");
}
}
return 0;
} |
add_wrapper.c
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
| #include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{
pid_t pid;
int in_fd[2], out_fd[2]; /* I/O pipe filedescriptors */
char buff[32]; /* I/O character buffer */
/* Setup communication pipelines */
if (pipe(in_fd) && pipe(out_fd)) {
perror("Pipe error.\n");
exit(1);
}
/* Attempt to fork and check for errors */
if ((pid = fork()) == -1) {
perror("Fork error.\n");
exit(1);
}
if (pid) { /* We're the parent */
/* Close the unused sides of the pipes */
close(in_fd[0]);
close(out_fd[1]);
while (fgets(buff, sizeof(buff), stdin) != NULL) {
write(in_fd[1], buff, sizeof(buff)); /* Write line to external process */
memset(buff, 0, sizeof(buff)); /* Clear the buffer */
read(out_fd[0], buff, sizeof(buff)); /* Read from the external process */
printf("%s", buff); /* Echo buffer */
memset(buff, 0, sizeof(buff)); /* Clear the buffer */
}
}
else { /* We're the child */
/* Connect pipes */
dup2(in_fd[0], 0); /* Connect stdin to the in side of in_fd */
close(in_fd[1]); /* Close out side of in_fd */
dup2(out_fd[1], 1); /* Connect stdout to the out side of out_fd */
close(out_fd[0]); /* Close in side of out_fd */
/* Execute the external process */
if(execl("add", "add", NULL) < 0) {
perror("Execl error.\n");
exit(1);
}
}
return 0;
} |