473,769 Members | 6,538 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Checking if a file exists

Is this a good way to check wheter a file already exists?

#include <stdio.h>
#include <stdlib.h>
int ask(const char *prompt);
typedef char filename[FILENAME_MAX];

int main(int argc, char *argv[])
{
FILE *in, *out;
filename in_name, out_name;
int overwrite = 0;
/* get filenames */
out = fopen(out_name, "r")
if (out != NULL) {
fclose(out);
printf("File %s already exists. ", out_name);
if (ask("Do you want to overwrite it?") == 1)
overwrite++;
else
exit(EXIT_FAILU RE);
}
/* etc... */
}

--
#include <stdio.h>
#include <stdlib.h>
int main(void) /* Don't try this at home */ {
const size_t dim = 256; int i;
for (i=0; malloc(dim); i++) /*nothing*/ ;
printf("You're done! %zu\n", i*dim);
puts("\n\n--Army1987"); return 0;
}
Apr 7 '07
26 4957
"Richard Heathfield" <rj*@see.sig.in validha scritto nel messaggio
news:E4******** *************** *******@bt.com. ..
Army1987 said:

<snip>
>Now if it is possible that out = fopen(out_name, "r"); fclose(out);
deletes the file, I'd better find another way...

Well, I wouldn't expect that to happen! But I would not be surprised by
the following sequence of events:

1) you open the file read-only
2) you close the file
3) another process deletes the file
4) you act on your belief that the file exists

Multi-user / multi-process systems can be tricky, can't they?
Probably, in this very case it wouldn't harm so much, because I meant to do
something like:

#include <stdio.h>
#include <stdlib.h>
int ask(const char *prompt);
typedef char filename[FILENAME_MAX];

int main(int argc, char *argv[])
{
char *name;
FILE *in, *out;
filename in_name, out_name;
int overwrite = 0;
/* get filenames */
in = fopen(in_name, "r");
if (in == NULL) {
perror("Unable to read from file");
exit(EXIT_FAILU RE);
out = fopen(out_name, "r");
if (out != NULL) {
fclose(out);
printf("File %s already exists. ", out_name);
if (ask("Do you want to overwrite it?") == 1)
overwrite++;
else
exit(EXIT_FAILU RE);
}
name = overwrite ? tmpnam(NULL) : out;
out = fopen(name, "w");
if (out == NULL) {
fclose(in);
perror(overwrit e ? "Unable to create temporary file"
: "Unable to create destination file");
exit(EXIT_FAILU RE);
}
/* do stuff */
fclose(in);
if (fclose(out)) {
perror(overwrit e ? "Unable to close temporary file"
: "Unable to close destination file");
exit(EXIT_FAILU RE);
}
if (overwrite) {
if (remove(in_name )) {
perror("Unable to overwrite destination file");
fprintf("The temporary file is available as %s", name);
exit(EXIT_FAILU RE);
}
if (rename(name, in_name)) {
perror("Unable to rename temporary file");
fprintf("The temporary file is available as %s", name);
exit(EXIT_FAILU RE);
}
}
return EXIT_SUCCESS; /* Finally... */
}
(The actual error messages are just examples, I would use fprintf so to
include filenames.)
The very worst thing that could happen is that the destination filename
would have a wrong, temporary name, which the user would know so to rename
it by hand... or is it?
Apr 8 '07 #11
"Army1987" <pl********@for .itha scritto nel messaggio
news:ev******** **@tdi.cu.mi.it ...
fprintf("The temporary file is available as %s", name);
Sorry. I meant:
fprintf(stderr, ...);
Apr 8 '07 #12
"Army1987" <pl********@for .itwrites:
"Keith Thompson" <ks***@mib.orgh a scritto nel messaggio
news:ln******** ****@nuthaus.mi b.org...
>"Army1987" <pl********@for .itwrites:
>>Is this a good way to check wheter a file already exists?
[snip]

Testing whether a file exists often (not always, but often) means
you're asking the wrong question.

Why do you want to know whether the file exists? If it's so you can
decide whether to attempt some operation (e.g., reading from the file
if it does exist, or creating it if it doesn't), it's often better to
just go ahead and attempt the operation, and handle the error if it
fails.

7.19.5.3.3 says that fopen(name, "w") "truncate[s] to zero length or
create[s] text file for writing".
Simply opening the file for writing loses its contents if it already exists.
Thus "often" rather than "always". See also Jens's followup about "a"
(append) mode.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Apr 8 '07 #13
>"Richard Heathfield" <rj*@see.sig.in validha scritto nel messaggio
>news:E4******* *************** ********@bt.com ...
>... I would not be surprised by the following sequence of events:

1) you open the file read-only
2) you close the file
3) another process deletes the file
4) you act on your belief that the file exists

Multi-user / multi-process systems can be tricky, can't they?
In article <ev**********@t di.cu.mi.it>, Army1987 <pl********@for .itwrote:
>Probably, in this very case it wouldn't harm so much ... [code snipped]
>The very worst thing that could happen is that the destination filename
would have a wrong, temporary name, which the user would know so to rename
it by hand... or is it?
There is definitely something worse that could happen. Richard
Heathfield's example covers a case like:

fp = fopen(name, "r");
if (fp != NULL) {
fclose(fp);
/* allow time to pass */

fp = fopen(name, "r");
/* assumption here: fp != NULL */
}

Your code (which I snipped), however, has a case more like this:

fp = fopen(name, "r");
if (fp != NULL) {
fclose(fp);
/* allow time to pass */
...
} else {
--- fp = fopen(name, "w");
...
}

Now, at the line I marked with an arrow "--->", you assume that
since fopen-for-reading returned NULL, the file does not exist (or,
as you noted elsewhere, that it has bizarre permissions, in which
case the user is shooting himself in the foot and there may not be
much we can do about it anyway).

The more serious problem -- and one which occurs in real-world
security holes on these multi-user, multi-process systems that
Richard Heathfield mentioned -- occurs when enough time passes
between the first fopen (with "r") and the second (with "w") so
that the file, which *did not exist* at the time of the first
fopen(), *does* exist at the time of the second.

In particular, consider, on a Unix-like system, what happens if
you "race" your program against another one that does:

/* evilprogram.c */
#include <unistd.h/* yes, non-ANSI */

#define sensitive_file "/home/user/very_important_ data"
#define name "whatever"

int main(void) {
for (;;) {
(void) unlink(name);
usleep(1);
(void) symlink(sensiti ve_file, name);
sleep(1);
}
/*NOTREACHED*/
}

Now, if "evilprogra m" runs at the right (wrong?) time while it
races against your program, your code will do:

fp = fopen(name, "r");

and get NULL, because the file named "whatever" does not exist.
Then evilprogram runs and creates the symlink, so that the file
named "whatever" refers to your "very_important _data" file (or,
in the case of the security holes I mentioned earlier, perhaps
something like "/etc/passwd"). Since, in your code, fp==NULL,
you assume that the file named "whatever" *still* does not
exist, and you do:

fp = fopen(name, "w");

and are now overwriting your very important data (or /etc/passwd,
if running as root, e.g.).

(This problem existed before symlinks: since typical systems at
the time had /etc and /tmp on the same file system, one could make
a hard link from /etc/passwd to /tmp/foo and trick a setuid-root
program into writing on /tmp/foo, which was by then actually
/etc/passwd. The solution is to avoid the C library routines,
which are insufficient, and go directly to open() -- and, in the
case of setuid programs, to use the original 4.3BSD setreuid() or
the more modern POSIX-style saved-setuid -- not the original,
broken, System V version, which did not work for the super-user --
to "give up" setuid permissions temporarily. Fundamentally, what
is needed is an atomic "test all permissions and, only if OK, then
do the open" call. This just does not exist in Standard C.)

There really are times one can, and even should, write non-Standard-C
code. The trick is knowing when. :-)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Apr 8 '07 #14
"Army1987" <pl********@for .itwrote:

# Now if it is possible that out = fopen(out_name, "r"); fclose(out); deletes
# the file, I'd better find another way...

<stdio.his sort of greatest common factor programming
amongst all possible C implementation. It's grossly unsuitable
for detailed I/O provided on various systems, by design.

You can beat your head against a wall or decide that you don't
want to program on all possible systems, just a subset. At that
point you can depend on other standards like SVID, and you get
additional operations which can do exactly this.

For example if you're willing to restrict yourself to Unix
and perhaps a few other systems, you can do an open(2) with
O_EXCL followed by an fdopen(3). I'm sure VMS also provides
this functionality in a completely different manner. Mac
System 7 also provided this functionality (preserved in Carbon),
again in completely different manner.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
God's a skeeball fanatic.
Apr 8 '07 #15
SM Ryan said:
"Army1987" <pl********@for .itwrote:

# Now if it is possible that out = fopen(out_name, "r"); fclose(out);
# deletes the file, I'd better find another way...

<stdio.his sort of greatest common factor programming
amongst all possible C implementation. It's grossly unsuitable
for detailed I/O provided on various systems, by design.
How are you going to do I/O /without/ it, in a portable manner?
You can beat your head against a wall or decide that you don't
want to program on all possible systems, just a subset.
Which subset?
At that
point you can depend on other standards like SVID,
Is that available for *all* possible subsets of all possible systems?
and you get
additional operations which can do exactly this.

For example if you're willing to restrict yourself to Unix
....you can use comp.unix.progr ammer. That's what it's for.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Apr 8 '07 #16
Richard Heathfield <rj*@see.sig.in validwrote:

# How are you going to do I/O /without/ it, in a portable manner?

I'm not part of your inbred clique.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
A bunch of savages in this town.
Apr 8 '07 #17
On Sun, 8 Apr 2007 16:09:22 +0200, "Army1987" <pl********@for .it>
wrote:
>"Richard Heathfield" <rj*@see.sig.in validha scritto nel messaggio
news:E4******* *************** ********@bt.com ...
>Army1987 said:

<snip>
>>Now if it is possible that out = fopen(out_name, "r"); fclose(out);
deletes the file, I'd better find another way...

Well, I wouldn't expect that to happen! But I would not be surprised by
the following sequence of events:

1) you open the file read-only
2) you close the file
3) another process deletes the file
4) you act on your belief that the file exists

Multi-user / multi-process systems can be tricky, can't they?

Probably, in this very case it wouldn't harm so much, because I meant to do
something like:

#include <stdio.h>
#include <stdlib.h>
int ask(const char *prompt);
typedef char filename[FILENAME_MAX];

int main(int argc, char *argv[])
{
char *name;
FILE *in, *out;
filename in_name, out_name;
int overwrite = 0;
/* get filenames */
in = fopen(in_name, "r");
if (in == NULL) {
perror("Unable to read from file");
exit(EXIT_FAILU RE);
out = fopen(out_name, "r");
if (out != NULL) {
fclose(out);
printf("File %s already exists. ", out_name);
if (ask("Do you want to overwrite it?") == 1)
overwrite++;
else
exit(EXIT_FAILU RE);
}
name = overwrite ? tmpnam(NULL) : out;
I assume you meant out_name here.

Isn't the test backwards?
out = fopen(name, "w");
if (out == NULL) {
fclose(in);
perror(overwrit e ? "Unable to create temporary file"
: "Unable to create destination file");
exit(EXIT_FAILU RE);
}
/* do stuff */
fclose(in);
if (fclose(out)) {
perror(overwrit e ? "Unable to close temporary file"
: "Unable to close destination file");
exit(EXIT_FAILU RE);
}
if (overwrite) {
if (remove(in_name )) {
Didn't you mean out_name throughout this overwrite logic?
perror("Unable to overwrite destination file");
fprintf("The temporary file is available as %s", name);
exit(EXIT_FAILU RE);
}
if (rename(name, in_name)) {
perror("Unable to rename temporary file");
fprintf("The temporary file is available as %s", name);
exit(EXIT_FAILU RE);
}
}
return EXIT_SUCCESS; /* Finally... */
}
(The actual error messages are just examples, I would use fprintf so to
include filenames.)
The very worst thing that could happen is that the destination filename
would have a wrong, temporary name, which the user would know so to rename
it by hand... or is it?

Remove del for email
Apr 8 '07 #18
SM Ryan said:
Richard Heathfield <rj*@see.sig.in validwrote:

# How are you going to do I/O /without/ it, in a portable manner?

I'm not part of your inbred clique.
Neither am I. But I note that you avoid the question instead of
answering it.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Apr 9 '07 #19
"Richard Heathfield" <rj*@see.sig.in validha scritto nel messaggio
news:AJ******** *************** *******@bt.com. ..
How are you going to do I/O /without/ it, in a portable manner?
<ot>
Not portable everywhere, but
#include <stdlib.h>
#include <string.h>
#define MAX 4090
int main(void)
{
char cmd[MAX+6] = "echo ";
system(strncat( cmd, "Hello, World!", MAX));
return 0;
}
should work on several systems. Input is trickier... :-) </ot>
Apr 10 '07 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
1756
by: Phil Lamey | last post by:
Hi Folks, I have run into a bit of an issue with checking for files. Some files reside on Server X and some on Server Y. The page with all the links is on Server X. If the file exists we display a link, if it does not then we display "sorry not yet available". For the files on server X it is no problem I use an FSO and don't have a problem. For files on server Y I am having a big problem.
15
114212
by: Geiregat Jonas | last post by:
is using if(open("file",O_EXCL) != -1){ printf("File does exists")}else{printf("file does not exists"); } a good way of checking if a file exists or not, if not how should I do it ?
11
16846
by: Daz | last post by:
Would anyone know of a way to check whether or not a particular path is a directory? If I have to go down the route of using _findfirst and _findnext (windows specific), then so be it. However, I don't think it should be that difficult to check. My original idea was to check to see if the path can be opened with fstream, but this can give false results if the path is a filename, and the file cannot be opened. I am using boost, and can't...
13
24195
by: darkslide | last post by:
Hi, I'm checking if a file exists with the following code; If System.IO.File.Exists("C:\test.txt") = True Then MsgBox("File Exists") Else MsgBox("File Does Not Exist") End If For some reason it always returns false even though the file does exist. Any suggestions? Could this be a security issue?
7
19117
by: sprash | last post by:
Newbie question: I'm trying to determine if a file physically exists regardless of the permissions on it Using File.Exists() returns false if it physically exists but the process does not have the necessary permissions. One hack could be to check for length and that would throw a FileNotFoundException ...but there is got to be a better way!
1
2933
by: mengesb | last post by:
I'm looking to utilize something to the effect of this code: ps -ef | grep sc_serv | grep -v grep | awk '{print $2}' > sc_serv.pid cat sc_serv.pid 3447 3449 The first id it spits out is the screen process that I run the sc_serv command under, and that's fine, because killing that process is really what I want. Killing the second will just produce nothing. What I'd really like is for when this system boots up, it will check for the...
1
3238
by: timexsinclair2068 | last post by:
This is a very simple question. Is there a simple,short way of checking if the application's App.Config file exists? Thanks!
4
2686
by: winningElevent | last post by:
Hi everyone, I have a question would like to ask. So far I know how to retrieve files from device, but sometimes device takes so long to produce file so I want my desktop to keep checking every 3seconds to see if file exist. Here is the conditions. 1- if file exists after checking for exisitng is True, then desktop application will continue to do other stuff. 2- if file doesn't exist after three times of checking, then desktop sends...
4
14994
by: ndedhia1 | last post by:
Hi. I am writing a java program in which I want to ftp a file to another unix box. First I have to check if the directory exists in which I am ftping into and if it does not exist, I have to create it: this is the code that I am using that is not working properly: System.out.println("YOU ARE IN UPLOAD"); System.out.println("THIS IS THE HOST: " + host); SshClient ssh = new SshClient();
0
9589
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9423
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10219
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10049
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9998
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
1
7413
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6675
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5448
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
2815
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.