On 13 Jan 2002 14:59:12 +0100,
Christian Hemmingsen <postmaster@hemmingsen.nospam.kampsax.k-net.dk> wrote:
>> >> Men hvis du i stedet kan fortælle mig hvordan man slår to
>> >> filedescripters sammen til en, hvor hvis man skriver til den så skriver
>> >> man til den ene, mens hvis man læser fra den, så læser man fra den
>> >> anden, ville det da også være godt.
>> >
>> > Der er ikke nogen system kald til det svjv.
>> > Jeg kan iøvrigt ikke se at der er noget som helst at vinde ved
>> > det. Desuden er det vist kun til mere besvær og forvirring.
>> > Hvad skal der ske når du laver en lseek(2) på din nye "sammenlagte"
>> > file descriptor?
>>
>> Da det skal bruges til at skrive og læse fra en process som kører i
>> baggrunden, giver det ikke meningen at bruge lseek.
>
> Kig på pipe(2), fork(2), dup2(2) og execve(2) med venner
>
> Følgende program eksekverer standard unix kommandoen cat(1) uden
> argumenter. Uden argumenter læser cat først til eof fra stdin og
> skriver det bagefter til stdout. Programmet skriver først "Hello,
> World\n" til cat og læser det tilbage og skriver det ud.
Minder meget om det jeg selv har bikset sammen (med god hjælp fra et
eksempel i Advanced Programming in the UNIX Environment. Det eneste jeg
mangler/manglede var blot at slå de to streams sammen til en. Men det lader
åbentbart ikke til at være en normal løsning, og så vil jeg undlade det.
Koden, hvis nogen der søger på google eller andre skulle være interesseret:
#define ERROR -1
int popenrw(char *command, char **args, FILE *&in, FILE *&out)
{
int fToCommand[2], fFromCommand[2];
int error;
if (error=pipe(fToCommand)) return error;
if (error=pipe(fFromCommand))
{
close(fToCommand[0]);
close(fToCommand[1]);
return ERROR;
}
pid_t pid=fork();
if (pid<0) //fork error
return ERROR;
if (pid > 0)
{
//we are the parent
char line[1024];
close(fToCommand[0]);
close(fFromCommand[1]);
if(!(in = fdopen(fFromCommand[0],"r"))) return ERROR;
if(!(out = fdopen(fToCommand[1],"w"))) return ERROR;
return 0;
}
else
{
//we are the child
close(fToCommand[1]);
close(fFromCommand[0]);
if (fToCommand[0]!=STDIN_FILENO)
{
if (dup2(fToCommand[0], STDIN_FILENO)==-1)
exit(1); //duplication was unsuccessful
close(fToCommand[0]);
}
if (fFromCommand[1]!=STDOUT_FILENO)
{
if (dup2(fFromCommand[1], STDOUT_FILENO)==-1)
exit(1); //duplication was unsuccessful
close(fFromCommand[1]);
}
if (execvp(command, args) < 0) exit(1);
exit(0);
}
}
--
Like a rat in a maze Anders Bo Rasmussen mailto:fuzz01@spamfilter.dk
The path before me lies Frimestervej 42 1.tv
http://www.fuzz.dk
And the pattern never alters 2400 Kbh. NV
Until the rat dies.