From: ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe)
Newsgroups: comp.lang.c
Subject: Re: Giles' Manual Mania (Was - Re: About the 'F' in RTFM)
Date: 9 Sep 92 04:27:35 GMT
Organization: Comp Sci, RMIT, Melbourne, Australia

In article <1992Sep8.183712.18867@newshost.lanl.gov>, jlg@cochiti.lanl.gov (Jim Giles) writes:
> Another example was the loss of files in Scope which you didn't 
> explicitly save.  Well, the conventional method in UNIX for temporary 
> files is to create a file (while opening it), destroy the file, but 
> keep it open (so there's still a link).  This will automatically 
> destroy the file when the process terminates - and there's nothing 
> you can do to save it!  Since this is the conventional UNIX `idiom',
> I've lost countless files this way - even when the process terminated
> abnormally (ie. when you want *all* context saved so that you can
> try to diagnose the problem).

It is a _possible_ way of making temporary files under UNIX.
But it is very far from being the conventional way.
Indeed, I wish more programs did it.
For example, the news program that I am using right at the moment
has made a temporary file called /tmp/post013174 for this message.
The conventional way of making a temporary file under UNIX is to
use
	/* ANSI C; UNIX System V; not older BSD */

	char *tmpnam(char *buffer);
	    /* uses P_tmpdir // unique-string */

	/* UNIX System V; not older BSD; not ANSI C */

	char *tempnam(char *directory, char *prefix);
	    /* if $TMPDIR is defined in the environment, use that; else
	       if directory is non-NULL and ok, use that; else
	       if P_tmpdir is usable, use that; else
	       use /tmp when all else fails.
	    */

	/* UNIX System V; BSD; not ANSI C */

	char *mktemp(char *template);
	    /* template must end with XXXXXX; overwrite that with
	       a letter and the process-ID to make a unique name
	    */

	/* UNIX BSD; not ANSI C; not UNIX System V */

	int mkstemp(char *template)
	    /* roughly equivalent to
		return open(mktemp(template),
			O_RDWR | O_CREAT | O_TRUNC, 0600);
	       Does _not_ unlink the file.
	    */

	/* ANSI C; UNIX System V; not older BSD */

	FILE *tmpfile(void);
	    /* roughly equivalent to
		p = tmpname(NULL);
		f = fopen(p, "w+b");
		if (f) unlink(p);
		return f;
	    */

There was nothing to stop BSD UNIX programmers manually calling unlink()
after opening a temporary file, but in my experience they usually forgot
to and while I have never wanted to look at the temporary files created
by a dead process I _have_ been held up because /tmp or /usr/tmp was full
of temporary files that had _not_ been deleted.

Perhaps now that tmpfile() is a required part of the ANSI C library,
more programmers will use it.  There is a practical problem with it, in
that there is no way to control which directory it will use, but of
course a general use programming language standard can't talk about
directories in any great detail.

One trap for ANSI C programmers:  tmpfile() always creates a _binary_ file.
If you want a temporary _text_ file you can of course do
fopen(tmpnam(buffer), "w+a"), but then you have to delete the file yourself,
which is more error prone.

Jim Giles has many valid points.  It is important to remember that he is
concerned with debugging programs that run for a _long_ time (even on very
fast machines), not with simple text-oriented utilities.  UNIX still shows
traces of its original uses.

-- 
You can lie with statistics ... but not to a statistician.
Newsgroups: comp.lang.c