[comp.unix.wizards] unlink safe before close?

rk@unify.UUCP (Ron Kuris) (05/07/89)

I heard from someone in our organization that the following code
was non-portable.  Does anyone know of some machines were it does
not work?  Obviously MS/DOS will fail (but who cares?).

The intent is to create a temporary file that noone else
can conflict with, and is automatically removed when the program
terminates (either normally or abnormally):

main()
{
    int fd;
    if ((fd = creat("/tmp/who-cares", 0600)) < 0)
	{
	/* failure code... */
	}
    unlink("/tmp/who-cares");
    /* initialize some-stuff and some-size here with whatever */
    write(fd, some-stuff, some-size);
    /* do whatever else you want with the fd: reads, writes, etc */
    .
    .
    .
    /* finally just exit which closes and cleans up everything */
    exit(0);
}

Note that if a core occurs somewhere in the . . . area, the file will
automatically be erased.  I think this is pretty peachy :-).

Comments?
-- 
Ron Kuris		(916) 920-9092
rk@unify.UUCP
{{ucdavis,csun,lll-crg}!csusac,pyramid,sequent}!unify!rk

harrison@utfyzx.uucp (David Harrison) (05/07/89)

In article <755@unify.UUCP> rk@unify.UUCP (Ron Kuris) writes:
>I heard from someone in our organization that the following code
>was non-portable.  Does anyone know of some machines were it does
>not work?  Obviously MS/DOS will fail (but who cares?).
> ...
>    if ((fd = creat("/tmp/who-cares", 0600)) < 0)
>	...
>    unlink("/tmp/who-cares");
>	...
>    /* finally just exit which closes and cleans up everything */
>    exit(0);

This *should* work on all UNIX systems, so far as I know. It is a
standard trick to automagically remove tmp files when the process
dies.
I also know for a fact that it does *not* work on an HP9000 Series 
500 running HP-UX (System V.2), a fact which has pained me for a 
number of years.  
So, your colleague is correct.  Whether or not the discontinued
HP9000s500 is alone is this particular brain-damage you may be
finding out from your posting.
-- 
David Harrison                            | "God does not play dice with
Dept. of Physics, Univ of Toronto         |  the universe." -- Einstein
UUCP: uunet!attcan!utgpu!utfyzx!harrison  | "Quit telling God what to
BITNET: HARRISON@UTORPHYS                 |  do." -- Neils Bohr

bernsten@phoenix.Princeton.EDU (Dan Bernstein) (05/08/89)

In article <755@unify.UUCP> rk@unify.UUCP (Ron Kuris) writes:
  [is it nonportable to unlink an fd and still use it?]

According to various UNIX standards and according to the internal
workings of the ``standard'' kernel routines (see, e.g., Bach),
it is perfectly safe. A file is removed when it is fully unlink()ed
*and* fully close()d; link() and unlink() do not affect file behavior
after an open().

> The intent is to create a temporary file that noone else
> can conflict with, and is automatically removed when the program
> terminates (either normally or abnormally):

Almost, but not quite. Before the creat(), the only way that someone
else can conflict with your operations is by guessing your filename;
this is reasonably easy to deal with. After the unlink(), no other
process (other than later children) can do anything to the file,
*as long as it has no remaining links*. That last assertion is the
tricky part; if someone makes an extra link to your file between
creat() and unlink(), then the file will still have the new link
and won't disappear after your close(). You can detect this situation,
but curing it is very difficult: there is no way to find the new link,
let alone to remove it if its directory is unwritable! A sufficiently
determined user can start filling the filesystem with your old files
in this manner.

Although creat()-unlink() is the closest we have right know to a
real fdopen(char *directory), it does not exactly do the job from
a security viewpoint. (By the way, fdopen() must take an argument
to determine the appropriate filesystem; I think a directory should
be specified and require write permission, so that users can't
fill up filesystems with fdopen() that they can't fill up otherwise.)

---Dan Bernstein, bernsten@phoenix.princeton.edu

rand@mks.UUCP (Randall Howard) (05/09/89)

Of course any SVID/POSIX compliant system where unlink before close
is dangerous is just plain buggy.  However, in the real world, systems
like MS-DOS and OS/2 corrupt the file system or give errors, respectively
in this case.  As a result, and in the interests of maximal portability
it is always a good idea to close files before unlinking.

-- 
     ll  // // ,~/~~\'   Randall Howard
    /ll/// //l' `\\\     Mortice Kern Systems Inc.
   / l //_// ll\___/     35 King Street North, Waterloo, ON, Canada N2J 2W9
O_/                      519/884-2251, FAX 519/884-8861, uunet!watmath!mks!rand

kent@ssbell.UUCP (Kent Landfield) (05/09/89)

In article <910@mks.UUCP> rand@mks.UUCP (Randall Howard) writes:
>Of course any SVID/POSIX compliant system where unlink before close
>is dangerous is just plain buggy.  However, in the real world, systems
>like MS-DOS and OS/2 corrupt the file system or give errors, respectively
>in this case.  As a result, and in the interests of maximal portability
>it is always a good idea to close files before unlinking.

The original question was specifically targeted towards creating
temporary files on UNIX machines. The rest of the world is targeting
compliance with 1003.1 POSIX. That should be your guide to portability.
If the "real world systems" do not comply with the standard, they should
be fixed. BTW, FYI, word has it that Bill Gates was claiming MS was
going to make OS/2 1003.1 compliant for government procurements real 
soon...

Now if you want to talk about "Real systems"..... :-)
		
		-Kent+
---
Kent Landfield               UUCP:     kent@ssbell
Sterling Software FSG/IMD    INTERNET: kent%ssbell.uucp@uunet.uu.net
1404 Ft. Crook Rd. South     Phone:    (402) 291-8300 
Bellevue, NE. 68005-2969     FAX:      (402) 291-4362

les@chinet.chi.il.us (Leslie Mikesell) (05/09/89)

In article <8201@phoenix.Princeton.EDU> bernsten@phoenix.Princeton.EDU (Dan Bernstein) writes:
>  [is it nonportable to unlink an fd and still use it?]

>According to various UNIX standards and according to the internal
>workings of the ``standard'' kernel routines (see, e.g., Bach),
>it is perfectly safe. A file is removed when it is fully unlink()ed
>*and* fully close()d; link() and unlink() do not affect file behavior
>after an open().

Note that this does not apply to NFS file systems.  The "stateless"
nature of the protocol precludes the server from knowing that a
client thinks it still has the file open.


Les Mikesell

ed@mtxinu.COM (Ed Gould) (05/10/89)

Regarding unlinking open files and continuing to use the descriptor:

>Note that this does not apply to NFS file systems.  The "stateless"
>nature of the protocol precludes the server from knowing that a
>client thinks it still has the file open.

In a strict sense, this is true.  But, there were enough programs
doing exactly this (e.g., the C compiler) that Sun considered the
consequenses too severe.  So they developed a work-around that
covers the typical case.  When a process unlinks a file that it
has open, the *client* system notices this, and instead of sending
an unlink request to the server, it sends a rename.  The new name is
structured according to a well-defined convention that will make it
unique.  The client then removes this file when the process closes
the descriptor.

This is *not* a general solution to the problem of removing open
files.  It is a work-around that solves the most common (and
arguably the only "correct") use of this semantic.

-- 
Ed Gould                    mt Xinu, 2560 Ninth St., Berkeley, CA  94710  USA
ed@mtxinu.COM		    +1 415 644 0146

"I'll fight them as a woman, not a lady.  I'll fight them as an engineer."

jc@minya.UUCP (John Chambers) (05/16/89)

In article <910@mks.UUCP>, rand@mks.UUCP (Randall Howard) writes:
> Of course any SVID/POSIX compliant system where unlink before close
> is dangerous is just plain buggy.  However, in the real world, systems
> like MS-DOS and OS/2 corrupt the file system or give errors, respectively
> in this case.  As a result, and in the interests of maximal portability
> it is always a good idea to close files before unlinking.

Well, nobody has pointed it out, so I guess the duty falls on me (;-) to
add Sun's NFS to the list of file systems where this doesn't work.  But
then, Sun doesn't claim that NFS is SVID- or BSD-compliant, even when used 
on a set of Sun workstations.

This one I learned the hard way.  You wouldn't believe how long it can
take to track down a bug caused by a "feature" like this that *usually*
works.  Well, maybe you would.  This is comp.unix.wizards, after all.


-- 
John Chambers <{adelie,ima,mit-eddie}!minya!{jc,root}> (617/484-6393)

[Any errors in the above are due to failures in the logic of the keyboard,
not in the fingers that did the typing.]

allbery@ncoast.ORG (Brandon S. Allbery) (05/22/89)

As quoted from <139@minya.UUCP> by jc@minya.UUCP (John Chambers):
+---------------
| works.  Well, maybe you would.  This is comp.unix.wizards, after all.
+---------------

It is?  After reading message after message after ... about how to remove a
file name starting with "-", I begin to wonder.  :-(

++Brandon
-- 
Brandon S. Allbery, moderator of comp.sources.misc	     allbery@ncoast.org
uunet!hal.cwru.edu!ncoast!allbery		    ncoast!allbery@hal.cwru.edu
      Send comp.sources.misc submissions to comp-sources-misc@<backbone>
NCoast Public Access UN*X - (216) 781-6201, 300/1200/2400 baud, login: makeuser

rml@hpfcdc.HP.COM (Bob Lenk) (05/25/89)

In article <1989May7.053222.21348@utfyzx.uucp> harrison@utfyzx.uucp
(David Harrison) writes:

> This *should* work on all UNIX systems, so far as I know. It is a
> standard trick to automagically remove tmp files when the process
> dies.
> I also know for a fact that it does *not* work on an HP9000 Series 
> 500 running HP-UX (System V.2), a fact which has pained me for a 
> number of years.  

What precisely is it that you find doesn't work about this on HP-UX
on the series 500?  An open file can be unlinked, the file descriptor
remains valid and usable, and the file is actually removed when there
are no longer any links or open file descriptors referring to it - just
like on any other implementation of UN*X.

		Bob Lenk
		hplabs!hpfcla!rml
		rml@hpfcla.hp.com