Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C fopen fails for write with errno is 2

Tags:

c

errno

fopen

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 ?

like image 222
JPM Avatar asked Apr 01 '13 22:04

JPM


People also ask

What if fopen fails?

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]

What is use of fopen() in c language?

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.

What is fopen() function?

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.

What does fopen return if successful?

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.


4 Answers

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

  • Set errno to 0 before the call;
  • Make the call and check the value it returned to see whether it succeeded or failed; and
  • Check the value of 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;
}
like image 111
Keith Thompson Avatar answered Sep 29 '22 16:09

Keith Thompson


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.

like image 41
Johnny Mnemonic Avatar answered Sep 29 '22 15:09

Johnny Mnemonic


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).

like image 26
Jonathan Leffler Avatar answered Sep 29 '22 16:09

Jonathan Leffler


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.

like image 34
Andrey Starodubtsev Avatar answered Sep 29 '22 15:09

Andrey Starodubtsev