View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0000087 | 1003.1(2008)/Issue 7 | System Interfaces | public | 2009-06-29 17:30 | 2013-04-16 13:06 |
Reporter | geoffclare | Assigned To | ajosey | ||
Priority | normal | Severity | Objection | Type | Error |
Status | Closed | Resolution | Accepted As Marked | ||
Name | Geoff Clare | ||||
Organization | |||||
User Reference | |||||
Section | fflush | ||||
Page Number | 844 | ||||
Line Number | 28024 | ||||
Interp Status | Approved | ||||
Final Accepted Text | 0000087:0000181 | ||||
Summary | 0000087: fflush and ungetc | ||||
Description | _____________________________________________________________________________ OBJECTION Enhancement Request Number 17 gwc:xxxxxxxxxxxxx Defect in XSH fflush (rdvk# 2) [gwc fflush and ungetc] Fri, 12 Dec 2008 10:23:07 +0000 _____________________________________________________________________________ The descriptions of fflush() and fclose() state: If the file is not already at EOF, and the file is one capable of seeking, the file offset of the underlying open file description shall be adjusted so that the next operation on the open file description deals with the byte after the last one read from or written to the stream being [flushed/closed]. I believe the intention of the statement is that implementations should do the equivalent of lseek(fileno(fp), ftello(fp), SEEK_SET). The point is to prevent data loss when changing the active handle for an open file description to a handle in a different process. Thus if app1 uses stdio to read from stdin, { app1; app2; } < file works as expected without app1 having to do anything special. It just reads from stdin and then closes it (explicitly or implicitly). However, the wording used does not match this intent when ungetc() is involved. Suppose app1 is the type of application that performs read-ahead when it parses its input, and the last thing it did is to call ungetc() before closing standard input. In this case the lseek() above is still the right thing for the implementation to do, so that app2 will read the first byte that was "unwanted" by app1. However, that's not what the statement in the standard requires. The last byte read by app1 was the byte that it passed to ungetc(). The ungetc() doesn't change history; it changes what is returned by the next read on the stream (if any). To match the intent, the wording should be changed so that it simply says the file offset of the underlying open file description is set to the file position of the stream. Another issue is what happens after an ungetc() and fflush() if the active file handle does not change, i.e. there is a subsequent read from the same stream. Should fflush() discard the pushed-back byte or not? Given that the file offset of the underlying open file description has (for the reasons above) been set to the file position of the stream, I think fflush() does have to discard the pushed-back byte. Otherwise that byte will be read twice after the fflush(). | ||||
Desired Action | Change: the file offset of the underlying open file description shall be adjusted so that the next operation on the open file description deals with the byte after the last one read from or written to the stream being flushed. to: the file offset of the underlying open file description shall be set to the file position of the stream, and any characters pushed back onto the stream by ungetc() or ungetwc() that have not subsequently been read from the stream shall be discarded. At page 805 line 26801 section fclose, change: the file offset of the underlying open file description shall be adjusted so that the next operation on the open file description deals with the byte after the last one read from or written to the stream being closed. to: the file offset of the underlying open file description shall be set to the file position of the stream. | ||||
Tags | tc1-2008 |
related to | 0000480 | Closed | ajosey | 1003.1(2008)/Issue 7 | freopen, fclose effect on multiple file handles |
related to | 0000452 | Closed | ajosey | 2008-TC1 | fflush changes need counterpart unget[w]c changes |
related to | 0000093 | Closed | ajosey | 1003.1(2008)/Issue 7 | ungetc fseeko |
related to | 0000482 | Closed | ajosey | 2008-TC1 | fclose change needs updating to match bug 87 change |
related to | 0000816 | Closed | 1003.1(2013)/Issue7+TC1 | does fflush(NULL) affect seekable read streams? | |
related to | 0000701 | Closed | 1003.1(2013)/Issue7+TC1 | unget[w]c() and file position after discarding push back |
|
Interpretation response ------------------------ The standard is unclear on this issue, and no conformance distinction can be made between alternative implementations based on this. This is being referred to the sponsor. Rationale: ------------- None. Notes to the Editor (not part of this interpretation): ------------------------------------------------------- Make the change suggested in 0000087:0000838 |
|
This change is incomplete - it introduces a conflict with existing wording in unget[w]c, which requires the file position to be reset to the position that was in effect before the pushed-back bytes when pushed-back bytes are discarded. That is, if the file underlying stream f contains the bytes "hello world" and is currently at position 5 (the space), then the sequence fgetc(f); ungetc('@', f); fflush(f); fgetc(f) should return space per this bug's fflush() wording, but 'w' per the existing ungetc() wording, based on whether fflush set the underlying file position back to position 5 (as if the first fgetc and ungetc had never happened), vs. position 6 (the position before any characters were pushed back). The simplest solution is to delete the phrase "or discarding" from line 67928 (ungetc) and 67972 (ungetwc), which I believe matches the intent. After all, in the case of '{ app1; app2; } < seekable', if app1 does an ungetc, then app2 should start at the point of the byte ignored by app1, rather than skipping over that byte. More specifically: On Page: 2151 Line: 67927 Section: ungetc() In the DESCRIPTION section, change from: The value of the file-position indicator for the stream after reading or discarding all pushed-back bytes shall be the same as it was before the bytes were pushed back. to: The value of the file-position indicator for the stream after reading all pushed-back bytes shall be the same as it was before the bytes were pushed back. Rationale: Pushed-back bytes discarded by fflush() are re-read from a seekable underlying file, rather than skipped. On Page: 2152 Line: 67971 Section: ungetwc() In the DESCRIPTION section, change from: The value of the file-position indicator for the stream after reading or discarding all pushed-back characters shall be the same as it was before the characters were pushed back. to: The value of the file-position indicator for the stream after reading all pushed-back characters shall be the same as it was before the characters were pushed back. Rationale: Pushed-back characters discarded by fflush() are re-read from a seekable underlying file, rather than skipped. |
|
New proposed changes which take into account 0000087:0000789 above, 0000087:0000895 below, 0000452:0000790 from 0000452 and email on the mailing list... Change: the file offset of the underlying open file description shall be adjusted so that the next operation on the open file description deals with the byte after the last one read from or written to the stream being flushed. to: the file offset of the underlying open file description shall be set to the file position of the stream, and any characters pushed back onto the stream by ungetc() or ungetwc() that have not subsequently been read from the stream shall be discarded (without further changing the file offset). At page 805 line 26801 section fclose, change: the file offset of the underlying open file description shall be adjusted so that the next operation on the open file description deals with the byte after the last one read from or written to the stream being closed. to: the file offset of the underlying open file description shall be set to the file position of the stream if the stream is the active handle to the underlying file description. On Page: 2151 Line: 67927 Section: ungetc() In the DESCRIPTION section, change from: The value of the file-position indicator for the stream after reading or discarding all pushed-back bytes shall be the same as it was before the bytes were pushed back. to: The value of the file-position indicator for the stream after all pushed-back bytes have been read, or discarded by calling fseek(), [CX]fseeko(),[/CX] fsetpos(), or rewind() [CX](but not fflush())[/CX], shall be the same as it was before the bytes were pushed back. On Page: 2152 Line: 67971 Section: ungetwc() In the DESCRIPTION section, change from: The value of the file-position indicator for the stream after reading or discarding all pushed-back characters shall be the same as it was before the characters were pushed back. to: The value of the file-position indicator for the stream after all pushed-back characters have been read, or discarded by calling fseek(), [CX]fseeko(),[/CX] fsetpos(), or rewind() [CX](but not fflush())[/CX], shall be the same as it was before the characters were pushed back. On Page: 2151 Line: 67920 Section: ungetc() In the DESCRIPTION section, change from: A successful intervening call (with the stream pointed to by stream) to a file-positioning function (fseek(), fsetpos(), or rewind()) shall discard any pushed-back bytes for the stream. to: A successful intervening call (with the stream pointed to by stream) to a file-positioning function (fseek(), [CX]fseeko(),[/CX] fsetpos(), or rewind()) [CX]or fflush()[/CX] shall discard any pushed-back bytes for the stream. On Page: 2152 Line: 67962 Section: ungetwc() In the DESCRIPTION section, change from: A successful intervening call (with the stream pointed to by stream) to a file-positioning function (fseek(), fsetpos(), or rewind()) discards any pushed-back characters for the stream. to: A successful intervening call (with the stream pointed to by stream) to a file-positioning function (fseek(), [CX]fseeko(),[/CX] fsetpos(), or rewind()) [CX]or fflush()[/CX] shall discard any pushed-back characters for the stream. [Note to the editor: these last two changes include the changes from Mantis bug 93.] [An editorial correction was made to the last ungetwc() change above, substituting "bytes" with "characters", on 2012-01-31.] |
|
For fclose, there are interactions to worry about when multiple handles exist to the same file description. If some other handle has become active and changes the file offset, then fclose must not undo that change to the file offset merely because fclose was used on an inactive handle. An example of this is the following code sequence: const char buf[] = "hello world"; int fd; int fd2; FILE *f; /* Prepare a seekable file. */ fd = open (NAME, O_RDWR | O_CREAT | O_TRUNC, 0600); assert (0 <= fd); assert (write (fd, buf, sizeof buf) == sizeof buf); assert (lseek (fd, 1, SEEK_SET) == 1); /* Create a second handle visiting the file */ fd2 = dup (fd); assert (0 <= fd2); f = fdopen (fd2, "w"); // stream offset of f must be at 1 assert (f); assert(lseek(fd, 4, SEEK_SET) == 4); // fd is now the active handle assert (fclose (f) == 0); // The f/fd2 handle was never repositioned or made active assert (lseek (fd, 0, SEEK_CUR) == 4); // so fd should still be at 4 To make this clear, the wording for fclose() at line 26801 in 0000087:0000838 should be: the file offset of the underlying open file description shall be set to the file position of the stream if the stream is the active handle to the underlying file description. |
|
Interpretation proposed 11 August 2011 for final 30 day review |
|
Interpretation approved 12 Sept 2011 |
Date Modified | Username | Field | Change |
---|---|---|---|
2009-06-29 17:30 | msbrown | New Issue | |
2009-06-29 17:30 | msbrown | Status | New => Under Review |
2009-06-29 17:30 | msbrown | Assigned To | => ajosey |
2009-06-29 17:30 | msbrown | Name | => Mark Brown |
2009-06-29 17:30 | msbrown | Organization | => IBM |
2009-06-29 17:30 | msbrown | Section | => fflush |
2009-06-29 17:30 | msbrown | Page Number | => 844 |
2009-06-29 17:30 | msbrown | Line Number | => 28024 |
2009-06-29 17:30 | msbrown | Status | Under Review => Resolved |
2009-06-29 17:30 | msbrown | Resolution | Open => Accepted |
2009-07-01 17:05 | msbrown | Name | Mark Brown => Geoff Clare |
2009-07-01 17:05 | msbrown | Organization | IBM => |
2009-07-01 17:05 | msbrown | Reporter | msbrown => geoffclare |
2009-08-06 15:56 | ajosey | Note Added: 0000181 | |
2009-08-06 15:56 | ajosey | Status | Resolved => Interpretation Required |
2009-08-11 16:36 | Don Cragun | Interp Status | => Pending |
2009-09-17 15:41 | nick | Interp Status | Pending => Proposed |
2009-10-12 05:32 | ajosey | Note Edited: 0000181 | |
2009-10-12 05:32 | ajosey | Interp Status | Proposed => Approved |
2009-10-12 05:32 | ajosey | Final Accepted Text | => 0000087:0000181 |
2010-09-20 09:24 | geoffclare | Tag Attached: tc1-2008 | |
2011-05-23 16:57 | eblake | Relationship added | related to 0000452 |
2011-05-23 17:03 | eblake | Note Added: 0000789 | |
2011-06-15 14:56 | eblake | Relationship added | related to 0000093 |
2011-06-15 16:13 | geoffclare | Note Added: 0000838 | |
2011-06-15 16:17 | geoffclare | Resolution | Accepted => Reopened |
2011-06-16 07:12 | Don Cragun | Interp Status | Approved => --- |
2011-06-16 15:04 | Don Cragun | Note Edited: 0000181 | |
2011-06-16 15:05 | Don Cragun | Interp Status | --- => Pending |
2011-06-16 15:05 | Don Cragun | Resolution | Reopened => Accepted As Marked |
2011-07-28 16:30 | eblake | Note Added: 0000895 | |
2011-07-28 16:30 | eblake | Note Edited: 0000895 | |
2011-07-28 16:31 | eblake | Relationship added | related to 0000480 |
2011-07-29 09:27 | geoffclare | Note Edited: 0000838 | |
2011-07-29 10:20 | geoffclare | Relationship added | related to 0000482 |
2011-08-11 16:02 | ajosey | Interp Status | Pending => Proposed |
2011-08-11 16:02 | ajosey | Note Added: 0000937 | |
2011-09-12 15:24 | ajosey | Interp Status | Proposed => Approved |
2011-09-12 15:24 | ajosey | Note Added: 0000965 | |
2012-01-31 17:12 | geoffclare | Note Edited: 0000838 | |
2013-04-16 13:06 | ajosey | Status | Interpretation Required => Closed |
2014-01-17 22:13 | eblake | Relationship added | related to 0000816 |
2019-08-29 16:21 | eblake | Relationship added | related to 0000701 |