Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #59850 > unrolled thread

How to use a temporary file in a portable way

Started bypozz <pozzugno@gmail.com>
First post2015-04-09 07:22 +0200
Last post2015-04-10 14:48 +0100
Articles 10 — 9 participants

Back to article view | Back to comp.lang.c


Contents

  How to use a temporary file in a portable way pozz <pozzugno@gmail.com> - 2015-04-09 07:22 +0200
    Re: How to use a temporary file in a portable way Robert Wessel <robertwessel2@yahoo.com> - 2015-04-09 02:15 -0500
    Re: How to use a temporary file in a portable way Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-04-09 11:00 +0100
    Re: How to use a temporary file in a portable way James Kuyper <jameskuyper@verizon.net> - 2015-04-09 08:42 -0400
    Re: How to use a temporary file in a portable way Greg Martin <greg.at.softsprocket@dot.com> - 2015-04-09 15:47 +0000
      Re: How to use a temporary file in a portable way Michael Angelo Ravera <maravera@prodigy.net> - 2015-04-09 14:52 -0700
    Re: How to use a temporary file in a portable way Richard Damon <Richard@Damon-Family.org> - 2015-04-09 23:43 -0400
      Re: How to use a temporary file in a portable way Keith Thompson <kst-u@mib.org> - 2015-04-10 08:29 -0700
        Re: How to use a temporary file in a portable way Richard Damon <Richard@Damon-Family.org> - 2015-04-10 22:31 -0400
    Re: How to use a temporary file in a portable way Nobody <nobody@nowhere.invalid> - 2015-04-10 14:48 +0100

#59850 — How to use a temporary file in a portable way

Frompozz <pozzugno@gmail.com>
Date2015-04-09 07:22 +0200
SubjectHow to use a temporary file in a portable way
Message-ID<mg527d$f4p$1@dont-email.me>
I understand the more portable and secure method to change the content 
of a file is through creating a temporary file.

For example, when I need to change a CSV file, a simple configuation 
file (typical in Unix systems), a INI file (typical on Windows systems) 
and many other proprietary and standard format.

   open/create temporary file
   put the new content on temporary file
   close temporary file
   remove original file
   rename temporary file with original filename

Just to be pedantic, at the initialization of the application, I could 
check for the existence of a temporary file (in case the application 
crashed just after removing the original file and before renaming 
temporary file):

   try to open original file
   if it failes, check if temp file exists
   if yes, rename it as original filename

This method uses a temporary file.  Now the main question of this post: 
how to use (mainly create) the temporary file in a portable way?

Should I create a temporary file in the executable directory?  Or in the 
original file directory?  Or in a system-dependent (non portable) 
temporary directory?

How to choose the temporary file name?  How to face the situation when 
the temporary file name already exist?

[toc] | [next] | [standalone]


#59852

FromRobert Wessel <robertwessel2@yahoo.com>
Date2015-04-09 02:15 -0500
Message-ID<fl8ciadsv6ptc0kkluegv5ua0le51gdfq0@4ax.com>
In reply to#59850
On Thu, 09 Apr 2015 07:22:22 +0200, pozz <pozzugno@gmail.com> wrote:

>I understand the more portable and secure method to change the content 
>of a file is through creating a temporary file.
>
>For example, when I need to change a CSV file, a simple configuation 
>file (typical in Unix systems), a INI file (typical on Windows systems) 
>and many other proprietary and standard format.
>
>   open/create temporary file
>   put the new content on temporary file
>   close temporary file
>   remove original file
>   rename temporary file with original filename
>
>Just to be pedantic, at the initialization of the application, I could 
>check for the existence of a temporary file (in case the application 
>crashed just after removing the original file and before renaming 
>temporary file):
>
>   try to open original file
>   if it failes, check if temp file exists
>   if yes, rename it as original filename
>
>This method uses a temporary file.  Now the main question of this post: 
>how to use (mainly create) the temporary file in a portable way?
>
>Should I create a temporary file in the executable directory?


Most certainly not.  In general you shouldn't even have the ability to
write in that directory (sadly you often do).


>Or in the 
>original file directory?


That's the usual approach.  Typically an editor, for example, will
create a shadow file in the same directory, and then rename it after
closing it.  The usual sequence is close temp file, delete old ".bak"
if you're keeping one (or whatever the convention is on your system)
file, rename original file, rename temp file, delete original file (if
you're not keeping a backup).  The sequence you suggested is also
used.

And, BTW, it's not actually guaranteed that the rename steps will
actually work, or that it can be recovered if they don't, but the odds
are usually pretty good.  Consider, using your sequence:

 - read existing file foo.bar
 - write/close temp file foo.new
 - close foo.bar
 - delete foo.bar
 - some other process creates foo.bar
 - rename of foo.new to foo.bar fails.  Now what? 


>Or in a system-dependent (non portable) 
>temporary directory?


Since C doesn't portably deal with directories at all, that's hard.
And even if it did, on many systems you cannot arbitrarily rename
files across volumes.  So any temp directory would have to be on the
same volume as the file being edited (and, of course, there's no
portable way to determine such a thing).  Plus you run into some
security issues.

The C tmpfile() function can be useful in some instances, and it
magically takes care of the file and directory name issues, but it
doesn't really apply to this scenario.


>How to choose the temporary file name?


Use the convention for your system.  Or make one up.  A semi-random
number as part of the name is a common approach, you can then adjust
that and retry if there's a duplicate.  Often the base of the
temporary file name is the original file name.


>How to face the situation when 
>the temporary file name already exist?


Try another name.  Or fail.

IOW, there's no way to do this portably, or fully reliably.

[toc] | [prev] | [next] | [standalone]


#59858

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-04-09 11:00 +0100
Message-ID<87twwp39lp.fsf@bsb.me.uk>
In reply to#59850
pozz <pozzugno@gmail.com> writes:

> I understand the more portable and secure method to change the content
> of a file is through creating a temporary file.

You might also consider just reading the whole thing into memory.

<snip>
> [...]  Now the main question of this
> post: how to use (mainly create) the temporary file in a portable way?

Quoting from the C standard:

      FILE *tmpfile(void);

  The tmpfile function creates a temporary binary file that is different
  from any other existing file and that will automatically be removed
  when it is closed or at program termination. If the program terminates
  abnormally, whether an open temporary file is removed is
  implementation-defined. The file is opened for update with "wb+" mode.

<snip>
> How to choose the temporary file name?  How to face the situation when
> the temporary file name already exist?

      char *tmpnam(char *s);

  The tmpnam function generates a string that is a valid file name and
  that is not the same as the name of an existing file.

(again, a quote from the standard).

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#59860

FromJames Kuyper <jameskuyper@verizon.net>
Date2015-04-09 08:42 -0400
Message-ID<mg5s2f$42j$1@dont-email.me>
In reply to#59850
On 04/09/2015 01:22 AM, pozz wrote:
> I understand the more portable and secure method to change the content 
> of a file is through creating a temporary file.
> 
> For example, when I need to change a CSV file, a simple configuation 
> file (typical in Unix systems), a INI file (typical on Windows systems) 
> and many other proprietary and standard format.
> 
>    open/create temporary file
>    put the new content on temporary file
>    close temporary file
>    remove original file
>    rename temporary file with original filename
> 
> Just to be pedantic, at the initialization of the application, I could 
> check for the existence of a temporary file (in case the application 
> crashed just after removing the original file and before renaming 
> temporary file):
> 
>    try to open original file
>    if it failes, check if temp file exists
>    if yes, rename it as original filename

I'd recommend not making that automatic, but rather to have the user
confirm what to do. The file could be renamed, deleted, or left in place
for the user to examine.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#59862

FromGreg Martin <greg.at.softsprocket@dot.com>
Date2015-04-09 15:47 +0000
Message-ID<V9xVw.291113$jx4.61649@fx27.iad>
In reply to#59850
On 2015-04-09, pozz <pozzugno@gmail.com> wrote:
> I understand the more portable and secure method to change the content 
> of a file is through creating a temporary file.
>
> For example, when I need to change a CSV file, a simple configuation 
> file (typical in Unix systems), a INI file (typical on Windows systems) 
> and many other proprietary and standard format.
>
>    open/create temporary file
>    put the new content on temporary file
>    close temporary file
>    remove original file
>    rename temporary file with original filename
>
> Just to be pedantic, at the initialization of the application, I could 
> check for the existence of a temporary file (in case the application 
> crashed just after removing the original file and before renaming 
> temporary file):
>
>    try to open original file
>    if it failes, check if temp file exists
>    if yes, rename it as original filename
>
> This method uses a temporary file.  Now the main question of this post: 
> how to use (mainly create) the temporary file in a portable way?
>
> Should I create a temporary file in the executable directory?  Or in the 
> original file directory?  Or in a system-dependent (non portable) 
> temporary directory?
>
> How to choose the temporary file name?  How to face the situation when 
> the temporary file name already exist?

As has been suggested elsewhere in the thread it is simple to create a
temp file name in C but using the temp file approach you need a
method to store the filename and relate it back to the original file.
You could keep a database of files used or some such measure but that
seems fraught with issues. 

I would think your better to follow the vi model and use a set
delimiter and keep the file in the directory the original is in.

-- 
http://www.softsprocket.com

[toc] | [prev] | [next] | [standalone]


#59864

FromMichael Angelo Ravera <maravera@prodigy.net>
Date2015-04-09 14:52 -0700
Message-ID<ed837a0f-9f26-4faf-990a-51793681dd14@googlegroups.com>
In reply to#59862
On Thursday, April 9, 2015 at 8:47:11 AM UTC-7, Greg Martin wrote:
> On 2015-04-09, pozz <pozzugno@gmail.com> wrote:
> > I understand the more portable and secure method to change the content 
> > of a file is through creating a temporary file.
> >
> > For example, when I need to change a CSV file, a simple configuation 
> > file (typical in Unix systems), a INI file (typical on Windows systems) 
> > and many other proprietary and standard format.
> >
> >    open/create temporary file
> >    put the new content on temporary file
> >    close temporary file
> >    remove original file
> >    rename temporary file with original filename
> >
> > Just to be pedantic, at the initialization of the application, I could 
> > check for the existence of a temporary file (in case the application 
> > crashed just after removing the original file and before renaming 
> > temporary file):
> >
> >    try to open original file
> >    if it failes, check if temp file exists
> >    if yes, rename it as original filename
> >
> > This method uses a temporary file.  Now the main question of this post: 
> > how to use (mainly create) the temporary file in a portable way?
> >
> > Should I create a temporary file in the executable directory?  Or in the 
> > original file directory?  Or in a system-dependent (non portable) 
> > temporary directory?
> >
> > How to choose the temporary file name?  How to face the situation when 
> > the temporary file name already exist?
> 
> As has been suggested elsewhere in the thread it is simple to create a
> temp file name in C but using the temp file approach you need a
> method to store the filename and relate it back to the original file.
> You could keep a database of files used or some such measure but that
> seems fraught with issues. 
> 
> I would think your better to follow the vi model and use a set
> delimiter and keep the file in the directory the original is in.

Three-, four, or five-file rollover is a fairly common practice. You may be able to rename, but sometimes you will have to copy.

If OLD exists OLD -> ANCIENT (deleting ANCIENT, if it exists)
If CURRENT exists CURRENT -> OLD
NEW -> CURRENT
INPROGRESS -> NEW

It is only for the INPROGRESS version that you would want a temporary file.

I have written a script macro or two and lines of code that used up to 10 generations of old files. "OOOOOOOO" would be deleted so that "OOOOOOOf" could be renamed to it. "OOOOOOfi" would be renamed to "OOOOOOOf"
"OOOOOfil" would be renamed to "OOOOOOfi"
"OOOOfile" would be renamed to "OOOOOfil"
"OOOfile" would be renamed to "OOOOOfile"
"OOfile" would be renamed to "OOOfile"
"Ofile" would be renamed to "OOfile"
"file" would be renamed to "Ofile"
"Nfile" would be renamed to "file" 
"Tfile" would be renamed to "Nfile"

With more flexible file system naming, it is more common to use numerical generations (especially for the INPROGRESS files). The first thing that a program would do was to create a backup and an INPROGRESS file. INPROGRESS files often have extra space or ordering information that saved files do not.

[toc] | [prev] | [next] | [standalone]


#59866

FromRichard Damon <Richard@Damon-Family.org>
Date2015-04-09 23:43 -0400
Message-ID<UFHVw.245921$bk5.66224@fx06.iad>
In reply to#59850
On 4/9/15 1:22 AM, pozz wrote:

> How to choose the temporary file name?  How to face the situation when
> the temporary file name already exist?

Call tmpnam(). From the standard:
The tmpnam function generates a string that is a valid file name and 
that is not the same as the name of an existing file.

[toc] | [prev] | [next] | [standalone]


#59882

FromKeith Thompson <kst-u@mib.org>
Date2015-04-10 08:29 -0700
Message-ID<87d23cuhle.fsf@kst-u.example.com>
In reply to#59866
Richard Damon <Richard@Damon-Family.org> writes:
> On 4/9/15 1:22 AM, pozz wrote:
>> How to choose the temporary file name?  How to face the situation when
>> the temporary file name already exist?
>
> Call tmpnam(). From the standard:
> The tmpnam function generates a string that is a valid file name and
> that is not the same as the name of an existing file.

tmpnam() has potential problems.  The Linux man page says:

    Although tmpnam() generates names that are difficult to guess,
    it is nevertheless possible that between the time that tmpnam()
    returns a pathname, and the time that the program opens it,
    another program might create that pathname using open(2), or
    create it as a symbolic link.  This can lead to security holes.
    To avoid such possibilities, use the open(2) O_EXCL flag to
    open the pathname.  Or better yet, use mkstemp(3) or tmpfile(3).

    ...

    BUGS

       Never use this function.  Use mkstemp(3) or tmpfile(3) instead.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#59896

FromRichard Damon <Richard@Damon-Family.org>
Date2015-04-10 22:31 -0400
Message-ID<pI%Vw.287785$2j2.189745@fx23.iad>
In reply to#59882
On 4/10/15 11:29 AM, Keith Thompson wrote:
> Richard Damon <Richard@Damon-Family.org> writes:
>> On 4/9/15 1:22 AM, pozz wrote:
>>> How to choose the temporary file name?  How to face the situation when
>>> the temporary file name already exist?
>>
>> Call tmpnam(). From the standard:
>> The tmpnam function generates a string that is a valid file name and
>> that is not the same as the name of an existing file.
>
> tmpnam() has potential problems.  The Linux man page says:
>
>      Although tmpnam() generates names that are difficult to guess,
>      it is nevertheless possible that between the time that tmpnam()
>      returns a pathname, and the time that the program opens it,
>      another program might create that pathname using open(2), or
>      create it as a symbolic link.  This can lead to security holes.
>      To avoid such possibilities, use the open(2) O_EXCL flag to
>      open the pathname.  Or better yet, use mkstemp(3) or tmpfile(3).
>
>      ...
>
>      BUGS
>
>         Never use this function.  Use mkstemp(3) or tmpfile(3) instead.
>

Both of these fail the original specifications:

1) Portable
2) Get the file name

mkstemp() is a POSIX function, so if your universe of portability goes 
outside that sphere, it is not available (admittedly, portability to 
POSIX does get you a lot of machines, just not all).

tmpfile() has no way to get the name of the file if it is needed for 
other purposes.

[toc] | [prev] | [next] | [standalone]


#59880

FromNobody <nobody@nowhere.invalid>
Date2015-04-10 14:48 +0100
Message-ID<pan.2015.04.10.13.48.37.131000@nowhere.invalid>
In reply to#59850
On Thu, 09 Apr 2015 07:22:22 +0200, pozz wrote:

> I understand the more portable and secure method to change the content of
> a file is through creating a temporary file.
> 
> For example, when I need to change a CSV file, a simple configuation file
> (typical in Unix systems), a INI file (typical on Windows systems) and
> many other proprietary and standard format.
> 
>    open/create temporary file
>    put the new content on temporary file close temporary file
>    remove original file
>    rename temporary file with original filename

On Unix, you shouldn't remove the original file, but simply rename() the
new file over it. That avoids having an interval where the target file
doesn't exist. On Windows, the separate remove step is necessary, as
rename() fails if the target exists.

> Should I create a temporary file in the executable directory?  Or in the
> original file directory?  Or in a system-dependent (non portable)
> temporary directory?

The temporary file should be on the same filesystem (partition) as the
target, otherwise rename() will fail. Placing it in the same directory
ensures that this is the case.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web