Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #59850 > unrolled thread
| Started by | pozz <pozzugno@gmail.com> |
|---|---|
| First post | 2015-04-09 07:22 +0200 |
| Last post | 2015-04-10 14:48 +0100 |
| Articles | 10 — 9 participants |
Back to article view | Back to comp.lang.c
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
| From | pozz <pozzugno@gmail.com> |
|---|---|
| Date | 2015-04-09 07:22 +0200 |
| Subject | How 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]
| From | Robert Wessel <robertwessel2@yahoo.com> |
|---|---|
| Date | 2015-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-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]
| From | Greg Martin <greg.at.softsprocket@dot.com> |
|---|---|
| Date | 2015-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]
| From | Michael Angelo Ravera <maravera@prodigy.net> |
|---|---|
| Date | 2015-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]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2015-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-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]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2015-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]
| From | Nobody <nobody@nowhere.invalid> |
|---|---|
| Date | 2015-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