Unix Programming - Read string from fifo

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > May 2005 > Read string from fifo





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author Read string from fifo
torpedo@bluebottle.com

2005-05-20, 7:55 am

Hi,
I have problem reading from fifo,
I want to read the complete line(length of the string is not
predictable it can be very long) from the fifo and store it in the
string.
following is the code fragment I am using read system call



while(1){
if ((rVal = read(mFd, &ch, sizeof(char))) < 0) {
mErrorString = string(strerror_r(errno,0,0));
return false;
}

// I have to added following code just because read call is
// not getting "blocked" and returning 0 charecter read
// this is not wise idea since it is consuming lot of processor

if (rVal == 0) {
continue;
}


//----

if ( ch == '\n') {
break;
}

sBuffer += ch;
}


am I missing something here.
Please suggest some other alternative if available.

thanks in advance,

regards,
torpedo

phil_gg04@treefic.com

2005-05-20, 7:55 am

> I have problem reading from fifo,
> I want to read the complete line(length of the string is not
> predictable it can be very long) from the fifo and store it in the
> string.


I'm assuming that sBuffer is a C++ std::string.

Your code is reading characters one at a time. This is not efficient.
You'd be better off reading into a buffer, e.g. something like

char b[1024];
rVal = read(mFd,b,sizeof(b));
.....
sBuffer.append(b,rVal);

Why is read() returning 0? Have you set it to nonblocking mode
somewhere? Why?

If you can, I'd open a proper C++ stream connected to the fifo file
descriptor. Unfortunately this is not easy to do portably, but there
are GNU extensions to do it if you're on that platform. This has been
discussed recently.

Phil.

Barry Margolin

2005-05-21, 2:52 am

In article <1116590493.712060.72440@g47g2000cwa.googlegroups.com>,
phil_gg04@treefic.com wrote:

>
> I'm assuming that sBuffer is a C++ std::string.
>
> Your code is reading characters one at a time. This is not efficient.
> You'd be better off reading into a buffer, e.g. something like
>
> char b[1024];
> rVal = read(mFd,b,sizeof(b));
> ....
> sBuffer.append(b,rVal);
>
> Why is read() returning 0? Have you set it to nonblocking mode
> somewhere? Why?
>
> If you can, I'd open a proper C++ stream connected to the fifo file
> descriptor. Unfortunately this is not easy to do portably, but there
> are GNU extensions to do it if you're on that platform. This has been
> discussed recently.


Or he could use the C/Unix library functions rather than the C++
functions. C's stdio provides fgets() to read a line, and fdopen() to
create a stdio stream connected to a Unix file descriptor.

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
torpedo@bluebottle.com

2005-05-24, 2:52 am

I am very sorry got late to reply.


phil_gg04@treefic.com wrote:
>
> I'm assuming that sBuffer is a C++ std::string.


yes you are rigth it is std::string

>
> Your code is reading characters one at a time. This is not

efficient.
> You'd be better off reading into a buffer, e.g. something like
>
> char b[1024];
> rVal = read(mFd,b,sizeof(b));
> ....
> sBuffer.append(b,rVal);
>
> Why is read() returning 0? Have you set it to nonblocking mode
> somewhere? Why?



even I am not getting why it is not getting blocked I am using shell
script for
testing purpose which continuously fill the fifo from the file
script is :




function append_file
{
while read LINE
do
echo "$LINE" >> $OUTFILE
sleep 0.5
:
done < $FILENAME
}






when ever the sleep is called there is no write in the fifo, in this
time span read call returns the 0 bytes read instead of getting blocked





>
> If you can, I'd open a proper C++ stream connected to the fifo file
> descriptor. Unfortunately this is not easy to do portably, but there
> are GNU extensions to do it if you're on that platform. This has

been
> discussed recently.



Please give the example using the stream if available


thanks & regards,
torpedo





>
> Phil.


phil_gg04@treefic.com

2005-05-24, 8:38 am

>>> read call is not getting "blocked" and returning 0
> I am not getting why it is not getting blocked


You must be doing something in code that you have not posted to put the
fd into non-blocking mode.
Please post a complete program that shows this problem, then someone
might be able to help.

--Phil.

torpedo@bluebottle.com

2005-05-24, 8:38 am

This is the complete class implementation I havent given the class
declaration here, It is too big thts why initially I avoided to put
this here.

//Code starts here


Fifo :: Fifo(string rFifoName) :
mFd(0),closed(false),mFifoName(rFifoName
)
{
}

Fifo :: ~Fifo() {
if (!closed) {
close(mFd);
}
}

bool Fifo :: CreateIPC() {
if (mkfifo(mFifoName.c_str(),S_IRUSR | S_IWUSR) < 0) {
mErrorString = string(strerror_r(errno,0,0));
return false;
}
return true;
}

bool Fifo :: CloseIPC() {
if(close(mFd) < 0) {
mErrorString = string(strerror_r(errno,0,0));
return false;
}
closed = true;
return true;
}


bool Fifo :: FileExist() {
if (access(mFifoName.c_str(), F_OK) < 0) {
mErrorString = string(strerror_r(errno,0,0));
return false;
}
return true;
}


bool Fifo :: OpenIPC( ) {
if (! FileExist()) {
return false;
}
if( (mFd = open(mFifoName.c_str(), O_RDONLY)) < 0)
{
mErrorString = string(strerror_r(errno,0,0));
return false;
}
return true;
}



bool Fifo :: ReadFromIPC(string& sBuffer) {
int rVal = 0; char ch = 0;
sBuffer.erase(0,sBuffer.length());
while(1)
{
if ((rVal = read(mFd, &ch, sizeof(char))) < 0) {
mErrorString = string(strerror_r(errno,0,0));
return false;
}

if (rVal == 0) {
continue;
}

if ( ch == '\n') {
break;
}
sBuffer += ch;
}
return true;
}



string Fifo :: GetErrorMsg() {
return mErrorString;
}


// Ends here

waiting for reply,
regards,
torpedo

phil_gg04@treefic.com

2005-05-24, 8:38 am

> This is the complete class implementation
> [snip]


I can't see anything in there that would cause it to be non-blocking.
Maybe try running strace to see what is really going on.
Sorry, I have no more clues. Anyone else?

--Phil.

torpedo@bluebottle.com

2005-05-30, 7:53 am

I think I have figured out the problem.

The problem is in the script and not in the code.
- read call returns the 0 when it receives the end-of-file

in the script after writing the line to the fifo it might be doing the
close on fifo

echo "$LINE" >> $OUTFILE

and this might be the reason for receiving the eof to read call

because when I use the write function of class (instead of script) to
write to fifo using other program it works fine

is this conclusion right ?

torpedo

phil_gg04@treefic.com

2005-05-30, 5:52 pm

> read call returns the 0 when it receives the end-of-file
>
> in the script after writing the line to the fifo it might be doing the
> close on fifo


Yes, each invokation of echo will open and close the fifo. This is the
problem.

You can perhaps write something like this in the script

( while .....
do echo ...
done ) > fifo

--Phil.

Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com