IO Redirection and Dual Stdio - FileIO.CPP issue
Posted: Fri Aug 03, 2012 11:41 am
I have used the dualstdio example I found elsewhere (http://forum.embeddedethernet.com/viewt ... f=5&t=1397). It basically redirects the stdin, stdout, and stderr to a custom File Descriptor and allows the use of stdio over telnet and a serial port at the same time. This is a very nice set of code.
I am running into an issue with the stdioinbyte() and read() functions in the fileio.cpp file. The standard operation (referring to stdioinbyte() function) when the stdio is not redirected is to call the LocalInByte() function which leads back to reading data from the serial ports. When you redirect the IO to your own file descriptor it uses a FD (file descriptor) number >= 3. This causes the code to do this:
Now that is find and dandy... but the read() function does something for you that ends up closing your stdin redirected file descriptor by executing the above if statement which BTW is very irritating.
The dualstdio IO code provides the IO library with its own read/write functions which the dual_read() function returns the # of bytes read. So if it does not read any bytes then it returns 0.
In the fileio.cpp -> read() function there is some code that processes the IOCTL_LAST_IS_RTN flag which is set by default. That is OK. Now this code does a little trick in which it replaces your \r with a \n ... and then attempts to delete or read over the next byte iff it is a \n. It does this by making the loop go round 1 more time. So what ends up happening is that the function calls the stdioinbyte() function again but this time since it is the 2nd byte (we are reading a single character at a time using the getc() function)... we don't have a 2nd byte so dual_read() returns a 0 which causes stdioinbyte() to close input file descriptor..... ugh. You will not see this problem using MTTY or some other terminal programs because they only send a \n. I am testing with telnet and HyperTerminal (configured to send a \r\n).
So my question is... what is the proper way to handle this? I have worked around the problem by having dual_read() return a 1 and setting the buffer[0] = 0... however it still returns a 0. I run into a problem figuring out how the LocalInByte() handles it because I get to that point in the debugger to see what happens and the debugger stops working but my program still works. LocalInByte() has to return something... same as dual_read() because the return from stdioinbyte() is a character however it doesn't actually appear to do that when debugging. What am I missing?
Thanks,
Chris Favreau
I am running into an issue with the stdioinbyte() and read() functions in the fileio.cpp file. The standard operation (referring to stdioinbyte() function) when the stdio is not redirected is to call the LocalInByte() function which leads back to reading data from the serial ports. When you redirect the IO to your own file descriptor it uses a FD (file descriptor) number >= 3. This causes the code to do this:
Code: Select all
if ( read( fd_map[fd], &c, 1 ) != 1 )
{
fd_map[fd] = -1;
}
The dualstdio IO code provides the IO library with its own read/write functions which the dual_read() function returns the # of bytes read. So if it does not read any bytes then it returns 0.
In the fileio.cpp -> read() function there is some code that processes the IOCTL_LAST_IS_RTN flag which is set by default. That is OK. Now this code does a little trick in which it replaces your \r with a \n ... and then attempts to delete or read over the next byte iff it is a \n. It does this by making the loop go round 1 more time. So what ends up happening is that the function calls the stdioinbyte() function again but this time since it is the 2nd byte (we are reading a single character at a time using the getc() function)... we don't have a 2nd byte so dual_read() returns a 0 which causes stdioinbyte() to close input file descriptor..... ugh. You will not see this problem using MTTY or some other terminal programs because they only send a \n. I am testing with telnet and HyperTerminal (configured to send a \r\n).
So my question is... what is the proper way to handle this? I have worked around the problem by having dual_read() return a 1 and setting the buffer[0] = 0... however it still returns a 0. I run into a problem figuring out how the LocalInByte() handles it because I get to that point in the debugger to see what happens and the debugger stops working but my program still works. LocalInByte() has to return something... same as dual_read() because the return from stdioinbyte() is a character however it doesn't actually appear to do that when debugging. What am I missing?
Thanks,
Chris Favreau