[an error occurred while processing this directive] [an error occurred while processing this directive][an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] (none) [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive][an error occurred while processing this directive] [an error occurred while processing this directive][an error occurred while processing this directive] [an error occurred while processing this directive][an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive] (none) [an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive][an error occurred while processing this directive]
 
[an error occurred while processing this directive] [an error occurred while processing this directive]
Skåne Sjælland Linux User Group - http://www.sslug.dk Home   Subscribe   Mail Archive   Forum   Calendar   Search
MhonArc Date: [Date Prev] [Date Index] [Date Next]   Thread: [Date Prev] [Thread Index] [Date Next]   MhonArc
 

Re: [CPROG] Read & Strängslut



Hej

Det ser ud til at det du har brug for er at sætte non-blocking mode
dette kan du gøre ved hjælp af fcntl(.).

Følgende er en implementation af en C++ socket streambuffer funktion der returnerer
!0 hvis næste read/recv/revfrom ikke vil blokere.


  // showmanyc():
  // throws runtime_error upon fcntl error -
  // this is termed unexpected and should not be caugth
  // fails if not open or pending output sequence not fully consumed
  // according to ISO/IEC 14882::1998(E) a failure is not termed fatal
  // relies on setbuf(0, 0) truly means unbuffered
  template <int St, int Pr>
  int
  std::basic_socketbuf<PF_UNSPEC, St, Pr, char, std::char_traits<char> >
  ::showmanyc()
  {
    if (!is_open())
      return -1;
#if 0  /* assert that no reading position is available */
    assert (!gptr() || gptr() >= egptr());
#endif /* should not occur */

    if (!sync()) {   // buffer is now syncronized
      // prepare for non-blocking mode:
      int oldflags= ::fcntl(descriptor(), F_GETFL, 0); // read old flags
      if (oldflags == -1)
 throw
   runtime_error("ngr::sockbuf showmanyc fcntl read error");

      // set non-bloking mode:
      if (::fcntl(descriptor(), F_SETFL, oldflags | O_NONBLOCK) == -1)
 throw runtime_error("ngr::sockbuf showmanyc fcntl"
       " non-blocking set error");

      register int howmany;  // purge howmany into register

      if (!blen()) {   // is unbuffered
 // peek at pending input sequence:
 char_type c_peek;
 howmany= recvfrom(descriptor(), &c_peek, sizeof c_peek,
     receive_flags() | MSG_PEEK,
     receive_addr(), receive_addr_len());

 // reset blocking mode:
 if (::fcntl(descriptor(), F_SETFL, oldflags) == -1)
   throw runtime_error("ngr::sockbuf showmanyc fcntl error");
 // then return chars receivied
 return howmany ? howmany != EOF ? howmany : 0 : -1;
      }

      else {   // buffered mode
 if (gptr()) {   // transfer last backup char to shortbuf
   *shortbuf()= *(egptr() - sizeof(char_type));
   setg(shortbuf(),
        shortbuf() + sizeof(char_type),
        shortbuf() + sizeof(char_type));
 }

 // peek at incomming
 howmany= ::recvfrom(descriptor(), base(), blen(),
       receive_flags() | MSG_PEEK,
       receive_addr(), receive_addr_len());

 // reset blocking mode:
 if (::fcntl(descriptor(), F_SETFL, oldflags) == -1)
   throw runtime_error("ngr_sockbuf showmanyc fcntl error");
 // then return chars receivied:
 return howmany ? howmany != EOF ? howmany : 0 : -1;
      }
    }
    return 0; // default behaviour
  } // showmanyc



Martin Bertilsson Haagen wrote:

> Hej
>
> Jag jobbar förnärvarande med ett program som läser och skriver till
> fildesciptors. Processessen har forkat några gånger och pratar med sina
> "childs" genom pipes. Det uppstår här ett litet problem, eftersom strängen kan
> vara hur lång som hälst så allocerar jag mera minne när det behövs. Detta gör
> jag med följande rutin:
> -------------------
>         struct ReadStruct{
>                 char Data[1025];
>                 struct ReadStruct *Next;
>         }
>
>         do{
>                 Item=(struct ReafStruct *) malloc(sizeof(ReadStruct));
>                 /*
>                  * Lite kod som sköter den länkade-listan
>                  */
> (1)             temp=read(fd,Item->Data,1024);
>         } while (temp==1024);
> ---------------------
>
> Koden funkar bra. Det finns tre olika möjligheter här;
> 1. strängen > 1024 tecken
> 2. strängen < 1024 tecken
> 3. strängen = 1024 tecken
>
> De två första tillfällena funkar fint. Men om strängen blir exact 1024 tecken
> lång så fastnar vi på raden som markerats med (1).
> Jag behöver altså kontrollera om fd är tom, men jag vet inte hur man gör detta.
> Det finns ju en möjlighet till det är att man på något sätt sätter ändra fd så
> att den inte är blockerande längre men jag vet inte om detta är möjligt eller
> hur man gör det.
>
> Någon som kan hjälpa mig?
>
>
> --
> mvh
>  Martin Bertilsson Haagen
> ______________________________________________________________
>         sslug@sslug, 0707/671717
>         http://www.geocities.com/SiliconValley/Sector/5700/
> ______________________________________________________________



 
Home   Subscribe   Mail Archive   Index   Calendar   Search

 
 
Questions about the web-pages to <www_admin>. Last modified 2005-08-10, 20:08 CEST [an error occurred while processing this directive]
This page is maintained by [an error occurred while processing this directive]MHonArc [an error occurred while processing this directive] # [an error occurred while processing this directive] *