[comp.unix.admin] How determine if a file is opened by another process

andrew@calvin.doc.ca (Andrew Patrick) (01/30/91)

In article <1488@nixsin.UUCP> koerber.sin@nixdorf.com writes:

>I want to find out, whether any process has opened a file, of which I only
>have the filename (or the inode, and the fs). The process that might have
>opened it need not be related to mine. I want to find out whether I can
>delete the file, without creating a still existing, unref'd file, which might
>grow without me knowing which file it is. I looked through inode.h and ino.h,
>but found no pointer to this.
>
>Could anyone pls give me a hint ?. Maybe it's in a table in the kernel ?

I need to know this too!

I just got the following question from one of my users:

    I need to know if there's a standard, *safe* way for a process to
    find out if some other process (any other process on the machine)
    has a specific file open at the time of the query.

    The other process is one I have no control over, and will be writing
    the file, assuming that no-one else is interested in it.  I can't
    change this other process, but I need to know when it's done writing
    the file.  It's a report-writer, and as soon as it has closed the
    file, it'll forget about it and I can do what I have to.  But I have
    to be sure that it is done writing the file before I touch it.  Any
    ideas?

    Oh yes.  The machine is an Encore Multimax 520, running UMax V (a
    System V based UNIX-alike).  I do know about the dodge of reading
    /dev/kmem, and the Multimax has a special call to get the address of
    the inode table, to make it a little safer, but I'd like to avoid
    this.  The program which needs this info would then have to be
    setuid root, or /dev/kmem would have to be opened for general read
    access, which we want to avoid if at all possible.
 
Any ideas?  


-- 
Andrew Patrick, Ph.D.       Department of Communications, Ottawa, CANADA
andrew@calvin.doc.CA
                    "The interface IS the program."

rrandall@zach.fit.edu (Rick Randall) (01/31/91)

In article <1991Jan29.204403.6071@rick.doc.ca> andrew@calvin.doc.ca (Andrew Patrick) writes:
>In article <1488@nixsin.UUCP> koerber.sin@nixdorf.com writes:
>
>>I want to find out, whether any process has opened a file, of which I only
>>Could anyone pls give me a hint ?. Maybe it's in a table in the kernel ?
>
>I need to know this too!
>

	ANSWER:  man fuser


			-------------------------
			| Rick G. Randall	|
			| rrandall@zach.fit.edu |
			-------------------------

clewis@ferret.ocunix.on.ca (Chris Lewis) (01/31/91)

In article <1991Jan29.204403.6071@rick.doc.ca> andrew@calvin.doc.ca (Andrew Patrick) writes:
>In article <1488@nixsin.UUCP> koerber.sin@nixdorf.com writes:

>>I want to find out, whether any process has opened a file, of which I only
>>have the filename (or the inode, and the fs). The process that might have
>>opened it need not be related to mine. I want to find out whether I can
>>delete the file, without creating a still existing, unref'd file, which might
>>grow without me knowing which file it is. I looked through inode.h and ino.h,
>>but found no pointer to this.

>>Could anyone pls give me a hint ?. Maybe it's in a table in the kernel ?

You don't really want to do that.  Though, might be able to do this with
"crash" or "pstat" if your system has either one.  But if the process isn't
related to yours, the O/S probably won't allow you to look at it.  Looking
thru /dev/kmem via the namelist is of course possible, but extremely
O/S specific and has to be done as root.  You would look via the inode
in the inode table and look for the reference count to go to zero (or
the inode disappear from the inode table).  This is a variation of how
fuser might be implemented on a given machine.

>I need to know this too!

>I just got the following question from one of my users:

|    I need to know if there's a standard, *safe* way for a process to
|    find out if some other process (any other process on the machine)
|    has a specific file open at the time of the query.

This is sort of gross, but I would imagine that this would work on
most versions of UNIX.  I'm not sure whether this would work across
a network though.  Do something like:
    
    struct stat stb;
    stat(<filename>, &stb);
    oldmtime = stb.st_mtime;
    while(1) {
	sleep(5);
	stat(<filename>, &stb);
	if (oldmtime == stb.st_mtime)
	    break;
	oldmtime = stb.st_mtime;
    }

This will loop waiting for the file to stop being written to.  You
might have to up the sleep time to something more substantial (on the order
of minutes) to ensure that you don't fall thru simply because the process
got swapped out or stopped printing for a while.  But I think it might
work well enough for your purposes.  This of course won't work for
a file that's open for reading.

As far as worrying about removing the file whilst it's being written to,
I wouldn't worry too much - the file will disappear once the process
closes the file (or dies).  If it doesn't die, you have a different problem.
-- 
Chris Lewis, Phone: (613) 832-0541, Internet: clewis@ferret.ocunix.on.ca
UUCP: uunet!mitel!cunews!latour!ecicrl!clewis
Moderator of the Ferret Mailing List (ferret-request@eci386)
Psroff enquiries: psroff-request@eci386, current patchlevel is *7*.

mike (Michael Stefanik) (01/31/91)

In an article, calvin.doc.ca!andrew (Andrew Patrick) writes:
>I need to know if there's a standard, *safe* way for a process to
>find out if some other process (any other process on the machine)
>has a specific file open at the time of the query. [...]
>Oh yes.  The machine is an Encore Multimax 520, running UMax V (a
>System V based UNIX-alike).  I do know about the dodge of reading
>/dev/kmem, and the Multimax has a special call to get the address of
>the inode table, to make it a little safer, but I'd like to avoid
>this.  The program which needs this info would then have to be
>setuid root, or /dev/kmem would have to be opened for general read
>access, which we want to avoid if at all possible.

There is no portable way to get the information that you want; poking
through the kernel is the only way I know of determining if some
unrelated and/or non-cooperative process has a file open.  If you're worried
about security issues (as well you should be), then one solution would
be to write a SUID daemon that, when prodded, will dump this information
into shared memory.  Thus, the program itself need not be running in a
privileged state.

However, the point remains, any mucking about such as this is inherently
non-portable.
-- 
Michael Stefanik                       | Opinions stated are not even my own.
Systems Engineer, Briareus Corporation | UUCP: ...!uunet!bria!mike
-------------------------------------------------------------------------------
technoignorami (tek'no-ig'no-ram`i) a group of individuals that are constantly
found to be saying things like "Well, it works on my DOS machine ..."

cjr@ssi.UUCP (Cris J. Rhea) (01/31/91)

See the System V command "fuser".  Although you do have to be root 
or have permissions on /dev/mem.....

--- Cris