how to test if a file is open ?

U

Une Bévue

i'd like to know how to test if a file is open from another app ?

i've read http://www.ruby-forum.com/topic/144114

and have tested with :
ruby 1.8.7 (2008-08-11 patchlevel 72) [universal-darwin10.0]
and
MacRuby version 0.5 (ruby 1.9.0) [universal-darwin10.0, x86_64]

the following :
f = File.new("/Users/yt/dev/Signature/signatures.txt")
puts "f.flock(File::LOCK_EX) : #{f.flock(File::LOCK_EX)}"
puts "f.flock(File::LOCK_UN) : #{f.flock(File::LOCK_UN)}"
puts "f.flock(File::LOCK_EX | File::LOCK_NB) : #{f.flock(File::LOCK_EX |
File::LOCK_NB)}"

giving the same result in both cases :
f.flock(File::LOCK_EX) : 0
f.flock(File::LOCK_UN) : 0
f.flock(File::LOCK_EX | File::LOCK_NB) : 0
 
B

Brian Candler

The traditional Unix utilities to solve this problem are "lsof" and
"fuser". I don't know if OSX has either of these as standard, but they
are probably available as ports.

Locking won't help unless the other process has taken a lock on the
file.
 
G

Giampiero Zanchi

You could use exceptions
try to read from file; if it is closed, then an exception will be
raised; then you can do something, for instance set a boolean and return
it...

def is_open(a_file)
begin
...read from file...
rescue
...if file is not open then do something...
end
end
 
B

Brian Candler

Giampiero said:
You could use exceptions

I thought the OP was interested in whether *another* process had the
same file open.

If you just want to test whether a Ruby File object is closed, there is
a 'closed?' method.

irb(main):002:0> f = File.open("/etc/passwd")
=> #<File:/etc/passwd>
irb(main):003:0> f.closed?
=> false
irb(main):004:0> f.close
=> nil
irb(main):005:0> f.closed?
=> true
 
U

Une Bévue

Brian Candler said:
Or it might be "fstat", given that OSX is BSD-derived.
http://netbsd.gw.com/cgi-bin/man-cgi?fstat++NetBSD-4.0

seems fstat doesn't exists on OS X :

zsh-% which fstat
fstat not found

however lsof and fuser does exists.

then i did some experiment ))

assuming the file is opened in a text editor i get :
zsh-% fuser -fu /Users/yt/dev/Signature/signatures.txt
/Users/yt/dev/Signature/signatures.txt:

or, with lsof :
zsh-% lsof /Users/yt/dev/Signature/signatures.txt
zsh-%


i get the correct answer when the file is selected by the Finder :
with fuser :
zsh-% fuser -fu /Users/yt/dev/Signature/signatures.txt
/Users/yt/dev/Signature/signatures.txt: 106(yt)

and, with lsof :
zsh-% lsof /Users/yt/dev/Signature/signatures.txt
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
Finder 106 yt 14r REG 14,2 3082 7364119
/Users/yt/dev/Signature/signatures.txt

then, i think, may be i'm wrong, that any text editor open a file show
it and close it afterwards even the file is still visible in that text
editor where the Finder lock the file when it is selected.

then lsof nor fuser are no help in my case because i want to avoid
opening a file under editing...
 
B

Brian Candler

Une said:
then, i think, may be i'm wrong, that any text editor open a file show
it and close it afterwards even the file is still visible in that text
editor where the Finder lock the file when it is selected.

That sounds quite likely.
then lsof nor fuser are no help in my case because i want to avoid
opening a file under editing...

Then the solution depends on your editor.

For example, under Linux, if I create file foo then do "vi foo", lsof
and fuser show that foo is not open. However, a lockfile ".foo.swp" is
created, and this is what prevents another vi instance from editing it.

If I edit the file in joe, then nothing is changed until I start typing
into that window. Then it creates ".#foo" which is a symlink to the user
and the pid of the joe instance. That is: the lock is only created when
I start to modify the buffer.

So there doesn't appear to be a universal way of handling this, although
perhaps Apple prescribe a standard way for applications to adhere to.

Useful command to see if any new dot-files are created:

ls -lArt | grep ^\\.

(newest files appear at the end of the list)

HTH,

Brian.
 
U

Une Bévue

Brian Candler said:
So there doesn't appear to be a universal way of handling this, although
perhaps Apple prescribe a standard way for applications to adhere to.

Apple recommandation are, afaik, * no test * but raise an exception if
an error occurs...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top