[net.unix-wizards] How can unlinking be postponed?

rjnoe@riccb.UUCP (Roger J. Noe) (09/06/85)

Perhaps I am misreading the manual, but I am under the impression that if
a process unlinks a file while any process has the same file open and that
is the last link to the file, then the actual removal of the file is post-
poned until the last process with the file open closes the file, either
explicitly or by exit or exec.  Yet when I try experiments with one or
more background processes and then do ls's in the foreground, I find the
file disappears immediately after one process does its unlink()!  What's
going on here?  Does the directory entry disappear immediately but not
the i-node and its associated disk space? If that's so, shouldn't any
syscall except read return an error value since the process making that
call is under the reasonable impression that the file's still there when
it isn't?  Is there no way for a file to be removed upon a process' exit?
--
"It's only by NOT taking the UNIX system seriously that I retain what
 fragments of my once considerable mental powers I still possess!"
	(apologies to Arthur Clarke)
Roger Noe			ihnp4!riccb!rjnoe

ark@alice.UucP (Andrew Koenig) (09/07/85)

> Perhaps I am misreading the manual, but I am under the impression that if
> a process unlinks a file while any process has the same file open and that
> is the last link to the file, then the actual removal of the file is post-
> poned until the last process with the file open closes the file, either
> explicitly or by exit or exec.  Yet when I try experiments with one or
> more background processes and then do ls's in the foreground, I find the
> file disappears immediately after one process does its unlink()!

No, you find that the link disappears immediately.  ls tells you about
links, not files.

> Does the directory entry disappear immediately but not
> the i-node and its associated disk space? If that's so, shouldn't any
> syscall except read return an error value since the process making that
> call is under the reasonable impression that the file's still there when
> it isn't?  Is there no way for a file to be removed upon a process' exit?

You are correct -- the directory entry disappears immediately
and the file stays around.  Thus system calls such as read, write,
fseek, and so on continue to work normally: the file is still there.
The file will go away by itself when the last process closes it
or terminates.

mjs@sfmag.UUCP (M.J.Shannon) (09/07/85)

> Perhaps I am misreading the manual, but I am under the impression that if
> a process unlinks a file while any process has the same file open and that
> is the last link to the file, then the actual removal of the file is post-
> poned until the last process with the file open closes the file, either
> explicitly or by exit or exec.  Yet when I try experiments with one or
> more background processes and then do ls's in the foreground, I find the
> file disappears immediately after one process does its unlink()!  What's
> going on here?  Does the directory entry disappear immediately but not
> the i-node and its associated disk space? If that's so, shouldn't any
> syscall except read return an error value since the process making that
> call is under the reasonable impression that the file's still there when
> it isn't?  Is there no way for a file to be removed upon a process' exit?
> --
> Roger Noe			ihnp4!riccb!rjnoe

Your surmise is correct: when the file is unlinked, its directory entry is
removed.  If the file is open, then the inode is retained until it is closed.
Depending on what kind of file it is, the process that has it open can still
read, write, lseek, fstat, ioctl, etc.  That is, any system call that requires
only a file descriptor, not a file name, may still be used successfully.  Thus,
your desire that the file will go away when the process exits is fulfilled!
(Remember that an implicit close is done on any file descriptors a process has
open at exit time.)
-- 
	Marty Shannon
UUCP:	ihnp4!attunix!mjs
Phone:	+1 (201) 522 6063
Disclaimer: I speak for no one.

gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (09/08/85)

> ...  Does the directory entry disappear immediately but not
> the i-node and its associated disk space?

Exactly.

> If that's so, shouldn't any
> syscall except read return an error value since the process making that
> call is under the reasonable impression that the file's still there when
> it isn't?

? Any meaningful system call (e.g., lseek, stat) still works.  Only
an attempt to locate the unlinked directory entry will fail.  There
is no reason to put special-case code for this into the kernel.

> Is there no way for a file to be removed upon a process' exit?

You can use onexit() if your system has it (it probably doesn't).
Any file made by tmpfile(3) will vanish upon process termination.

Thomas@uwai.UUCP (09/08/85)

First of all, one unlink()s *directory entries*, not inodes.  If the
inode pointed to by the directory entry has its link count decremented
to zero, then that inode is deallocated *as soon as* the file is no
longer open by anyone.  As long as you have the file open, you can
perform any operation on it you want that does not take a filename but
rather just a descriptor, such as lseek, read, write, close, fchmod,
etc., but not rename, access, or chmod.  Once it is closed, it is gone.  
Thus the proper way to create a file which will be removed upon the 
process's exit is:

	invent a filename
	unlink the file (in case it already exists)
	create the file (saving the file descriptor)
	unlink the file

Now only the creating process and its descendents (though inhereited
file descriptors) may access the file, and the space will be reclaimed
upon the process's exit.  Note that if someone tried to create the file
again while it was open but not in any directory, then a different file
would be created!

-- tom
-- 

Tom Christiansen
University of Wisconsin
Computer Science Systems Lab 
...!{allegra,heurikon,ihnp4,seismo,uwm-evax}!uwvax!tom
tom@wisc-ai.arpa

chris@umcp-cs.UUCP (Chris Torek) (09/09/85)

To give people another reason not to unlink open files (besides
that it does, er, ``interesting'' things under NFS [it *does*
work, I'm told]), consider the following:

	multi 1000 </usr/dict/words >/tmp/file1

(multi is a program that makes N copies of its input; here N is 1000)
Now suppose /tmp runs out of space.  You can:

	rm /tmp/file1		# oops, file didn't actually go away
	ps ax			# find the "multi" process
	kill <pid>		# get rid of it

or you can

	cp /dev/null /tmp/file1	# now have some time to fix things up

Bending the example a bit, suppose that /tmp runs out of file space
and there are a bunch of unlinked-but-open files.  To get rid of
the space these occupy, you must kill the processes holding them
open.  However, if there are ordinary files, you can just trim them
down to zero bytes.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@maryland

alan@drivax.UUCP (Alan Fargusson) (09/10/85)

> Perhaps I am misreading the manual, but I am under the impression that if
> a process unlinks a file while any process has the same file open and that
> is the last link to the file, then the actual removal of the file is post-
> poned until the last process with the file open closes the file, either
> explicitly or by exit or exec.  Yet when I try experiments with one or
> more background processes and then do ls's in the foreground, I find the
> file disappears immediately after one process does its unlink()!  What's
> going on here?  Does the directory entry disappear immediately but not
> the i-node and its associated disk space? If that's so, shouldn't any
> syscall except read return an error value since the process making that
> call is under the reasonable impression that the file's still there when
> it isn't?  Is there no way for a file to be removed upon a process' exit?

When a file is unlinked while a process has it open then the name is removed
from the directory, but the contents of the file are not released until the
file is closed. All syscalls work correctly because they use information
from the inode. The directory entry is only used by open.
-- 

Alan Fargusson.

{ ihnp4, amdahl, mot }!drivax!alan