I do not understand why this is seemingly failing with errno of 2:
char debugText [256];
sprintf (debugText, "C:\\List.txt");
dfile = fopen( debugText, "w");
fprintf ( dfile, " err %d \n", errno);
I say seemingly because while dfile is NULL the file gets created and is filled with my output.
so what is going on ?
The fopen() function will fail if: [EACCES] Search permission is denied on a component of the path prefix, or the file exists and the permissions specified by mode are denied, or the file does not exist and write permission is denied for the parent directory of the file to be created. [EINTR]
The fopen() method in C is a library function that is used to open a file to perform various operations which include reading, writing etc. along with various modes. If the file exists then the particular file is opened else a new file is created.
The fopen() function opens the file specified by filename and associates a stream with it. The mode variable is a character string specifying the type of access requested for the file. The mode variable contains one positional parameter followed by optional keyword parameters.
Upon successful completion, fopen() returns a pointer to the object controlling the stream. Otherwise, a null pointer is returned, and errno is set to indicate the error.
All this tells you is that errno
had the value 2 after your fopen
call. You don't know that the call failed, because you didn't check whether dfile == NULL
. If the output was actually written to the file, presumably the fopen
call succeeded and the errno
value was left over from some previous call, likely one you didn't make explicitly.
Failing calls can set errno
to some non-zero value, but successful calls don't set errno
to 0. To check for errors, you need to
errno
to 0 before the call;errno
after the call -- but only if you know it failed (otherwise the value of errno
is meaningless).If defile == NULL
, then the fprintf
call has undefined behavior; it will probably fail.
On the other hand, you say that dfile
is NULL
. How do you know that? Your code doesn't check it. (If the fopen
call really did fail, could the contents of C:\List.txt
be left over from a previous run of your program?)
What output do you get from this program?
#include <stdio.h>
#include <errno.h>
int main(void) {
char debugText [256];
FILE *dfile;
sprintf (debugText, "C:\\List.txt");
dfile = fopen( debugText, "w");
if (dfile == NULL) {
printf("fopen failed, errno = %d\n", errno);
}
else {
printf("fopen succeeded\n");
}
return 0;
}
2 ENOENT No such file or directory. A component of a specified pathname
did not exist, or the pathname was an empty string.
Here is a list of the error codes:
http://www.thegeekstuff.com/2010/10/linux-error-codes/
But you should check if fopen()
returned NULL
first because this value in errno
might be left over from something else.
No library function ever sets errno
to zero.
You should only check errno
after a function reports an error.
For example, your code should be:
if ((dfile = fopen(debugText, "w")) == 0)
...then fopen() failed and errno is relevant...
If the function does not report failure, the value in errno
may be anything. For example, on Solaris, you often end up with errno
set to ENOTTY
after a successful operation, because stdout
is not connected to a terminal. It doesn't mean anything actually went wrong; it just means that a test for whether standard output is a terminal failed (because it isn't a terminal).
In my case I got errno == 2
while trying to open file for writing on mounted flash drive with FAT file system; it turns out that if file doesn't comply with 8.3 rule, fopen
returns NULL
and sets errno
to ENOENT
.
It's necessary to say though, that I came across this situation on embedded system, and it shouldn't be the issue on Windows.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With