From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM autolearn=unavailable autolearn_force=no version=3.4.4 X-Received: by 10.107.6.221 with SMTP id f90mr4487985ioi.13.1441137735243; Tue, 01 Sep 2015 13:02:15 -0700 (PDT) X-Received: by 10.182.112.234 with SMTP id it10mr85294obb.13.1441137735192; Tue, 01 Sep 2015 13:02:15 -0700 (PDT) Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!mx02.eternal-september.org!feeder.eternal-september.org!news.glorb.com!kq10no211134igb.0!news-out.google.com!nt1ni21499igb.0!nntp.google.com!kq10no170669igb.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Tue, 1 Sep 2015 13:02:14 -0700 (PDT) In-Reply-To: Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=50.111.117.58; posting-account=Ies7ywoAAACcdHZMiIRy0M84lcJvfxwg NNTP-Posting-Host: 50.111.117.58 References: User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: <23506b3b-57f4-4e74-947a-c0655f15d198@googlegroups.com> Subject: Re: Exclusive file access From: brbarkstrom@gmail.com Injection-Date: Tue, 01 Sep 2015 20:02:15 +0000 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Xref: news.eternal-september.org comp.lang.ada:27680 Date: 2015-09-01T13:02:14-07:00 List-Id: On Tuesday, September 1, 2015 at 10:05:42 AM UTC-4, ah...@marriott.org wrot= e: > On Thursday, August 27, 2015 at 3:52:36 PM UTC+2, ah...@marriott.org wrot= e: > > Dear All, > >=20 > > Obviously I'm misunderstanding something here. > >=20 > > I thought that if two processes tried to open the same file for write a= ccess then the second process would get an exception. > >=20 > > I have a simple example which when compiled using GnatPro 7.3.1 and run= under 32-bit Windows XP demonstrates that this is not so. > >=20 > > Which then begs the question on how to detect if the file is in use and= abort if it is. > > This should be simple but obviously too complex for my tiny brain. > > Does anyone know how to do this from Ada (without resorting to the OS d= irectly)? > >=20 > > My simple test program is > >=20 > > package body Test is > >=20 > > package Io renames Ada.Text_IO; > >=20 > > procedure Work is > > The_File : Io.File_Type; > > begin > > Io.Open (The_File, Io.Out_File, "Test.Txt"); > > for Count in Natural'value(Ada.Command_Line.Argument(1)) .. Natural= 'value(Ada.Command_Line.Argument(2)) loop > > Io.Put_Line (The_File, "Count =3D" & Count'img); > > Io.Put_Line ("Count =3D" & Count'img); > > delay 1.0; > > end loop; > > Io.Close (The_File); > > exception > > when others =3D> > > Io.Put_Line ("Exception"); > > end Work; > >=20 > > end Test; > >=20 > > If I execute this from one process with parameters 1 10 and then when i= t reaches 8 start the program again from a second process with parameters 3= 7 on the same machine, the resultant file is a nice mixture! :-( > >=20 > > Count =3D 3 > > Count =3D 4 > > Count =3D 5 > > Count =3D 6 > > Count =3D 7 > > Count =3D 6 > > Count =3D 7 > > Count =3D 8 > > Count =3D 9 > > Count =3D 10 > >=20 > > This is not what I want. I want what the first instance produces and th= e second instance to fail. Surely nobody would want otherwise ;-) > >=20 > > Best wishes, > > Ahlan >=20 > I am not trying to protect the file from other tasks I am trying to prote= ct the file from other processes - ie other programs or utilities - perhaps= executing on other computers if the file in question is on a network. I wa= nt to open the file in such a way that I am granted exclusive write access.= This has absolutely nothing to do with tasking or protected objects etc. > Bruce B. tells me that there are routines in the package Directories that= can be used to check if the file is already open. However that wouldn't be= a full solution because there would be nothing to stop any other program f= rom opening the file and messing with it. However it would be a start. If t= he file was already opened (by some other process) then I could avoid openi= ng it. Unfortunately I couldn't find any such routine in Ada.Directories. A= m I going blind? > So far the only solution I can see is for me to write my own filing syste= m, one that has the ability to open the file for exclusive file access. How= ever I cannot believe that this is what people really do. > As it stands if I write a program that writes a log to a text file a seco= nd occurrence of the program if run concurrently will mess up this log. > Is there really no way for an Gnat Ada program to open a file for exclusi= ve access against other processes without resorting to the program writing = his/her own filing system? (Open/Read/Write/Close that call directly the OS= API) My Linux version of the reference manual is a bit hard to find from my e-ma= il. The Ada-2012 version of the RM has a function Is_Open that returns a Boolea= n for each of the IO types defined in that document. For example section A.1= 0.1 has Is_Open as the first function in the description for Text_IO. I apolog= ize for not checking Ada.Directories in the RM when I posted my note earlier to= day. I'm still not sure why the alternate processes you're referring to wouldn't be Ada Tasks. In that case, the appropriate design would embed the informa= tion you want to protect into an object that forces the other tasks to wait unti= l the task accessing the file ends. If you are really running multi-language implementations, you'll probably need to uncover the code to identify which process is your Ada process and then have code that interfaces with the Ada= . If you try to run concurrent write operations to text files without using protected objects or some other form of locking, the IO buffer will certain= ly=20 get confused. As a result, the output will have a strange interleaving of= =20 characters from the different processes. This difficulty certainly makes debugging by printing lines of text more complicated. =20 McCormick, et al. have a very nice (and simple) code example for a package called "Protected_Output" that uses a pattern called a Semaphore that deals with this problem. The code is on pp. 145-146 of their book. It may be that their web site can provide the source code. After you open the site, find a tab labelled "Resources". Then choose one called "Source Code" and download the zip file. The Protected_Output code is from section 4.7 in the book. I think the driver for this code is included in the zip file. I have compiled and run this demo successfully. I strongly suggest you con= sult=20 McCormick et al. before you try writing your own file system. I do apologize for not carefully checking the RM for the proper location and name of the Is_Open function. Bruce B.