[net.unix-wizards] /tmp versus temporary file types

mouse@mcgill-vision.UUCP (der Mouse) (09/03/85)

[paraphrasing]
> ....like to see some discussion on: /tmp.
> ....anybody can 'rm /tmp/*', read files there, etc....

Anyone can rm /tmp/*, true.  Read on.
Anyone can read files there only if the program which creates them gives
them  a mode which allows  read  access.   Usually if you umask  007  or
anything ending in a 7 then world cannot access to files you create.

     When I write something which wants a temporary  file I do something
like this:

	/* generate temporary filename via mktemp() or some such */
	/* temporary filename in tmpfn */
	unlink(tempfn); /* in case a file by that name already exists */
	fd = open(tempfn,O_CREAT|O_TRUNC|O_RDWR,0644);
	/* O_RDWR and 0644 are variable depending on the application */
	unlink(tempfn);
	/* now the temporary file sticks around on disk as long as I have */
	/* it open, but is COMPLETELY inaccessible except to this process */
	/* and any children I fork */

     Granted, this does not work  when  you want another program to read
the file by name.    Just another reason to  make  everything work as  a
filter  (:-).  This sort of code has proven useful  in several  programs
which  merely want someplace  to  put huge (>  max  malloc()able  space)
amounts of temporary data.
-- 
					der Mouse

{ihnp4,decvax,akgua,etc}!utcsri!mcgill-vision!mouse
philabs!micomvax!musocs!mcgill-vision!mouse

Hacker: One responsible for destroying /
Wizard: One responsible for recovering it afterward

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

The unlink/open/unlink trick is neat, but as network file systems
crop up it is starting to turn into something really nasty.  As
you may know, Sun's NFS is (mostly) stateless, and stateless file
systems and open-but-gone files don't coexist very well.

Whether this means that statelessness is bad, or that using unnamed
files is bad, I do not care to debate at this time.
-- 
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

cudcv@daisy.warwick.UUCP (Rob McMahon) (10/10/85)

In article <136@mcgill-vision.UUCP> mouse@mcgill-vision.UUCP (der Mouse) writes:
>> ....like to see some discussion on: /tmp.
>> ....anybody can 'rm /tmp/*', read files there, etc....
>
>	unlink(tempfn); /* in case a file by that name already exists */
>	fd = open(tempfn,O_CREAT|O_TRUNC|O_RDWR,0644);
>	/* O_RDWR and 0644 are variable depending on the application */
>	unlink(tempfn);

I have always felt this was a mess.  How about an O_TEMP option to open, so
that you can do something like

        fd = open(dirname, O_TEMP);

to atomically create and unlink a file on the same filesystem as dirname if
the user has write permission to the directory dirname.  This would save
having to guess a unique name, checking to see if the name already existed,
leaving files around if the program or system crashed between the open and the
unlink, people accidentally removing other peoples temporary files (I get
people coming to me saying "but I didn't think the system would let me remove
other peoples files", having destroyed half a dozen peoples long troff jobs
running in the background).

A new system call

        flink(fd, name, mode) char *name;

would be useful too, so that a link could be created for an open temporary
file.  This would save file transfer programs, for example, having to create a
temporary file on the same file system, which it leaves around if it fails (or
worse yet overwrite the existing file before it knows whether the transfer
will succeed.  Daemons wouldn't have to create files tf... and change them to
cf... later.

Doesn't this seem like a cleaner way of working ?  I look at my /tmp
filesystem which is normally 2% full, but occasionally overflows with
disasterous consequences, and I cringe.  Maybe we could do away with those
        find /tmp -mtime +1 -exec rm -f {} \;
things in /etc/rc and crontab ?  Any thoughts ...

Rob McMahon, Computer Unit, Warwick University, Coventry, England
UUCP: ..!mcvax!ukc!warwick!cudcv

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

Funny, Fred and I were talking about flink() and open(O_TEMP) mode
just last week....

There are some problems.  Flink is easy, but O_TEMP is not; not
really.  Basically, O_TEMP wants to open an unnamed file:  to get
an inode on some device, but to leave its link count zero.  So for
an O_TEMP open you do not care at all about the file name.  Why,
then, should you have to specify it?  Well, you *do* care (presumably)
about the device from which the inode is taken.  After all, you
are (most likely) going to flink the inode to a name once the file
is built.  But the device is normally just a part of the file name,
and deduced by namei as mounted file systems are encountered in
the path name.

Fred suggested completely ignoring the `name' argument to open if
you are using O_TEMP, and using u.u_cdir to get the device for the
new inode.  This seems a bit kludgy but would probably work.

If you instead use the pathname to find the device, you run into
a different problem:  what if the named file exists?  Namei currently
will return the inode for that file.  So you must also kludge namei
to ignore the last file name argument.  Somehow, this does not
`feel' like the right solution either.

Any suggestions?  DMR, are you listening?
-- 
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@mimsy.umd.edu

dave@uwvax.UUCP (Dave Cohrs) (10/15/85)

> If you instead use the pathname to find the device, you run into
> a different problem:  what if the named file exists?  Namei currently
> will return the inode for that file.  So you must also kludge namei
> to ignore the last file name argument.  Somehow, this does not
> `feel' like the right solution either.

How about requiring that a file opened O_TEMP not exist.  If the file
exists, you can't really make it temporary (well, you could, but it feels
wrong).

-- 
Dave Cohrs
(608) 262-1204
...!{harvard,ihnp4,seismo,topaz}!uwvax!dave
dave@wisc-romano.arpa

root%bostonu.csnet@CSNET-RELAY.ARPA (BostonU SysMgr) (10/16/85)

Just a design note: On our IBM system files are named on CLOSE rather
than open (better put, *can* be named on close rather than open.)
This leads one into a call sequence like:

	fd = open(NULL,O_CREAT...) ;
	...write to it...
	close(fd,filename) ;

besides tmp files it just generally guarantees that programs which
for some reason, um, er, abend, and don't want things left around
can have that (if you think about it, it's an easier way to handle
a user ^C'ing a program, besides just providing a way to create
temporary files, now one generally has to provide a signal handler
that tries to carefully undo things on ^C, one assumes that any
exit that tries to close an unnamed file without giving it a name
will cause the file to disappear.

If you think about it, that's actually a lot closer to the 4.2 socket
design (this has nothing whatsoever to do with the current STREAMS/SOCKET
discussions),  a cleaner way to implement the above might be:

	fd = socket(AF_UNIX,SOCK_FILE,..)

At this point, in this domain, writing would be legal, so would reading
back after a seek, it would behave like a new file.
then at some point where maybe it shouldn't be deleted but you are not
ready to close yet:

	bind(fd,filename,..)

and finally

	close(fd)

One suspects that if the first method (close(fd,fname)) were offered
then a need would arise to make a file have a name without having
to close it (remember all those close(creat(fname,mode)) ; fd=open(...);
code sequences so you could get a new r/w/seekable file!)

Just trying to pull together several ideas.

Ok, that settled, onwards to picking funny characters for the
shell to interpret as DISP=(NEW,KEEP,DELETE) :-)

	-Barry Shein, Boston University

hmm, we could make 'dd' a builtin and add a few new keywords...nahhh

levy@ttrdc.UUCP (Daniel R. Levy) (10/17/85)

In article <2152@brl-tgr.ARPA>, root%bostonu.csnet@CSNET-RELAY.ARPA (BostonU SysMgr) writes:
>Just trying to pull together several ideas.
>
>Ok, that settled, onwards to picking funny characters for the
>shell to interpret as DISP=(NEW,KEEP,DELETE) :-)
>
>	-Barry Shein, Boston University
>
>hmm, we could make 'dd' a builtin and add a few new keywords...nahhh

hmm, we already have a c shell, now a f77 shell? :-)
-- 
 -------------------------------    Disclaimer:  The views contained herein are
|       dan levy | yvel nad      |  my own and are not at all those of my em-
|         an engihacker @        |  ployer or the administrator of any computer
| at&t computer systems division |  upon which I may hack.
|        skokie, illinois        |
 --------------------------------   Path: ..!ihnp4!ttrdc!levy

arnold@gatech.CSNET (Arnold Robbins) (10/21/85)

Here's my two cents worth (I'm a little behind in my Unix-wizards, if some one
else has beat me to the idea, I apologize).

Why not do something like

	fd = open ("/dev/temp", O_RDWR);
	/* O_CREAT implied by the use of /dev/temp */

The kernel just grabs a fresh inode off whatever device /tmp is mounted on,
or the "temp device" could be a configurable parameter in the same way that
the swap device is. Then flink() or whatever ought to work properly as well.

In other words, /dev/null is the null device, /dev/swap the swap device, so
why not a /dev/temp for temporary files?
-- 
Arnold Robbins
CSNET:	arnold@gatech	ARPA:	arnold%gatech.csnet@csnet-relay.arpa
UUCP:	{ akgua, allegra, hplabs, ihnp4, seismo, ut-sally }!gatech!arnold

Hello. You have reached the Coalition to Eliminate Answering Machines.
Unfortunately, no one can come to the phone right now....

peter@graffiti.UUCP (Peter da Silva) (10/22/85)

> 
> Just a design note: On our IBM system files are named on CLOSE rather
> than open...
> ...
> besides tmp files it just generally guarantees that programs which
> for some reason, um, er, abend, and don't want things left around
> can have that...

But the usual case where you *do* want to keep the file around dies
horribly if you do this. Remember that one of the *nice* features of
UNIX files is that they are always "closed" from the outside. You can
always look at the output of a long-running background job without
bending over backwards...

	% nroff -ms huge_file > huge_file.out &
	% ...wait a while, maybe doing other things...
	% tail huge_file.out
	...whatever the output is, so long as it's reasonable...
	% ...and repeat...

boyd@basser.oz (Boyd Roberts) (10/22/85)

  In article <1622@gatech.CSNET> arnold@gatech.CSNET (Arnold Robbins) writes:
  >Why not do something like
  >
  >	fd = open ("/dev/temp", O_RDWR);
  >	/* O_CREAT implied by the use of /dev/temp */
  >
  >The kernel just grabs a fresh inode off whatever device /tmp is mounted on,
  >or the "temp device" could be a configurable parameter in the same way that
  >the swap device is. Then flink() or whatever ought to work properly as well.

Yes, that's the way.  Re-define the semantics of the system calls because
you want dodgy feature X.  The UNIX file-system is clean and straight forward.
So too are the system calls.  But, oh no, instead of using the interfaces
provided it's time to mash them into five zillion different flavours, with
no gain in functionality.

How about a "/dev/dir" for directories, "/dev/pipe" for pipes, "/dev/link"
for links?  And, of course, depending on the file type change the semantics
of the system calls.  Add fchdir().

Be real.  Write a function to provide the interface you want, using the
interfaces provided.  Give a programmer a job, but *DON'T* bust the kernel!


Boyd Roberts			...!seismo!munnari!basser.oz!boyd

Anw%maths.nottingham.ac.uk@UCL-CS.ARPA (10/23/85)

boyd@basser.oz (Boyd Roberts) writes:
> In article <1622@gatech.CSNET> arnold@gatech.CSNET (Arnold Robbins) writes:
> >Why not do something like
> >
> >	fd = open ("/dev/temp", O_RDWR);
> >	/* O_CREAT implied by the use of /dev/temp */
> >
> > [...]
>Yes, that's the way.  Re-define the semantics of the system calls because
>you want dodgy feature X.  The UNIX file-system is clean and straight forward.
>So too are the system calls.  But, oh no, instead of using the interfaces
>provided it's time to mash them into five zillion different flavours, with
>no gain in functionality.  [...]

	Ouch!  But the system calls are not all THAT clean and s-f.  Why does
the ownership & mode of "fred" after 'creat ("fred", 0644);' depend on whether
"fred" existed before?  Why is "fred" opened for writing as well?  Why, in
standard V7 at least, can I not shorten a file, or open one by an existing
descriptor?  There is scope for making several of the system calls more
orthogonal and more primitive, were it not for the dead hand of tradition.

	There IS a minor lack of functionality which would be cured by some
form of anonymous or temporary file, and which is exemplified by the common
and not entirely satisfactory sequence

		s = mktemp ("/tmp/eXXXXXX");
		close (creat (s, 0600));
		fd = open (s, 2);
		unlink (s);

	Here's my 2p-worth.  Why not use an explicitly null file name to
indicate an anonymous file (with no links) in the implied directory?  Thus,

		fd = open ("/tmp/", 2);

(simply) would be equivalent to the above.  'open ("", 2)' would do it in
the current directory instead.  (At least, how often has anyone used null
file names in anger?  Hands up anyone who is not slightly surprised by the
behaviour of "mv junk ''", or of "date > ''".)	  No doubt some guru will
suggest a clean way round the obvious problem with "/" (but the name of the
root directory is already anomalous, and a counterexample to the c&sf-ness
of the file system).

	-- Andy Walker, Maths Dept, Nottingham Univ
		anw@UK.AC.Nott.Maths

gwyn@BRL.ARPA (VLD/VMB) (10/24/85)

A null path component already has a meaning (same as ".").
On System V, the whole pathname cannot be null, however.

root%bostonu.csnet@CSNET-RELAY.ARPA (BostonU SysMgr) (10/24/85)

>From: peter@graffiti.UUCP (Peter da Silva)
>> 
>> Just a design note: On our IBM system files are named on CLOSE rather
>> than open...
>> ...
>> besides tmp files it just generally guarantees that programs which
>> for some reason, um, er, abend, and don't want things left around
>> can have that...

>But the usual case where you *do* want to keep the file around dies
>horribly if you do this...

Re-read the note, by my suggestion you would only get an unnamed file which
disappears on abend if you explicitly called open(NULL,mode);, or something
like that (the design problem with that is which device to put the unnamed
file on tho I guess something could be done like it always is on /tmp
wherever that is.) In the case you mention of the shell redirection one
assumes it is not being called with NULL so it has no effect on that. There
is a slight problem still if you were debugging, say, the C compiler and
really wanted to abort it leaving the temps around, tho there are obviously
better ways to accomplish the same effect.

--While we are on the subject, a quick opinion--

There have been notes in this list suggesting new features to UNIX,
typically at the system call level.
There have been notes in this list rejecting new features either
specifically or in general.

The notes which reject them in general are fairly useless I believe,
unless you consider UNIX to be completely finished.

The notes which reject things in specific are valuable, that is discussion.
(like Peter's note above, I just think he misunderstood my suggestion,
probably my fault.)

A paradox of UNIX has been to maintain great portability/compatibility with
itself over time while adapting to changing needs. Would the person who
screamed about features remove, say, TCP/IP from 4.2? I doubt it, except
as a wholly selfish exercise. On the other hand, being very suspicious of
any new proposed feature is quite a reasonable attitude in my opinion,
but the specifics should be dealt with to have useful discussion.

As far as it relates to this /tmp business, we are discussing a security and
integrity problem (I started this discussion) which is very visible,
obviously we have lived this long w/o a solution, but I suspect we have paid
intermittently with problems for administrators. It is also a very realistic
criticism when, for example, choosing UNIX for a student environment
(*my* real world, which probably involves more $$ and people than many who
claim some monopoly on what the *real* world is -- side flame, sorry.)

We can live w/o this solution, maybe there just is no good solution in
general, but we can't live with an attitude that nothing should ever change
as some have proposed to this list. That would be suicide.

	-Barry Shein, Boston University

Anw%maths.nottingham.ac.uk@UCL-CS.ARPA (10/24/85)

> A null path component already has a meaning (same as ".").
	Well, yes, more-or-less;  "the null file name refers to the current
directory" [The UNIX Time-Sharing System], and repeated slashes are ignored,
but (a) is this anything but a kludge so that "/" works? and (b) apart from
"/", has anyone ever used this facility in real-life?

	V7 (but not some other systems) even allows "fred///" as a synonym
for "fred" (an ordinary file);  I can see no reason why this, and "///tmp//"
and so on, should not be errors.

mike@whuxl.UUCP (BALDWIN) (10/26/85)

> As far as it relates to this /tmp business, we are discussing a security and
> integrity problem (I started this discussion) which is very visible,
> obviously we have lived this long w/o a solution, but I suspect we have paid
> intermittently with problems for administrators. It is also a very realistic
> criticism when, for example, choosing UNIX for a student environment
> (*my* real world, which probably involves more $$ and people than many who
> claim some monopoly on what the *real* world is -- side flame, sorry.)
> 
> We can live w/o this solution, maybe there just is no good solution in
> general, but we can't live with an attitude that nothing should ever change
> as some have proposed to this list. That would be suicide.

I agree with your last paragraph completely!  So how about this solution
that's already been done in 2.8BSD:  sticky dirs.  The problem is: /tmp
has to allow anyone to create files in it, but in standard UNIX, if you
can create a file, you can remove it too (write perm on dir).  You need
to give anyone the ability to create files, but only to remove their own.
BSD overloaded the sticky bit on dirs to mean:  in unlink(2), if the parent
has the sticky bit (t) set, only unlink if you OWN the file or the directory
(of course, you have to have write perms in the parent as always).  This is
an amazingly trivial change, and perms on dirs are different anyway (e.g.,
x means search).  It also seems to solve the /tmp problem.  To get a secure
tmp file, do open("/tmp/blat", O_CREAT|O_EXCL, 0600).  The file is completely
safe.  Is this an acceptable fix, or am I missing something?
-- 
						Michael Baldwin
						{at&t}!whuxl!mike