/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
[unix] filedescriptors og FILE *
Fra : Anders Bo Rasmussen


Dato : 12-01-02 23:19

Hvis man vil lave en filedescriptor om til en FILE *, med
fdopen. Men hvad gør jeg hvis jeg har to filedescripters, og jeg vil
skrive til den ene og læse fra den anden når jeg henholdsvis
skriver/læser fra FILE*'eren.

--
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.

 
 
Christian Hemmingsen (12-01-2002)
Kommentar
Fra : Christian Hemmingsen


Dato : 12-01-02 23:46

fuzz01@spamfilter.dk (Anders Bo Rasmussen) writes:

> Hvis man vil lave en filedescriptor om til en FILE *, med
> fdopen. Men hvad gør jeg hvis jeg har to filedescripters, og jeg vil
> skrive til den ene og læse fra den anden når jeg henholdsvis
> skriver/læser fra FILE*'eren.

Generelt er det en dårlig ide at blande buffered og unbuffered IO
sammen.


--
Christian Hemmingsen

Anders Bo Rasmussen (13-01-2002)
Kommentar
Fra : Anders Bo Rasmussen


Dato : 13-01-02 00:34

On 12 Jan 2002 23:46:02 +0100,
Christian Hemmingsen <postmaster@hemmingsen.nospam.kampsax.k-net.dk> wrote:

>> Hvis man vil lave en filedescriptor om til en FILE *, med
>> fdopen. Men hvad gør jeg hvis jeg har to filedescripters, og jeg vil
>> skrive til den ene og læse fra den anden når jeg henholdsvis
>> skriver/læser fra FILE*'eren.
>
> Generelt er det en dårlig ide at blande buffered og unbuffered IO
> sammen.

For at lave noget buffered IO, bliver man vel nødt til at skrive til
noget der er unbuffered.

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.

--
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.

Christian Hemmingsen (13-01-2002)
Kommentar
Fra : Christian Hemmingsen


Dato : 13-01-02 04:01

fuzz01@spamfilter.dk (Anders Bo Rasmussen) writes:

> >> Hvis man vil lave en filedescriptor om til en FILE *, med
> >> fdopen. Men hvad gør jeg hvis jeg har to filedescripters, og jeg vil
> >> skrive til den ene og læse fra den anden når jeg henholdsvis
> >> skriver/læser fra FILE*'eren.
> >
> > Generelt er det en dårlig ide at blande buffered og unbuffered IO
> > sammen.
>
> For at lave noget buffered IO, bliver man vel nødt til at skrive til
> noget der er unbuffered.

Jeg misforstod dit spørgsmål.

> 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?
Hvad skal der ske når kommer fejl på den ene af dine to oprindelige
descriptors?
Hvad med stat(2)?
Osv....

--
Christian Hemmingsen

Anders Bo Rasmussen (13-01-2002)
Kommentar
Fra : Anders Bo Rasmussen


Dato : 13-01-02 13:28

On 13 Jan 2002 04:01:11 +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.

> Hvad skal der ske når kommer fejl på den ene af dine to oprindelige
> descriptors?
> Hvad med stat(2)?
> Osv....

Hmmm.

--
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.

Christian Hemmingsen (13-01-2002)
Kommentar
Fra : Christian Hemmingsen


Dato : 13-01-02 14:59

fuzz01@spamfilter.dk (Anders Bo Rasmussen) writes:

> On 13 Jan 2002 04:01:11 +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.


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
int pid, p1[2], p2[2];
char msg[] = "Hello, World\n";
char response[1024];
pipe(p1);
pipe(p2);

memset(response, '\0', 1024);

pid = fork();

if(pid > 0){
    /* parent */
    close(p1[1]);
    close(p2[0]);
    write(p2[1], msg, strlen(msg));
    close(p2[0]);

    read(p1[0], response, 1024);

    printf("%s", response);
    return EXIT_SUCCESS;

}else if(pid == 0){
    /* child */
    close(p1[0]);
    close(p2[1]);
    dup2(p1[1],1);
    dup2(p2[0],0);
   
    execlp("cat", "cat", 0);
    perror("execlp failed");
return EXIT_FAILURE;
}else{
    /* error */
    perror("fork failed");
    return EXIT_FAILURE;
}
}


--
Christian Hemmingsen

Christian Hemmingsen (13-01-2002)
Kommentar
Fra : Christian Hemmingsen


Dato : 13-01-02 15:45

Christian Hemmingsen <postmaster@hemmingsen.nospam.kampsax.k-net.dk> writes:

> if(pid > 0){
>     /* parent */
>     close(p1[1]);
>     close(p2[0]);
>     write(p2[1], msg, strlen(msg));
>     close(p2[0]);
^^^^^^^^^^^^^
Hov, her er der vist sket en fejl, der skal stå
close(p2[1]);

--
Christian Hemmingsen

Anders Bo Rasmussen (13-01-2002)
Kommentar
Fra : Anders Bo Rasmussen


Dato : 13-01-02 17:37

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.

Byrial Jensen (13-01-2002)
Kommentar
Fra : Byrial Jensen


Dato : 13-01-02 01:58

Anders Bo Rasmussen <fuzz01@spamfilter.dk> skrev:
> Hvis man vil lave en filedescriptor om til en FILE *, med
> fdopen.

Ja, hvad så?

> Men hvad gør jeg hvis jeg har to filedescripters, og jeg vil
> skrive til den ene og læse fra den anden når jeg henholdsvis
> skriver/læser fra FILE*'eren.

Jeg forstår ikke spørgsmålet. Prøv at formulere dig klarere.
Kig evt. også på dup(2) og dup2(2) som kopierer
fildeskriptorer, eller kig evt. på fileno(3) som kan fortælle
hvilken underliggende fildeskriptor en given strøm bruger.

Anders Bo Rasmussen (13-01-2002)
Kommentar
Fra : Anders Bo Rasmussen


Dato : 13-01-02 02:16

On Sun, 13 Jan 2002 00:57:44 GMT,
Byrial Jensen <bjensen@nospam.dk> wrote:

>> Men hvad gør jeg hvis jeg har to filedescripters, og jeg vil
>> skrive til den ene og læse fra den anden når jeg henholdsvis
>> skriver/læser fra FILE*'eren.
>
> Jeg forstår ikke spørgsmålet. Prøv at formulere dig klarere.
> Kig evt. også på dup(2) og dup2(2) som kopierer
> fildeskriptorer, eller kig evt. på fileno(3) som kan fortælle
> hvilken underliggende fildeskriptor en given strøm bruger.

Ok (måske skulle jeg ikke skrive midt om natten):

Jeg har to filedescriptors:

int in=foo(), out=bar();

De kan konverteres til to FILE*, med:

FILE *fIn = fdopen (in, "r");
FILE *fOut = fdopen (out, "w");

Jeg ville så gerne i stedet lave noget i retning af:

FILE *f = fdopen2(in, out, "rw");

Så skrivning og læsning foregik til in og out foregik via f.

Jeg håber det var lidt mere klart. Men det kan da godt være min ide ikke
er så kanonisk som jeg først syntes den var.

--
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.

Per Abrahamsen (14-01-2002)
Kommentar
Fra : Per Abrahamsen


Dato : 14-01-02 13:44

fuzz01@spamfilter.dk (Anders Bo Rasmussen) writes:

> Jeg ville så gerne i stedet lave noget i retning af:
>
> FILE *f = fdopen2(in, out, "rw");
>
> Så skrivning og læsning foregik til in og out foregik via f.

Det mener jeg ikke der er nogen standard Unix API der tillader, men
jeg har læst at glibc (som bl.a. Linux bruger) giver adgang til at man
definerer sine egne FILE typer. Det bør kunne bruges til at lave en
FILE der bruger to fildescriptors i stedet for en enkelt.

Kig på documentationen til glibc, specielt libio.




Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408925
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste