-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make mbed_getc and gets compatible with POSIX ( and also IAR 8.x ) #7749
Conversation
I came across this while trying to get the Stream object to work in IAR 8.x. As you can see, there was already a kludge fix for IAR 7.x that touched the _FILE descriptor. This fix won't compile in 8.x so it is simply disabled. This causes streams to fail in IAR 8.x ( specifically, putc stops working after you call getc ) I tracked this down to the root cause. Basically, you are allowed in POSIX / ANSI C to read and write on the same stream, BUT, you have to do an fseek in between. From the Linux man pages ( https://www.systutorials.com/docs/linux/man/3-fdopen/ ): "Reads and writes may be intermixed on read/write streams in any order. Note that ANSI C requires that a file positioning function intervene between output and input, unless an input operation encounters end-of-file. (If this condition is not met, then a read is allowed to return the result of writes other than the most recent.) Therefore it is good practice (and indeed sometimes necessary under Linux) to put an fseek(3) or fgetpos(3) operation between write and read operations on such a stream. This operation may be an apparent no-op (as in fseek(..., 0L, SEEK_CUR) called for its synchronizing side effect." I did the prescribed "no op" and now it works in IAR 8.x. I would think this should also work for IAR 7.x as well ( but I don't have 7.x installed to test with) And also...whatever future POSIX platforms mbed ends up on. :-)
I'm generally extremely unhappy with The But then Assuming that the |
Might need to figure this out a bit more - the standard text I'm looking at (C99) seems to contradict what you've found. Precise wording:
By that wording, I don't see how adding I don't totally recall what that IAR workaround was about, but I'm assuming it /was/ a library bug otherwise it would have just done something through proper APIs... |
@kjbracey-arm I see your text as agreeing with mine, not contradicting. “Input shall not be followed by output without intervening call to file positioning function “. That’s what my link says too. This commit adds the required file positioning function. IAR is in spec. The other library must be more tolerant. Am I missing something here? |
Your man page is paraphrasing slightly, suggesting fseek is needed between every output and input operation in either order. C99 and POSIX standard is slightly laxer than that, asymmetrically - output,fflush,input is okay, and it's only input,fseek,output that is required and we're missing. I then confused myself about which direction reversal you were inserting the fseek on - I wrongly thought it was adding it in the unnecessary direction. I agree this is putting in a required fseek that currently isn't happening. However, as the actual problem is that Full removal of the IAR 7 fudge itself is another issue. We'd need to test and confirm that changing |
@Alex-EEE @kjbracey-arm So what's the action here? It sounds like this either needs more work, more planning, or both. |
I've got the fix in my fork and it's working fine. I think we're in agreement on the need for the fseek? I think? Seems there's discussion around the proper location for said fix. |
Yes, needs work. And we can't remove the workaround for previous IAR as this does without any testing. |
You are allowed in POSIX / ANSI C to read and write on the same stream, but you have to do an fseek in between read and write call (getc->fseek->putc) Thanks @Alex-EEE for sharing the fix: ARMmbed#7749 Added test case for verification of the behavior
@Alex-EEE Is there any more planned movement on this PR? |
I believe #8331 replaces this one? |
Yep, #8331 replaces, thanks! |
Description
I came across this while trying to get the Stream object to work in IAR 8.x. As you can see, there was already a kludge fix for IAR 7.x that touched the _FILE descriptor. This fix won't compile in 8.x so it is simply disabled. This causes streams to fail in IAR 8.x ( specifically, putc stops working after you call getc )
I tracked this down to the root cause. Basically, you are allowed in POSIX / ANSI C to read and write on the same stream, BUT, you have to do an fseek in between. From the Linux man pages ( https://www.systutorials.com/docs/linux/man/3-fdopen/ ):
"Reads and writes may be intermixed on read/write streams in any order. Note that ANSI C requires that a file positioning function intervene between output and input, unless an input operation encounters end-of-file. (If this condition is not met, then a read is allowed to return the result of writes other than the most recent.) Therefore it is good practice (and indeed sometimes necessary under Linux) to put an fseek(3) or fgetpos(3) operation between write and read operations on such a stream. This operation may be an apparent no-op (as in fseek(..., 0L, SEEK_CUR) called for its synchronizing side effect."
I did the prescribed "no op" and now it works in IAR 8.x. I would think this should also work for IAR 7.x as well ( but I don't have 7.x installed to test with) And also...whatever future POSIX platforms mbed ends up on. :-)