From: Ludwigi Beethoven Date: 2003-07-27T00:27:42+09:00 Subject: Re: Confused about locking a file via file.flock(File::LOCK_EX) --- Brian Candler wrote: > On Sat, Jul 26, 2003 at 08:57:00PM +0900, Ludwigi > Beethoven wrote: > > I guess I would have to grab the file and update > it > > rather quickly, and hope that nobody else is > updating > > it at the same time via some other way. > > The requirement was to prevent another user editing > the same file with 'vi', > right? > > On my system (FreeBSD), if I edit a file with vi, > then try to edit the same > file in vi in another window, I get: > > /etc/motd already locked, session is read-only. > /etc/motd: unmodified, readonly: line 1 > > This implies that there is some sort of locking > going on. > > Now, if I run this test program: > > def testlock(filename) > f = File.open(filename) > f.flock(File::LOCK_EX) > sleep 30 > f.close > end > testlock("/etc/motd") > > then vi /etc/motd also reports that the file is > locked. Is that not the case > for you? > > If not, then the "update it rather quickly and hope" > is most safely done by: > - creating a copy of the file with a different name > and modified contents > - doing a 'rename' operation to replace the original > file with it > > This is an atomic operation - it will either succeed > or fail. Of course > someone else who has it open in a buffer could > overwrite it again, but at > least it will always be a complete and valid file, > not corrupted by two > people writing to it simultaneously. > > Regards, > > Brian. > Well, I am using AIX version 4. I tried a similar test and I was able to change and save /etc/hosts. Perhaps there is a difference right there between AIX and FreeBSD. As a matter of facts, I will attach below a copy of the program that I am writing. Perhaps someone can make suggestions. The program will provide remote printing support to a Windows/98 ws with a printer attached to it, managed by a lpd server. The user comes in via a VPN that provides a different IP address with every connection. That's the reason to update the /etc/hosts table. If anyone knows an off the shelv software that will do this then I will recommend that to the client. Althoug it is more fun to write it myself as I learn ruby. Of course I am not providing ALL the details, such us the AIX printer config, which I think is irrelevant at this point. For the UDP part I used a piece of code from "The Ruby Way". Thank you Here is the ruby code: require "socket" log="/tmp/udpsrv.log" begin out = File.new(log, "a") rescue => e puts "Problem with I/O operation: #{e}" exit 1 else time = Time.now time1 = time.strftime("%a%b%d%Y %H:%M:%S") out.puts time1 + " " + $0 + " Started Executing..." PORT = 12321 time = Time.now time1 = time.strftime("%a%b%d%Y %H:%M:%S") out.puts time1 + " Listening on port: " + PORT.to_s server = UDPSocket.open # Using UDP here... server.bind("cwsa", PORT) out.close loop do puts "Waiting for requests" out = File.new(log, "a") time = Time.now time1 = time.strftime("%a%b%d%Y %H:%M:%S") out.puts time1 + " Wait for requests." text, sender = server.recvfrom(64) time = Time.now time1 = time.strftime("%a%b%d%Y %H:%M:%S") out.puts time1 + " Client domain: " + sender[0].to_s out.puts time1 + " Client port: " + sender[1].to_s out.puts time1 + " Client host: " + sender[2].to_s out.puts time1 + " Client IP adddress: " + sender[3].to_s out.puts time1 + " Client requests: " + text.to_s system("rm /tmp/newhosts 1>/dev/null 2>&1") # Remove old file function, printer = text.chomp.split if function.include?("Enable") # Replace old definition from /etc/hosts table entry for this printer fileArr = IO.readlines("/tmp/hosts") f = File.new("/tmp/newhosts", "w+") index = 0 found = false fileArr.each do |line| if line.include?("VPNTEST") fileArr[index] = sender[3].to_s + " " + "VPNTEST" found = true break end index += 1 end # End of do loop if !found # Add to end of hosts file, if it was not found f.close # Firts close file entry = sender[3].to_s + " " + "VPNTEST" #system("echo #{entry} >> /tmp/hosts") system("mv /tmp/hosts /etc/hosts") # UNCOMMENT else # Re-write hosts file back with the change IP address f.puts fileArr f.close #system("mv /tmp/newhosts /tmp/hosts") system("mv /tmp/newhosts /etc/hosts") end system("enable VPNTEST >>/tmp/dpsrv.log 2>>/tmp/udpsrv.log") else if function.include?("Disable") system("disable VPNTEST >>/tmp/dpsrv.log 2>>/tmp/udpsrv.log") else out.puts time1 + " Request " + text.to_s + " ignored." end end out.close end end __________________________________ Do you Yahoo!? Yahoo! SiteBuilder - Free, easy-to-use web site design software http://sitebuilder.yahoo.com