!standard A.8.2 (16) 98-04-04 AI95-00085/05 !standard A.12.1(33) !class confirmation 95-08-19 !status ARG approved (subject to editorial review) 12-0-0 98-04-03 !status work item 95-11-01 !status received 95-08-19 !priority High !difficulty Hard !subject Append_File, Reset and positioning !summary 98-04-04 A call to Reset without the Mode parameter is equivalent to a call to Reset with the current mode of the file. The beginning and end of the file mentioned in the description of the semantics of Reset designate the beginning and end of the external file. It is legitimate for an implementation to raise Use_Error on the positioning operations of Stream_IO in the circumstances where the underlying operating system does not support positioning. The procedure Stream_IO.Set_Mode sets the mode of the file, it doesn't necessarily change it. !question 98-04-04 1. Are the following two calls equivalent, even if F is opened in Append_File mode? (yes) Reset (F, Mode => Mode (F)); Reset (F); 2. A call to Reset with mode In_File allows reading to be restarted "from the beginning of the file". RM95 A.7(2) indicates that the term "file" refers to a file object, not to an external file. Does the phrase "beginning of the file" refer to the beginning of the external file? (the external file) 3. For a Unix implementation that uses the Unix append mode to implement files opened in Append_File mode, what are the possible effects of Set_Index? (do the right thing or raise Use_Error.) 4. RM95 A.12.1(35) says that "the Set_Mode procedure changes the mode of file." Does that mean that Set_Mode can only be used to "change" the mode of the file? (no) !response 98-04-04 1. RM95 A.8.2(16) states that: "if a Mode parameter is supplied, the current mode of the given file is set to the given mode." This paragraph doesn't mention any other effect for the Mode parameter; therefore, setting the Mode parameter Mode (F) has essentially no effect, and the two calls Reset (File, Mode (File)) and Reset (File) are equivalent. For a file which is opened in Append_File mode, Reset (F) positions the file so that writing can be restarted after the last element of the external file. This is explicitly stated in RM95 A.8.2(16), although this section uses the word "file" when it should say "external file". Note that for a Unix implementation, it makes it possible to use the Unix append mode, and to implement any of these two calls without closing and reopening the file. 2. When RM95 A.8.2(16) talks about the "beginning of the file" or "the last element of the file" it is talking about the beginning and end of the external file (despite RM95 A.7(2)). For a file that is Reset to mode In_File, reading restarts at the beginning of the external file. This is supported by the annotation in AARM A.10.2(4.a), which indicates that Reset should be similar to closing and then reopening. The internal file essentially disappears between closing and reopening, so clearly Reset is resetting based on properties of the external file, not of the internal file. Note that for a Unix implementation which uses the Unix append mode to implement files opened in Append_File mode, this means that resetting to In_File or Out_File must be implemented by closing and reopening. 3. It is the intent that a Unix implementation can use the Unix append mode to implement files opended in Append_File mode. For a stream designating such a file, positioning is effectively impossible because, if the O_APPEND bit was set at open time, "the file pointer is set to the end of the file prior to each write" (excerpt from the Unix man page for open). RM95 A.12.1(32) makes it clear that such an implementation is legitimate, provided that it raises Use_Error on the positioning operations: "if positioning is not supported for the given file, then a call to Index or Set_Index propagates Use_Error." Although this compromises portability (different compilers may use different implementations, and certainly different OSes may have different restrictions), the stress here is on performance: the intent is that the file and stream operations should be implemented as a thin layer on top of the OS calls, and should not have to simulate services that are not provided by the underlying OS. 4. RM95 A.12.1(35) should say that "the procedure Set Mode sets the mode of the file." If the Mode parameter is the current mode of the file, then surely the mode of the file is not changed. !appendix 96-04-04 !section A.7(02) !subject Questions about Append_File mode !reference RM95-A.7(2) !reference RM95-A.8.2(15,16) !reference AARM95-A.10.2(4.a) !from Keith Thompson 95-08-09 !reference as: 95-5253.a Keith Thompson 95-8-9>> !discussion Some aspects of Append_File mode seem unclear. For example: 1. Reset with an explicit Mode => Append_File (for a text or sequential file) causes writing to continue at the end of the file, yes? Assume F is a (text or sequential) file whose current mode is Append_File. Are the following two calls equivalent? Reset(F, Mode => Append_File); Reset(F); More generally, are these always equivalent? Reset(F, Mode => Mode(F)); Reset(F); I believe they should be, but I've been unable to prove it from the RM or AARM. 2. A call to Reset with mode In_File allows reading to be restarted "from the beginning of the file". RM95-A.7(2) indicates that the term "file" refers to a file object, not to an external file. Does the phrase "beginning of the file" refer to the beginning of the external file? In particular, what is the effect of the following code fragment, assuming all operations are successful? declare package Int_IO is new Ada.Sequential_IO(Integer); F: Int_IO.File_Type; File_Name: constant String := "foo.dat"; begin Int_IO.Create(F, File_Name); for I in 1 .. 3 loop Int_IO.Write(F, I); end loop; Int_IO.Close(F); -- -- foo.dat now contains (1, 2, 3) -- Int_IO.Open(F, Mode => Int_IO.Append_File, Name => File_Name); for I in 4 .. 6 loop Int_IO.Write(F, I); end loop; -- -- foo.dat now contains (1, 2, 3, 4, 5, 6), -- but where is the "beginning of the file"? -- Int_IO.Reset(F, Mode => Int_IO.Out_File); Int_IO.Write(F, 999); Int_IO.Close(F); end; If the "beginning of the file" is the beginning of the external file, the final contents of foo.dat should be the single integer 999. If it refers to the beginning of the file object, *and* the beginning of a file in Append_File mode is considered to be the point at which it was opened, foo.dat should contain 4 integers: 1, 2, 3, and 999. (The previously written values 4, 5, and 6 are lost in either case). It would be easier and more intuitive, IMHO, for Reset to go to the beginning of the external file, but I can't infer this behavior from the RM. The note in AARM95-A.10.2(4.a): The behavior of Reset should be similar to closing a file and reopening it with the given mode. tends to support this, but it's not binding. On the other hand, if Reset goes back to the beginning of the external file, there's no easy way to go back to the position at which it was opened for appending. (This is probably no great loss.) **************************************************************** !section A.8.2(16) !subject Questions about Append_File mode !reference AI95-00085 !reference RM95-A.8.2(16) !reference RM95-A.7(2) !reference AARM-A.10.2(4.a) !from Tucker Taft 95-10-30 !reference 95-5373.h Tucker Taft 95-10-30>> !discussion I certainly believe that Reset(File, Mode(File)) is equivalent to simply Reset(File). I can't imagine any other meaningful interpretation for A.8.2(16). As far as external vs. internal file, I believe that the wording in A.8.2(16) is sloppy, and whenever it talks about the "beginning of the file" or "the last element of the file" it is talking about the beginning and end of the external file (despite A.7(2)). It makes no difference whether the file was initially opened in append mode, or was reset to that mode somewhere along the way. The annotation in A.10.2(4.a) seems to make this intent clear, by indicating that Reset should be similar to closing and then reopening. The internal file essentially disappears between closing and reopening, so clearly Reset is resetting based on properties of the external file, not of the "internal" file. **************************************************************** From: Robert Dewar[SMTP:dewar@gnat.com] Sent: Thursday, April 09, 1998 8:36 AM Subject: Re: AI95-00085 <> I find this FAR too vague. Obviously if poisitioning is not supported at all (a system with only tapes :-) then no argument. But how about a unix-like system in which general positioning is of course supported, but you *prefer* to use some specific OS facility to implement e.g. append mode files, which does not support the positioning that is needed. Are you allowed to blow away the call with a use_error. I think the answer should be no! There should be maximum pressure to make your IO system conform to the Ada model, and I dislike strong suggestions to the contrary. I think this paragraph should be removed from the AI. It adds nothing, except an unwelcome suggestion that this kind of compromise is perfectly OK. **************************************************************** From: Pascal Leroy[SMTP:phl@Rational.Com] Sent: Thursday, April 09, 1998 10:55 AM Subject: Re: AI95-00085 > But how about a unix-like system in which general positioning is of > course supported, but you *prefer* to use some specific OS facility > to implement e.g. append mode files, which does not support the > positioning that is needed. Are you allowed to blow away the call > with a use_error. I think the answer should be no! But the feeling at the last meeting was precisely that the implementation should be allowed to use Unix O_APPEND, and that if it does so it probably has to raise Use_Error on a call to Set_Index for a stream that is open in Append_Mode. It seems to me that requiring an implementation to support Set_Index on a stream in Append_Mode effectively precludes use of O_APPEND, and that's annoying. Pascal **************************************************************** From: Robert Dewar[SMTP:dewar@gnat.com] Sent: Thursday, April 09, 1998 9:10 AM Subject: Re: AI95-00085 <> Why is that annoying? If people want to use Unix-specific I/O, please do it directly! The whole idea in defining an I/O facility at the language level is for portability. Yes, it is frustrating when the models do not match, but that's too bad, since models between operating systems do not match precisely, this is inevitable. I think the decision to allow O_APPEND here is plain wrong. It is perfectly possible to implenment the Ada I/O facilities without allowing O_APPEND. **************************************************************** From: Robert Dewar[SMTP:dewar@gnat.com] Sent: Thursday, April 09, 1998 9:15 AM Subject: Re: AI95-00085 Incidentally, I absolutely agree that the design of the Ada with respect to Append was injudicious. I suspect that whoever did the design simply did not take the effort to look at the Unix semantics. But there are only two acceptable approaches in my mind at this stage: 1. Change the language to match the Unix semantics 2. Insist on the (perfectly possible to meet even on Unix) requirement that the implementation implement the language as chosen. The permission not to implement things in the RM is supposed to handle cases where it is impractical or impossible to implement things right, not simply cases where implementing things right is, to use Pascal's word, "annoying". **************************************************************** From: Pascal Leroy[SMTP:phl@Rational.Com] Sent: Thursday, April 09, 1998 11:43 AM Subject: Re: AI95-00085 > 1. Change the language to match the Unix semantics Well, if you ask me, the notion of calling Set_Index on a stream in Append_Mode if pretty weird, and it's not clear what the semantics of such a call should be. Say that after calling Set_Index, I call Write: what happens? Does it write at the end of the file? At the current point? Does it truncate the file? At the very least, these questions require clarification, and this is not changing the language. I am tempted to say that Set_Index in Append_Mode is likely to be a programming error, and should always raise some exception (and I now regret that I didn't write the AI in this direction in the first place). > 2. Insist on the (perfectly possible to meet even on Unix) requirement > that the implementation implement the language as chosen. > > The permission not to implement things in the RM is supposed to handle > cases where it is impractical or impossible to implement things right, > not simply cases where implementing things right is, to use Pascal's > word, "annoying". I was not thinking in terms of implementation, but in terms of usage. We have many users who want to mix Ada and C I/Os on the same file. I would find it rather unpleasant if an Ada Append_Mode file was not opened with O_APPEND, or if passing an O_APPEND file to Ada caused it to be closed and reopened so that Ada can do its silly simulation. Pascal **************************************************************** From: Robert Dewar[SMTP:dewar@gnat.com] Sent: Thursday, April 09, 1998 9:46 AM Subject: Re: AI95-00085 <> Mixing Ada and C I/O may or may not succeed. It is not a requirement that it work smoothly, just something nice to have. You are free to implement a form parameter to ensure this smooth interchange. As I am sure you know GNAT takes a different tack, we allow a file to be opened using the stream identifier passed in from C, and that ensures a common view of the file. **************************************************************** From: Robert I. Eachus[SMTP:eachus@mitre.org] Sent: Thursday, April 09, 1998 10:10 AM Subject: Re: AI95-00085 At 10:15 AM 4/9/98 EDT, Robert Dewar wrote: >The permission not to implement things in the RM is supposed to handle >cases where it is impractical or impossible to implement things right, >not simply cases where implementing things right is, to use Pascal's >word, "annoying". Is an implementation allowed to silently close and reopen an (external) file in response to a Set_Position, if it was originally opened in Append mode? I assume so, and that this would be the preferable option for Unix. (I'm not sure what the right thing to do is if an unnamed file/pipe was opened in append mode though. Probably, that is a case for Use_Error.) Robert I. Eachus with Standard_Disclaimer; use Standard_Disclaimer; function Message (Text: in Clever_Ideas) return Better_Ideas is... **************************************************************** From: Tucker Taft Sent: Thursday, April 09, 1998 10:42 AM Subject: Re: AI95-00085 Another possibility would be to use O_APPEND mode until a Set_Index is called, and only then go through the trouble of re-opening in non-append mode rather than raising Use_Error, with the presumption that Set_Index will be used rarely for files opened in append mode. Effectively Set_Index would be almost like a Reset(F, Mode => Out_File) (though of course Mode(F) would still return Append_File). -Tuck **************************************************************** From: Robert Dewar[SMTP:dewar@gnat.com] Sent: Thursday, April 09, 1998 11:50 AM Subject: Re: AI95-00085 < Out_File) (though of course Mode(F) would still return Append_File). >> That's perfectly reasonable. We do something like this in GNAT when you switch from read to write mode for stream_io, we first open in read only mode, then reopen in update mode when you switch. **************************************************************** From: Robert Dewar[SMTP:dewar@gnat.com] Sent: Thursday, April 09, 1998 11:47 AM Subject: Re: AI95-00085 << Is an implementation allowed to silently close and reopen an (external) file in response to a Set_Position, if it was originally opened in Append mode? I assume so, and that this would be the preferable option for Unix. (I'm not sure what the right thing to do is if an unnamed file/pipe was opened in append mode though. Probably, that is a case for Use_Error.) >> Of course you are allowed to silently close and reopen in response to Set_Position (you can do it on every read if you like :-) **************************************************************** From: Randy Brukardt[SMTP:Randy@rrsoftware.com] Sent: Thursday, April 09, 1998 12:29 PM Subject: RE: AI95-00085 I've been following this discussion, and I just don't get it. Probably the problem is my lack of experience with the common usages of Unix. I just don't understand why anyone would want to use O_APPEND on a positionable device. When I studied the Unix documents, I just viewed O_APPEND as (to borrow Robert's term) a junk mode. Why would anyone WANT to disallow positioning on their file? I can see that it may not matter in some cases, but I can't see any reason that anyone would want the defined behavior of O_APPEND. I would expect that most users just want to start writing at the end of the file, and don't care about positioning. I would expect that non-positionable devices would essentially be in append mode at all times, so there is no need for some junk mode in that case, either. The Ada Append_Mode matches the behavior I would expect exactly: starting writing at the end of the file, but has no other semantic effects. If this means not using a junk mode, so be it. It was always my view that Append is a feature of Open/Create, not a mode. It should have been implemented as an optional parameter to Open/Create. As far as mixing Ada and C I/O, I don't see a problem. If the file is opened in C, and imported into Ada somehow, there cannot be a problem. That is outside of anything in the Ada standard, so do whatever you want - raise Use_Error anywhere you have to. If the file is opened in Ada and passed to C, there shouldn't a be a problem. Since O_APPEND disallows various operations, I don't see how not using it on a file could break any existing C code (unless that C code was completely broken in the first place). In any, I would expect most code that takes files to work irregardless of the file mode. If you absolutely have to have O_APPEND opens, add a form parameter "Open_with_junk_O_Append" and open it that way. Then you can raise Use_Error anywhere you like. I agree with Robert that there is no good reason to break portability of software by allowing compilers to raise Use_Error when it is easy to avoid it. This is especially so in order to support junk file options of a particular (admittedly popular) operating system. Randy. **************************************************************** From: Tucker Taft[SMTP:stt@inmet.com] Sent: Thursday, April 09, 1998 2:14 PM Subject: RE: AI95-00085 > I've been following this discussion, and I just don't get it. Probably the > problem is my lack of experience with the common usages of Unix. > > I just don't understand why anyone would want to use O_APPEND on a > positionable device. When I studied the Unix documents, I just viewed > O_APPEND as (to borrow Robert's term) a > junk mode. Why would anyone WANT to disallow positioning on their file? I > can see that it may not matter in some cases, but I can't see any reason > that anyone would want the defined behavior of O_APPEND. I would expect > that most users just want to start writing at the end of the file, and > don't care about positioning. O_APPEND is a relatively new mode for Unix (speaking geologically here). It was invented to solve the problem of having multiple processes all writing to the same log file at the same time, wanting all messages to end up at the end, no matter which process wrote them. Without O_APPEND, each process maintains its own internal idea of what is its position in the file, and even though it may position to the end when it first opens the file, because other processes are writing to the same file simultaneously, its position may no longer correspond to the end when it gets around to writing. In my view, the "Append_File" mode in Ada is intended to allow the use of O_APPEND, but not require it, at least for Sequential_IO. However, A.14 makes it clear that each stream file object has its own current_index, presuming the file supports positioning. This would seem to preclude the use of O_APPEND, with its automatic position-to-the-end semantics, unless positioning is disallowed for the file. Hence it seems necessary to either raise Use_Error on Set_Index, or not use O_APPEND mode for stream files. Presumably a Form parameter could be used to control which semantics are preferred. > I would expect that non-positionable devices would essentially be in append > mode at all times, so there is no need for some junk mode in that case, > either. > > The Ada Append_Mode matches the behavior I would expect exactly: starting > writing at the end of the file, but has no other semantic effects. If this > means not using a junk mode, so be it. > > It was always my view that Append is a feature of Open/Create, not a mode. > It should have been implemented as an optional parameter to Open/Create. The issue is what happens in the presence of multiple processes all appending to the same file. > I agree with Robert that there is no good reason to break portability of > software by allowing compilers to raise Use_Error when it is easy to avoid > it. This is especially so in order to support junk file options of a > particular (admittedly popular) operating system. It seems better to support either approach by use of a Form parameter. It is not clear to me which should be the default for Append_File in the absence of a Form parameter, but it now seems clear to me that O_APPEND mode is inconsistent with the A.14(4) requirement that each stream file maintains its own current index, unless positioning is not allowed for the file (i.e. Set_Index raises Use_Error). > Randy. -Tuck **************************************************************** From: Ted Baker[SMTP:baker@dad.cs.fsu.edu] Sent: Thursday, April 09, 1998 2:41 PM Subject: Re: AI95-00085 This kind of Ada-centric view (of append-only file access modes) is typical of the kind of attitude that has held Ada back. The Ada'95 append mode was intended to allow access to OS-provided append modes. If we now prevent it from mapping in a sensible way, we just make Ada look absurd. --Ted **************************************************************** From: Robert Dewar[SMTP:dewar@gnat.com] Sent: Thursday, April 09, 1998 2:40 PM Subject: Re: AI95-00085 <> Are you specifically talking about O_APPEND here? We may say that the Ada 95 append mode was intended to allow access to OS-provided append modes, but all OS's do not provide the same stuff, are you saying that you think append mode should be entirely implementation dependent? **************************************************************** From: Randy Brukardt[SMTP:Randy@rrsoftware.com] Sent: Thursday, April 09, 1998 3:16 PM Subject: RE: AI95-00085 >O_APPEND is a relatively new mode for Unix (speaking geologically here). >It was invented to solve the problem of having multiple processes >all writing to the same log file at the same time, wanting all messages >to end up at the end, no matter which process wrote them. OK. Sounds like my impression is correct: it is a junk mode created to patch around the lack of kernel-level sharing, good synchronization methods, and shared address space threads in [basic] Unix, and a lack of awareness of tasking issues in C. Such stuff is totally unnecessary from an Ada perspective, which has good synchronization methods and tasking. This just makes it a C-to-Ada interface issue, and such issues are best handled with forms and pragmas, not by messing with the basic Ada semantics. Randy. **************************************************************** From: Ted Baker[SMTP:baker@dad.cs.fsu.edu] Sent: Thursday, April 09, 1998 4:10 PM Subject: Re: AI95-00085 | Of course you are allowed to silently close and reopen in response to | Set_Position (you can do it on every read if you like :-) The above would be very unwise in a UNIX system, since the semantics would be much different than if the file were to stay open. In particular, a file that is open cannot go away, even if it is (concurrently) unlinked, whereas once an unlinked file is closed it goes away. I suppose this is another respect in which the ARM semantics don't match UNIX semantics. The ARM says that when you Delete a file it ceases to exist. In UNIX, a file does not cease to exist until the last close. I can't imagine that existing Ada implementations on UNIX systems are required to somehow defeat the UNIX last-close semantics, so I guess the requirement about files ceasing to exist immediately after Delete is not being enforced. Given this, why not leave the Append semantics open enough that a direct mapping to O_APPEND mode is OK? --Ted **************************************************************** From: Ted Baker[SMTP:baker@dad.cs.fsu.edu] Sent: Thursday, April 09, 1998 4:24 PM Subject: RE: AI95-00085 | I just don't understand why anyone would want to use O_APPEND ... | ... junk mode. ... I can't see any reason | that anyone would want the defined behavior of O_APPEND. ... O_APPEND serves a critical purpose, i.e., a safe way to write to log-files by multiple processes. When you use it, you DON'T want to allow positioning the file, and the mode prevents you from doing so; however, the file normally is disk file and so positionable if opened in other modes. [In case it is not sufficiently obvious, O_APPEND does something you *cannot* do with lseek() to the end of the file, because the lseek() and the following write operation are not atomic, and so one process could end up writing on top of something just previously logged by another.] | It was always my view that Append is a feature of Open/Create, not a mode. | It should have been implemented as an optional parameter to Open/Create. ?????????? Append *is* something you specify in Open/Create. --Ted **************************************************************** From: Ted Baker[SMTP:baker@dad.cs.fsu.edu] Sent: Thursday, April 09, 1998 4:31 PM Subject: Re: AI95-00085 | Are you specifically talking about O_APPEND here? Certainly it should include O_APPEND, or more specifically the append-only (nonrepositionable, always-write-at the end) semantics. Otherwise, if the semantics could be emulated using other existing Ada operations, there would be no reason to add an append mode to the language. | We may say that the Ada 95 append mode was intended to allow access to | OS-provided append modes, but all OS's do not provide the same stuff, are | you saying that you think append mode should be entirely implementation | dependent? Not "entirely", but certainly loose enough to allow mapping to O_Append. --Ted **************************************************************** From: Ted Baker[SMTP:baker@dad.cs.fsu.edu] Sent: Thursday, April 09, 1998 4:27 PM Subject: RE: AI95-00085 | However, A.14 makes it clear that each stream file object has its | own current_index, presuming the file supports positioning. | This would seem to preclude the use of O_APPEND, with its automatic | position-to-the-end semantics, unless positioning is disallowed | for the file. Hence it seems necessary to either raise Use_Error | on Set_Index, or not use O_APPEND mode for stream files. Presumably the only issue here is whether we want people to be able to use stream I/O to write log files from Ada programs in a concurrent environment. I've been presuming everyone would agree that the answer is "yes". --Ted **************************************************************** From: Robert Dewar[SMTP:dewar@gnat.com] Sent: Thursday, April 09, 1998 4:45 PM Subject: RE: AI95-00085 <> It is inappropriate to expect the Ada feature to provide this functionality. It is not documented to do so, and relying on it to do so, because you know your implementation happens to work this way is a style of non-portable programming that is not to be encouraged. If you want to rely on a Unix specific feature, use the Unix specific feature directly! <> No, it is a mode, and can be reset -- I very much agree that it should have been an optional parameter of Open/Create, but it is not! **************************************************************** From: Robert Dewar[SMTP:dewar@gnat.com] Sent: Thursday, April 09, 1998 4:42 PM Subject: Re: AI95-00085 <> Certainly GNAT does reopens in some cases, precisely to get a BETTER match to Unix semantics (i.e. do not open in update mode until you know you are going to be writing). <> Because it introduces unnecessary non-portability. If you think that it is fine not to be able to position, then your implementation can use O_APPEND *until* you reposition. If you want to use O_APPEND and reposition you are out of luck anyway! **************************************************************** From: Robert Dewar[SMTP:dewar@gnat.com] Sent: Thursday, April 09, 1998 4:46 PM Subject: RE: AI95-00085 <> Absolutely NOT! If you want to rely on Unix specific features for writing log files in a concurrent safe manner, then you should use the C streams and specific C/Unix features to do this. You can still use stream attributes in Ada to write and read the data. I see no particular merit in twisting Stream_IO into service for this purpose, since the resulting code would be annoyingly and obscurely implementation dependent. **************************************************************** From: Robert Dewar[SMTP:dewar@gnat.com] Sent: Thursday, April 09, 1998 4:52 PM Subject: RE: AI95-00085 <> What he means by junk (and I concur with his choice of the term) is some operating specific special feature meant to solve some problem in a peculiar operating system idiosyncratic feature. This feature may be interesting for Unix users, but it has nothing to do with Ada, and *allowing* (rather than insisting, which is impractical) implementations to map a specific restricted style of Ada stream_io (without a form parameter) to this strange Unix feature is not only not helpful it is actively harmful. If an implentor wants to provide this feature, the proper way to do it is with a form parameter, that specifies O_APPEND mode is to be used, and then of course you are free to enforce any restrictions you like. This is a perfectly valid approach, it makes the implementation dependence apparent, which is a GOOD THING, while preserving the capability you think is important in this specific environment. **************************************************************** From: Norman H Cohen[SMTP:ncohen@us.ibm.com] Sent: Thursday, April 09, 1998 4:52 PM Subject: Re: AI95-00085 It seems quite reasonable to assert that repositioning a file opened in append mode raises Use_Error, and to state that this happens portably and predictably for all implementations (Write Once, Blow Up Anywhere). This would allow Ada append mode to be directly mapped to Unix O_APPEND. More importantly, appending and repositioning are a logically inconsistent combination. -- Norman **************************************************************** From: Robert Dewar[SMTP:dewar@gnat.com] Sent: Thursday, April 09, 1998 4:58 PM Subject: Re: AI95-00085 <> It may be reasonable. It is a definite language change. It is perfectly reasonable to append, write stuff, go back and patch something you already wrote, position to the end, write some more, etc. so I disagree with the last statement. **************************************************************** From: Jean-Pierre Rosen[SMTP:rosen.adalog@wanadoo.fr] Sent: Friday, April 10, 1998 2:19 AM Subject: Re: AI95-00085 After reading the flood on this subject, I strongly concur with Robert's position, that I would rephrase this way: Those who want the semantics of a particular OS use the binding to this OS (and we do have a good binding to POSIX). Those who want portability across various OSes use Ada predefined services. Ted, are you discovering that portability sometimes requires the least common demoninator of various OSes ? ---------------------------------------------------------------------------- J-P. Rosen (Rosen.Adalog@wanadoo.fr) Visit Adalog's web site at http://perso.wanadoo.fr/adalog **************************************************************** From: Pascal Leroy[SMTP:phl@Rational.Com] Sent: Friday, April 10, 1998 5:46 AM Subject: Re: AI95-00085 Wow! 30+ messages in my mailbox this morning on this wretched AI! We have not had such a lively discussion on the ARG list for a long time. For the record, I agree with essentially everything that Ted said. > < append > mode raises Use_Error, and to state that this happens portably and > predictably > for all implementations (Write Once, Blow Up Anywhere). This would allow Ada > append mode to be directly mapped to Unix O_APPEND. More importantly, > appending and repositioning are a logically inconsistent combination. > >> > > It may be reasonable. I agree with Norm that appending and repositioning are probably inconsistent, and at the very least don't have a "natural" semantics. So if nothing else, this AI _must_ define what repositioning might mean for an append stream. > It is a definite language change. Definitely not. It is very much unclear what is the semantics of repositioning on an append file in the first place, and the RM doesn't give any clue as to what it should mean in Ada. (In fact, it's hard to find a section of the RM which is less precise than A.12.1.) So whatever we decide is not a language change, only a clarification. > It is perfectly reasonable to append, write stuff, go back and patch > something > you already wrote, position to the end, write some more, etc. so I disagree > with the last statement. That's one possible interpretation. Here is another one: On a stream opened in Append_Mode, Set_Index truncates the file at the specified position, and the next write will take place at the (new) end of the file. Surely this preserve two invariants: (1) Set_Index effectively moves to the specified position and (2) in Append_Mode, you only write to the end of the file. These two interpretations are (1) legitimate (2) not substantiated by the RM and (3) not contradicted by the RM. Pascal _____________________________________________________________________ Pascal Leroy +33.1.30.12.09.68 pleroy@rational.com +33.1.30.12.09.66 FAX **************************************************************** From: Robert Dewar[SMTP:dewar@gnat.com] Sent: Friday, April 10, 1998 6:03 AM Subject: Re: AI95-00085 Pascal says Definitely not. It is very much unclear what is the semantics of repositioning on an append file in the first place, and the RM doesn't give any clue as to what it should mean in Ada. (In fact, it's hard to find a section of the RM which is less precise than A.12.1.) So whatever we decide is not a language change, only a clarification. >> Robert replies: Well it is clear that positioning *is* allowed, so an AI that says it is not allowed is clearly a language change. Pascal suggests a possible interpretation of positioning: On a stream opened in Append_Mode, Set_Index truncates the file at the specified position, and the next write will take place at the (new) end of the file. Surely this preserve two invariants: (1) Set_Index effectively moves to the specified position and (2) in Append_Mode, you only write to the end of the file. These two interpretations are (1) legitimate (2) not substantiated by the RM and (3) not contradicted by the RM. Robert replies I disagree that the RM is unclear, and I do not think that Pascal's interpretation here is supportable. The RM simply says about Append_File that it causes the first transfer to be at the end of the file. I think what is going on here is that people read about append, and assume that for stream files it has something to do with O_APPEND in Unix, and then they start importing irrelevant semantics from Unix. When I looked at the RM, it was immediately clear to me that of course you can't use Unix append mode for stream_IO Append_File, since it has inconsistent semantics. We implemented a long time ago what seemed like the obviously required semantics, no one has ever complained, and no ACVC tests has contradicted this. I would be *very* reluctant to swich to an interpretation like the one above, which has no justification whatsoever in the RM, and might well cause silent malfunction of existing programs. Since Stream_IO is part of the core, there are 70 or so compilers that are implementing some interpretation or other of how this works. Can we please do a reasonably comprehensive survey of what implementors are in fact doing now, to at least make sure that whatever the ARG does in this non-critical area is not unnecesarily disruptive. I say non-critical here, because I have not seen users get worried about this issue! **************************************************************** From: Ted Baker[SMTP:baker@dad.cs.fsu.edu] Sent: Friday, April 10, 1998 8:28 AM To: arg95@sw-eng.falls-church.va.us Subject: copy of Baker/Dewar exchange Robert Dewar has requested that I forward the following e-mail exchange between him and myself, which I intended as a private exchange, but Robert apparently intended for the whole ARG. My apologies for the length. --Ted --------------------------------------------- From baker Thu Apr 9 18:59:59 1998 To: dewar@gnat.com Subject: RE: AI95-00085 Content-Length: 556 It is unfair to cite me as a satisfied user of that GNAT idiosyncracy. My "use" of GNAT is primarily for implementing the POSIX.5 interfaces, and implementing the GNAT runtime. This feature does not come up there. That does not mean it is not an important functionality to real users. What really galls me about this discussion is that the reason for Append being added to Ada'9X was input from the POSIX Ada bindings group, and it specifically was intended to map O_APPEND --- despite whatever revisionist rhetoric you and Randy want to put out. --Ted From dewar@gnat.com Thu Apr 9 23:01 EST 1998 Return-Path: Received: from cs.fsu.edu by dad.cs.fsu.edu with SMTP (SMI-8.6/SMI-SVR4) id XAA20500; Thu, 9 Apr 1998 23:01:25 GMT Received: from sw-eng.falls-church.va.us (ns1.sw-eng.falls-church.va.us [199.75.54.2]) by cs.fsu.edu (8.8.8/8.7.3) with ESMTP id TAA22871 for ; Thu, 9 Apr 1998 19:01:27 -0400 (EDT) Received: from nile.gnat.com by sw-eng.falls-church.va.us (8.8.8/) id WAA11205; Thu, 9 Apr 1998 22:57:37 GMT Received: by nile.gnat.com (5.0/1.20) id AA28031; Thu, 9 Apr 98 18:59:04 EDT Date: Thu, 9 Apr 98 18:59:04 EDT From: dewar@gnat.com (Robert Dewar) Message-Id: <9804092259.AA28031@nile.gnat.com> To: Arg95@sw-eng.falls-church.va.us, baker@dad.cs.fsu.edu, dewar@gnat.com, ncohen@us.ibm.com Subject: Re: AI95-00085 Content-Type: text Content-Length: 393 Status: RO <> That's odd, the whole discussion is about *taking away* functionality from the current append semantics in the RM! From baker Thu Apr 9 19:15:45 1998 To: dewar@gnat.com Subject: Re: AI95-00085 Content-Length: 592 | That's odd, the whole discussion is about *taking away* functionality from | the current append semantics in the RM! The capability that is lost from UNIX is (atomic) writes to the end of a file by multiple processes. Providing that requires mapping directly to the OS O_APPEND mode, if there is one. If we require the Ada implementation to provide some other functionality (that can be simulated via other existing operations, and so is not a real gain) that required simulation of normal append mode writes via some non-atomic combination of system calls, then there is a loss. --Ted From dewar@gnat.com Thu Apr 9 23:05 EST 1998 Return-Path: Received: from nile.gnat.com by dad.cs.fsu.edu with SMTP (SMI-8.6/SMI-SVR4) id XAA20521; Thu, 9 Apr 1998 23:05:13 GMT Received: by nile.gnat.com (5.0/1.20) id AA02217; Thu, 9 Apr 98 19:03:03 EDT Date: Thu, 9 Apr 98 19:03:03 EDT From: dewar@gnat.com (Robert Dewar) Message-Id: <9804092303.AA02217@nile.gnat.com> To: baker@dad.cs.fsu.edu, dewar@gnat.com Subject: RE: AI95-00085 Content-Type: text Content-Length: 795 Status: R <<> This is not historically accurate, there were a number of revision requests for append mode, and they did not mention O_APPEND (I am not even sure it existed then!) What puzzles me Ted, is you had years to see a plain definition that was obviously inconcistent with O_APPEND semantics, and so did everyone else have this chance. The inconsistency was mentioned several times during the revision process. No one seemed concerned. No one raised the issue. It is a bit late to be suggesting significant changes to the language! From baker Thu Apr 9 19:19:28 1998 To: dewar@gnat.com Subject: RE: AI95-00085 Content-Length: 1006 | This is not historically accurate, there were a number of revision requests | for append mode, and they did not mention O_APPEND (I am not even sure it | existed then!) It certainly has existed, for many years, and has been in the POSIX spec. from the very beginning. The requests where I knew the people who put them in (like Dave Emery) were motivated by experience with UNIX/POSIX applications where the functionality was needed. Those requests may not have mentioned POSIX explicitly, so you may not have seen the connection. | What puzzles me Ted, is you had years to see a plain definition that was | obviously inconcistent with O_APPEND semantics, and so did everyone else | have this chance. The inconsistency was mentioned several times during | the revision process. No one seemed concerned. No one raised the issue. | It is a bit late to be suggesting significant changes to the language! Like several other things outside the tasking/AnnexD/AnnexC domain, I managed to miss this. --Ted From dewar@gnat.com Thu Apr 9 23:22 EST 1998 Return-Path: Received: from nile.gnat.com by dad.cs.fsu.edu with SMTP (SMI-8.6/SMI-SVR4) id XAA20558; Thu, 9 Apr 1998 23:22:20 GMT Received: by nile.gnat.com (5.0/1.20) id AA21075; Thu, 9 Apr 98 19:20:09 EDT Date: Thu, 9 Apr 98 19:20:09 EDT From: dewar@gnat.com (Robert Dewar) Message-Id: <9804092320.AA21075@nile.gnat.com> To: baker@dad.cs.fsu.edu, dewar@gnat.com Subject: Re: AI95-00085 Content-Type: text Content-Length: 1558 Status: RO <> Wait a minute, where is the loss here? There is nothing in the RM that talks about atomic writes by multiple processes. Such multiple writes to a file are clearly undefined in the Ada semantics. I really don't understand Ted's position at all. It seems to be something like: a) weaken the Ada semantics so that Ada compilers can use O_APPEND by default. b) do not require this weakening c) do not require the use of O_APPEND d) if you are lucky enough to have a compiler that takes advantage of this new functionality, then feel free to use it to write non-portable code. Seems quite strange to me. Ted, why do you object to a Form parameter something like Atomic_Append, which we all agree MUST have the semantics you want if it is implemented, and is rejected otherwise. Incidentally, I think Ted's history is totally wrong here. Append is seriously useful functionality for Sequential and Text_IO. Its provision in Stream_IO seems to have been mostly a matter of (possibly misguided) orthogonality. At least that is the way that Dewar remembers history! From baker Fri Apr 10 08:02:15 1998 To: dewar@gnat.com Subject: Re: AI95-00085 Content-Length: 2276 Sorry to spend so much talk on such a minor matter, but not allowing a mapping to O_APPEND still seems fundamentally wrong-headed to me, your repeated assertions notwithstanding. I guess we are not going to agree on this one. | Wait a minute, where is the loss here? Loss of permission to access to underlying OS functionality. | a) weaken the Ada semantics so that Ada compilers can use O_APPEND by | default. Weaken here means giving up a functionality (repositioning an append-only stream) that seems to have no practical use. | b) do not require this weakening Seems to mean the same thing as below. | c) do not require the use of O_APPEND In case the OS does not support O_APPEND. | d) if you are lucky enough to have a compiler that takes advantage of | this new functionality, then feel free to use it to write | non-portable code. I'd like to see this be the required semantics, for UNIX systems, e.g. by the POSIX Ada bindings. | Seems quite strange to me. Ted, why do you object to a Form parameter | something like Atomic_Append, which we all agree MUST have the semantics | you want if it is implemented, and is rejected otherwise. Does GNAT support such a form parameter? POSIX.5 defined an interface for this, before Ada'9X, but I have not seen the POSIX.5 form parameters supported. Moreover, last time we revised POSIX.5, people argued that we did not need this (complicated and unwieldy) form parameter business any more, given Ada'95 support for Append mode. In contrast to the form parameter, O_APPEND is very simple to implement (simpler than the form parameter, and simpler than trying to allow repositioning), and could easily become the defacto standard for systems that support it, if it were permitted. | Incidentally, I think Ted's history is totally wrong here. | Append is seriously useful functionality for Sequential and Text_IO. Its | provision in Stream_IO seems to have been mostly a matter of (possibly | misguided) orthogonality. | At least that is the way that Dewar remembers history! Yes, the addition to Stream_IO was clearly last-minute, and for orthogonality. The inclusion for Sequential and Text_IO is what I was taking about, where providing a mapping for O_APPEND is the historical basis. --Ted From dewar@gnat.com Fri Apr 10 12:20 EST 1998 Return-Path: Received: from nile.gnat.com by dad.cs.fsu.edu with SMTP (SMI-8.6/SMI-SVR4) id MAA20861; Fri, 10 Apr 1998 12:20:07 GMT Received: by nile.gnat.com (5.0/1.20) id AA22760; Fri, 10 Apr 98 08:17:54 EDT Date: Fri, 10 Apr 98 08:17:54 EDT From: dewar@gnat.com (Robert Dewar) Message-Id: <9804101217.AA22760@nile.gnat.com> To: baker@dad.cs.fsu.edu, dewar@gnat.com Subject: Re: AI95-00085 Content-Type: text Content-Length: 5379 Status: R <> Ah! But that is a TOTALLY different matter. Nothing we are talking about here requires any compiler to actually *support* what you want. If you want to go far beyond the AI, appropriate in the context of the POSIX Ada bindings, but clearly not in the context of the AI, and make such a requirement, then that's fine, but a Form parameter is a perfectly good (actually preferable) path to implementing this requirement. <> Too bad that people did not know what they were talking about! Clealry the Ada semantics as defined at the time did not support this argument. This is not an unknown issue, as my comments quoted from the GNAT sources show, I was aware of this issue years ago when I first implemented append mode. Indeed it seemed quite obvious to me that the RM was inconsitent with the use of the Unix append mode. I found it annoying, but there are many things an implementor finds annoying with the language! Actually I found it much more annoying that you don't know whether to open a file in read or update mode when you first open it. <> Certainly not! As I mentioned to you earlier, no customer of ours has ever indicated that this was of interest. <> No, that's wrong. The desire for append here has nothing necessarily to do with synchronization with multiple processes. It is a much simpler requirement, namely to be able to write starting at the end of the file. Recall that neither Sequential_IO nor Text_IO allow the possibility of positioning, so this fundamental capability, needed on all operating systems, and available on all operating systems, was missing from Ada 83. The revision requests in this area mentioned nothing about O_APPEND or the need for providing this unix/posix special synchronization mechanism. Indeed, NONE of the Ada 95 discussions raised the issue of this syncrhonization question. Perhaps it was always in the minds of the Posix folks who were involved in the discussion, and perhaps they always *knew* that this was the crucial issue, but if so, it is too bad that they (a) did not speak up and (b) let the language be designed in a manner inconsistent with the use of Unix append without comment. I have been involved in all the Ada 95 discussions, but not the Posix discussions. However, I would comment that I always thought that the basic motivation for the Posix append was the more general requirement. After all, the main use of the append mode in Unix is for the simple general requirement of doing appends. Even in Unix, the synchronization lockout use is somewhat specialized (at least that is my experience in seeing the mode used in real programs). By the way, what does the ANSI C standard have to say about appending exactly, can someone provide the quote. I think compatibility with C, as opposed to compatibility with Unix, always provides a stronger form of the compatibility argument. I certainly have no objection to the Ada/Posix interface requiring support of the Posix/Unix type append. However *even if* the AI is written to allow the default behavior to mirror the Posix way of doing append, I would be *really annoyed* if the Posix binding required you to change your compiler to implement things this way. Ted says <> That is completely incorrect. Implementing append by changing the current semantics, which our customers have been using for four years is not at all trivial. We will have to do a survey to see who would be affected, and most probably implement some complex mechanism to provide back compatibility to those who are affected. Implementing a form parameter is a simple job which should take only a day or two, and be completely upwards compatible. When the ARG changes the language in a manner that requires existing compilers to change their implementation, and existing users to modify their code, they are behaving in the most aggressive manner possible. This level of aggression is only approrpriate for absolutely major issues (we did even dare to do this for the 256 character case -- have indeed we EVER done this). I do not begin to believe that this issue is of sufficient importance to warrant a requirement that existing implementations change, and I strongly recommend that the POSIX group meet their (very reasonable) requirement by other means than requiring language and implementation chanes. Yes, we might have done things differently 5 years ago if the issue had been clearly understood, but since no one brought it to the table then, it is too late now. Ada 95 is not under construction! We are talking about features that have been available to users for four years, following a standard that has been available for over two years. From baker Fri Apr 10 08:05:59 1998 To: dewar@gnat.com Subject: RE: AI95-00085 Content-Length: 600 | I never saw an explicit request for Append mode for Stream_IO ... | Ted, can you give the exact reference, I dug a little, but could not | find anything at all. I'm sorry I don't have the original (foot-think) revision requests any more, due to lack of storage space. If you have the original revision requests documents on-line, and can't find it there, then I may have to partially concede that I remember it wrong. Of course my memory is weighted toward what was said at the requirements workshops (e.g. Soderfors and Ft. Walton Beach), and that is not written down anywhere to check. --Ted From dewar@gnat.com Fri Apr 10 12:29 EST 1998 Return-Path: Received: from nile.gnat.com by dad.cs.fsu.edu with SMTP (SMI-8.6/SMI-SVR4) id MAA20879; Fri, 10 Apr 1998 12:29:48 GMT Received: by nile.gnat.com (5.0/1.20) id AA22843; Fri, 10 Apr 98 08:27:35 EDT Date: Fri, 10 Apr 98 08:27:35 EDT From: dewar@gnat.com (Robert Dewar) Message-Id: <9804101227.AA22843@nile.gnat.com> To: baker@dad.cs.fsu.edu, dewar@gnat.com Subject: RE: AI95-00085 Content-Type: text Content-Length: 3415 Status: R <> I was at Soderfors and at Ft. Walton Beach, and I am 99% sure that the syncrhonization issue was never mentioned. I think what happened is that people just *assumed* that the Ada append mode would map into the Unix append mode, and so it was not discussed. I must say I made this same assumption. It was a surprise to find out that this was not the case, but I only noticed this later on when I came to implement it. Interestingly, in GNAT, we do not even use append mode for the Text_IO and Sequential_IO cases, because of orthogonality in the implementation for the Stream_IO case. That's probably undesirable, but actually until this discussion, I was completely unaware of the synchronization issue, and of course it is completely outside the Ada 95 semantics. Indeed, relying on Append_File mapping into the Unix mode append even for Text_IO or Sequential_IO is incorrect implementation dependent coding in any case, so it is not clear that a user should rely on it. In the GNAT documentation (I am not talking the sources now, but the user level documentation), things are quite clear: Table 6-1 Open and Create Call Modes OPEN CREATE Append_File "r+" "w+" In_File "r" "w+" Out_File (Direct_IO) "r+" "w" Out_File (all other cases) "w" "w" Inout_File "r+" "w+" If text file translation is required, then either b or t is added to the mode, depending on the setting of Text. Text file translation refers to the mapping of CR/LF sequences in an external file to LF characters internally. This mapping only occurs in DOS and DOS-like systems, and is not relevant to other systems. A special case occurs with Stream_IO. As shown in the above table, the file is initially opened in r or w mode for the In_File and Out_File cases. If a Set_Mode operation subsequently requires switching from reading to writing or vice-versa, then the file is reopened in r+ mode to permit the required operation. I think it is quite important to provide this kind of documentation. Note that it is quite clear from this that we do NOT use the a or a+ modes for Append_File, and as I said before, no user has ever questioned this decision. I can't say all our users read the documentation carefully, but I can say that a lot do. GNAT does provide a mechanism for opening a Text_IO or Sequential_IO file using a stream value obtained from a C library call (or C code making such a library call), and so this is the well defined mechanism in GNAT for making use of the Unix append modes (you will then of course get an exception if you try to do a positioning operation). I would assume that any of our customers needing the special synchronization mechanisms of Unix/Posix are using this approach, which seems quite appropriate, since it nicely encapsulates the implementation dependent part of the process. From baker Fri Apr 10 09:02:32 1998 To: dewar@gnat.com Subject: Re: AI95-00085 Content-Length: 771 | That is completely incorrect. Implementing append by changing the current | semantics, which our customers have been using for four years is not at | all trivial. We will have to do a survey to see who would be affected, | and most probably implement some complex mechanism to provide back | compatibility to those who are affected. ... | Ada 95 is not under construction! We are talking about features that have | been available to users for four years, following a standard that has been | available for over two years. I may have lost the thread by now, but I thought the AI came because an implementation was raising Use_Error in this situation, and that I've been trying to support the position that such an implementation be allowed to continue to do so. --Ted From baker Fri Apr 10 09:08:54 1998 To: dewar@gnat.com Subject: RE: AI95-00085 Content-Length: 610 | this discussion, I was completely unaware of the synchronization issue, | and of course it is completely outside the Ada 95 semantics. It is not exactly synchronization (between processes), but atomicity. All individual I/O operations are atomic up to some level of granularity defined by the OS (usually one disk block). The special issue here is atomicity of the combined seek-to-end + write. With append mode, you do get something you cannot do with the combination of lseek and write. In this regard, the UNIX kind of append mode also provides functionality beyond Ada's Direct_IO interfaces. --Ted From dewar@gnat.com Fri Apr 10 12:53 EST 1998 Return-Path: Received: from nile.gnat.com by dad.cs.fsu.edu with SMTP (SMI-8.6/SMI-SVR4) id MAA20939; Fri, 10 Apr 1998 12:53:39 GMT Received: by nile.gnat.com (5.0/1.20) id AA23135; Fri, 10 Apr 98 08:51:27 EDT Date: Fri, 10 Apr 98 08:51:27 EDT From: dewar@gnat.com (Robert Dewar) Message-Id: <9804101251.AA23135@nile.gnat.com> To: baker@dad.cs.fsu.edu Subject: RE: AI95-00085 Content-Type: text Content-Length: 338 Status: R Ted, is it really the case that my last few messages on this went only to you. If so that's really aggravating, since the whole point is to discuss this with the ARG. GRRRR! I see that is the case. Have you saved these messages, if so, PLEASE forward them to the whole group. It is really a waste of time for just the two of us to talk. From baker Fri Apr 10 09:12:14 1998 To: dewar@gnat.com Subject: Re: previous mail Content-Length: 213 I'll find the mail, and forward it. I hope it does not overwhelm everybody. I was getting uncomfortable about the volume and length of it, hence my limiting my reply to you only, a couple of cycles back. --Ted **************************************************************** From: Ted Baker[SMTP:baker@dad.cs.fsu.edu] Sent: Friday, April 10, 1998 8:43 AM Subject: Re: last message of Baker/Dewar exchange | <> | Indeed, there is an implementation that wants to negate the standard by | raising Use_Error for all uses of positioning when Append_File is used. | We object because it is perfectly possible, even on Unix, and even if you | use the Unix append mode, to support positioning (by reopening the file). My disagreement here is that if you do this you hide a significant semantic event that the user did not expect (i.e., closing and then reopening) and which may have unwanted side-effects. If there were some important special Ada functionality here, this might be worth while, but no one has given any argument yet that explains how this functionality is needed. First of all, if repositioning is needed (even in other modes) with Stream_IO, why can we do without it for Text_IO and Sequential_IO? Second, if the semantics of repositioning in Append mode are the same as a combination of other operations that a user could have done, why do we need this mode at all? | But the suggestion that ALL implementations be required to raise Use_Error | (your suggestion) is way out of line. That is *not* what I'm suggesting. I'm suggesting that implementations be allowed (by the ARG) to raise Use_Error. What may have misled you is that I've also argued that other standards groups, like POSIX, be allowed (by the ARG) to narrow the semantic window for a particular OS. --Ted **************************************************************** From: Robert Dewar[SMTP:dewar@gnat.com] Sent: Friday, April 10, 1998 9:20 AM To: Arg95@sw-eng.falls-church.va.us; baker@dad.cs.fsu.edu Subject: Re: last message of Baker/Dewar exchange <> But these implicit reopens are part of life anyway, you have no way of avoiding these for the switch from reading to writing in a stream file, you certainly don't want to open all files in update mode just in case you may want to write, since that would mean you could not use stream_io on read only files. <> It is VERY useful to be able to reposition for stream files, code does this ALL the time. Sequential_IO and Text_IO are at a higher level where repositioning makes zero sense. <<| But the suggestion that ALL implementations be required to raise Use_Error | (your suggestion) is way out of line. That is *not* what I'm suggesting. I'm suggesting that implementations be allowed (by the ARG) to raise Use_Error. >> No, you are clearly suggesting this, *so that* you can then have the Posix binding require its use, so your ultimate agenda is precisely to require implementations to raise Use_Error. If this is not your intent (in the long run, including what you want the Posix interface to do), please clarify. To me, introducing implementation dependence here is a bad thing. Both in the case of direct Ada use of Stream_IO and the POSIX interface (which should support O_APPEND), I see no advantages in introducing implementation dependence. **************************************************************** From: David Emery[SMTP:emery@mitre.org] Sent: Friday, April 10, 1998 9:00 AM Subject: Re: last message of Baker/Dewar exchange Well, since my name was mentioned, I guess I'm entitled to contribute $.02 :-) Ted's recollection about 'intent' for Append_Mode matches my own. This was discussed within the POSIX.5 group, within the SIGAda ALIWG, and in some emails I remember back and forth during the Mapping and Revision process. The particular "desire" was to provide access to the functionality provided by Unix's O_APPEND for Ada files. There were two motivations for this: 1. Conformity with Unix semantics 2. It's generally useful. Within Unix, the 'formal semantics' mention atomic writes to the end of the file. At the user level, this degree of specification wasn't mentioned to my recollection. But the "semantics by analogy" from users was clear: We want Ada's Append_Mode to act like Unix's O_APPEND. I don't have my copy of POSIX.1 with me (I'm now working nearly full-time in the Pentagon :-(, so I can't look at the POSIX-specified for O_APPEND and lseek(). Robert Dewar argues, rightly, for surveying the vendors to see the degree of implementation approaches. At the same time, it is appropriate in an issue like this to survey users, too. Thus a message to comp.lang.ada and/or TeamAda that asks people about what they expect when they use Append_Mode would seem to me to be appropriate. Personally, I've never thought about the interactions between Append_Mode and file positioning, because my expected use for Append_Mode has always been for "write-only" files (e.g. logfiles), where file seeking makes no application-level sense. dave **************************************************************** From: Robert Dewar[SMTP:dewar@gnat.com] Sent: Friday, April 10, 1998 9:31 AM Subject: Re: last message of Baker/Dewar exchange <> We can get any answer we like here: What do you think Append_File should do? Most people will simply answer that it should start writing at the end of the file. Do you think Append_File should map to the Unix append mode? Most people will simply answer yes. <> So for you, the obvious implementation which Ted rejects would be fine. The issue is the following. Suppose you open a file in append mode and write some stuff Then suppose you do a positioning operation. Ted thinks it is fine to reject all positioning operations. Robert thinks it is easy enough to implement them, so you should. Ted doesn't like Robert's implementation because it involves closing and opening the file, he prefers to be able to completely forbid the positioning. The trouble is that the RM absolutely clearly and unambiguously, and intentionally, allows positioning and append_file mode to be combined. What Ted (and Dave perhaps) are recommending is that implementations be free to say "I could implement that, in a manner consistent with Ada semantics, but I don't think it's a good idea, and I would never use it, so I am not going to implement it." That's a heavy burden to support! **************************************************************** From: Robert Dewar[SMTP:dewar@gnat.com] Sent: Friday, April 10, 1998 9:34 AM Subject: Re: last message of Baker/Dewar exchange <> But appending only had to do with the initial position, as Ada is defined. Yes, you are certainly not appending in the Unix sense, but you know that, because the Unix sense of appending would not have allowed you to position. Actually I think one sense in which positioning and append are perfectly compatible from a conceptual point of view is if you are allowed to position, but only at or after the original append point. I hoped to be able to read this permission into the RM, since it seems to make a lot more sense, but in fact I concluded that it was absolutely clear that the RM requires you to be able to position behind the starting position, which I agree is bogus. I really think it would be useful to know what other compilers are currently doing, can we have some data on this please? **************************************************************** From: Robert I. Eachus[SMTP:eachus@mitre.org] Sent: Friday, April 10, 1998 10:40 AM Subject: Re: AI95-00085 At 09:30 AM 4/10/98 -0400, Robert Dewar wrote: > Indeed, there is an implementation that wants to negate the standard by > raising Use_Error for all uses of positioning when Append_File is used. > > We object because it is perfectly possible, even on Unix, and even if you > use the Unix append mode, to support positioning (by reopening the file). > > But the suggestion that ALL implementations be required to raise Use_Error > (your suggestion) is way out of line. Can we all agree to this? It allows both sides to go away happy. Yes, it does require a bit of extra work if the implementation chooses to make use of O_APPEND. And, yes, there are cases where the reopening can be detected or will fail. But it preserves the current RM semantics, and will allow implementations (including GNAT) to use O_APPEND if they choose to. A little more on what happens with the reopen. It is perfectly reasonable for an implementation (IMHO) to raise Use_Error in some cases (see A.12.1(33)) --repositioning on a pipe for example. But in general, an implementation must support repositioning on a stream connected to a "real" disk file, no matter what mode it was originally opened in. And there some are anomalies that should be left as implementation defined. (For example, if the file is deleted by one task while a second task is writing to the associated stream.) Robert I. Eachus with Standard_Disclaimer; use Standard_Disclaimer; function Message (Text: in Clever_Ideas) return Better_Ideas is... **************************************************************** From: Pascal Leroy[SMTP:phl@Rational.Com] Sent: Tuesday, April 14, 1998 6:15 AM Subject: Re: copy of Baker/Dewar exchange > By the way, what does the ANSI C standard have to say about appending > exactly, can someone provide the quote. I think compatibility with C, > as opposed to compatibility with Unix, always provides a stronger > form of the compatibility argument. The only interesting thing that I could find in the ANSI C RM is this: <<7.9.7.3 The fputc function If the file cannot support positioning requests, or if the stream was opened with append mode, the character is appended to the output stream.>> This is rather terse, but still much more precise than RM95 A.12. To summarize the ANSI C semantics is as follows: Positioning is supported for files opened in append mode (except of course for some special files, in an implementation-dependent manner). Positioning is in fact _useful_ if the file is opened in a+ or ab+ mode (reading and appending) because you can go back to some earlier location in the file, and start reading from there. However, each time you _write_ to the file, you go to the end. As already noted, it is rather unfortunate that Ada doesn't have read+write or read+append modes. If we wanted to mimic the C semantics, we would have to decide that Set_Index moves the index (and does not raise an exception); and that the next Write moves to the end of file no matter what. (I am not saying that we should do that, btw.) Pascal _____________________________________________________________________ Pascal Leroy +33.1.30.12.09.68 pleroy@rational.com +33.1.30.12.09.66 FAX **************************************************************** From: Robert Dewar[SMTP:dewar@gnat.com] Sent: Tuesday, April 14, 1998 5:24 AM Subject: Re: copy of Baker/Dewar exchange So one interesting conclusion from Pascal's summary of the ANSI C semantics is that forbidding all positioning for stream files in append mode, as suggested by some, would actually *decrease* compatibility with C, interesting ... Pity no one looked at the ANSI C standard more carefully if people think that compatibility with C is so important (I don't, my feeling is that if you want compatibiliy with C, please use the C routines directly, you can still us the stream attributes, so you don't lose any expressive power). **************************************************************** From: Ted Baker[SMTP:baker@dad.cs.fsu.edu] Sent: Tuesday, April 14, 1998 7:53 AM Subject: Re: copy of Baker/Dewar exchange | So one interesting conclusion from Pascal's summary of the ANSI C semantics | is that forbidding all positioning for stream files in append mode, as | suggested by some, would actually *decrease* compatibility with C, It would be compatible. Given that you can't read from an Ada file in append mode, the only use of such files is to write. In C repositioning in append mode has no effect on subsequent writes (they still go to the end of the file), you effectively cannot reposition. Of course, I agree that it would have been nicer if we had all sensible combinations of read, write, append in Ada, but we don't. | Pity no one looked at the ANSI C standard more carefully if people think | that compatibility with C is so important (I don't, my feeling is that | if you want compatibiliy with C, please use the C routines directly, | you can still us the stream attributes, so you don't lose any expressive | power). Admittedly, the only way to get true C compabibility. --Ted ****************************************************************