Hallo,
ik ben momenteel bezig met het schrijven van een shell onder Linux welke binnenkort wordt getest onder Minix 3.
Ik heb veel zaken al aan de praat, zoals I/O redirection, backgrounding ("&"), etc, maar het enige wat ik niet goed aan de praat krijg is het opzetten van een pijplijn tussen n processen. Ik krijg namelijk bij het herleiden de volgende foutmelding:
*** glibc detected *** double free or corruption (!prev): 0x0804b108 ***
Hieronder staat het voorbeeld in het boek Operating Systems van Tanenbaum:
Hierboven staat een beetje code voor communicatie tussen twee processen middels een pipe, maar dit is niet wat ik wil hebben, want het moet werken voor n processen zonder de exec in de parent process, omdat de shell dan vervangen wordt door een ander proces (je bent je shell kwijt). Wat ik dus doe is het volgende. Ik maak een char pointer array die naar alle commando's wijzen die 1 voor 1 in het child gedeelte worden uitgevoerd. Ik maak sowieso gebruik van een filedescriptor array die 2 maal zo groot is als het aantal commando's, zodat tussen de processen door wel alles gebuffered blijft met het pipe commando waarna alles weer afgesloten wordt en zowel stdin als stdout gedupt wordt zodat het alles weer teruggezet wordt naar het oude situatie.
Hieronder staat mijn code:
De foutmelding treedt op zodra de close functie direct onder de fork aangeroepen wordt.
EDIT:
ik kom er net achter dat close niks veroorzaakt. De foutmelding treedt direct na de fork op. Waarschijnlijk gaat er dan iets mis in het child gedeelte.
EDIT2:
De parameterlijst wordt dubbel gealloceerd. Waarschijnlijk gaat er dan iets fout als het gefreed wordt.
ik ben momenteel bezig met het schrijven van een shell onder Linux welke binnenkort wordt getest onder Minix 3.
Ik heb veel zaken al aan de praat, zoals I/O redirection, backgrounding ("&"), etc, maar het enige wat ik niet goed aan de praat krijg is het opzetten van een pijplijn tussen n processen. Ik krijg namelijk bij het herleiden de volgende foutmelding:
*** glibc detected *** double free or corruption (!prev): 0x0804b108 ***
Hieronder staat het voorbeeld in het boek Operating Systems van Tanenbaum:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| #define STD_INPUT 0 #define SD_OUTPUT 1 pipeline(process1, process2) char *process1, *process2 int fd[2]; pipe(&fd[0]); if (fork() != 0) { close(fd[0]); close(STD_OUTPUT); dup(fd[1]); close(fd[1]); execl(process1, process1, 0); } else { close(fd[1]); close(STD_OUTPUT); dup(fd[0]); close(fd[0]); execl(process2, process2, 0); } |
Hierboven staat een beetje code voor communicatie tussen twee processen middels een pipe, maar dit is niet wat ik wil hebben, want het moet werken voor n processen zonder de exec in de parent process, omdat de shell dan vervangen wordt door een ander proces (je bent je shell kwijt). Wat ik dus doe is het volgende. Ik maak een char pointer array die naar alle commando's wijzen die 1 voor 1 in het child gedeelte worden uitgevoerd. Ik maak sowieso gebruik van een filedescriptor array die 2 maal zo groot is als het aantal commando's, zodat tussen de processen door wel alles gebuffered blijft met het pipe commando waarna alles weer afgesloten wordt en zowel stdin als stdout gedupt wordt zodat het alles weer teruggezet wordt naar het oude situatie.
Hieronder staat mijn code:
C:
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
| if (commandIndex == 0) { pipe(&fd[0]); pipe(&fd[2]); stdoutfd = dup(STDOUT); stdinfd = dup(STDIN); } else { pipe(&fd[(commandIndex + 1) * 2]); } if (fork() != 0) { close(fd[commandIndex * 2]); close(STDOUT); dup(fd[(commandIndex * 2) + 1]); close(fd[(commandIndex * 2) + 1]); if ((background == 0) && (commandIndex == (maxPipe + 1))) { waitpid(-1, &status, 0); } } else { close(fd[(commandIndex * 2) + 1]); close(STDIN); dup(fd[commandIndex * 2]); close(fd[commandIndex * 2]); if (commandIndex < (maxPipe + 1)) { close(fd[(commandIndex + 1) * 2]); close(STDOUT); dup(fd[((commandIndex + 1) * 2) + 1]); close(fd[((commandIndex + 1) * 2) + 1]); } else { close(fd[((commandIndex + 1) * 2) + 1]); dup(stdoutfd); } execve(command, parameters, NULL); } close(fd[((commandIndex + 1) * 2)]); dup(stdinfd); |
De foutmelding treedt op zodra de close functie direct onder de fork aangeroepen wordt.
EDIT:
ik kom er net achter dat close niks veroorzaakt. De foutmelding treedt direct na de fork op. Waarschijnlijk gaat er dan iets mis in het child gedeelte.
EDIT2:
De parameterlijst wordt dubbel gealloceerd. Waarschijnlijk gaat er dan iets fout als het gefreed wordt.
[ Voor 3% gewijzigd door Comp_Lex op 27-12-2007 01:01 ]