Fotinopoulos Giorgos
Fotinopoulos Giorgos

Reputation: 1027

Open system call failure

After i call open() system call as

fd = open(dir, O_RDONLY, 0);
printf("fd=%d\n", fd);
if (fd < 0)
   perror("open");

i get fd = -2 and the perror("open") prints "Success"!!!

What does this mean, and why it happens?

Ok, i decided to test my code differently, like this:

if ((fd = open(dir, O_RDONLY, 0)) >= 0) {
  /* do smthg */
}
else {
  perror("open");
  printf("fd=%d\n", fd);
}

I think that the last portion of code i suggested, doesn't conflict from the in-between functions alternation of errno's value, but i'm still getting fd=-2 (???) and perror() prints "Success".!

Upvotes: 4

Views: 7369

Answers (4)

Ken Bloom
Ken Bloom

Reputation: 58770

From the manpage for "open"

Return Value

open() and creat() return the new file descriptor, or -1 if an error occurred (in which case, errno is set appropriately).

You'll notice that -2 is not the -1 that's supposed to be returned on failure, though the manpage does also say

Given a pathname for a file, open() returns a file descriptor, a small, nonnegative integer for use in subsequent system calls

Upvotes: 1

Ken Bloom
Ken Bloom

Reputation: 58770

From the errno manpage:

A common mistake is to do

       if (somecall() == -1) {
           printf("somecall() failed\n");
           if (errno == ...) { ... }
       }

where errno no longer needs to have the value it had upon return from somecall() (i.e., it may have been changed by the printf(3)). If the value of errno should be preserved across a library call, it must be saved:

       if (somecall() == -1) {
           int errsv = errno;
           printf("somecall() failed\n");
           if (errsv == ...) { ... }
       }

Upvotes: 3

Geoff Reedy
Geoff Reedy

Reputation: 36011

The error code of the last call is stored in the errno global variable. perror uses this error code to lookup an error message string. When you get to perror("open") you are reading the error set by the call to printf. There wasn't an error printing your fd=... message so the error code is set to 0 which is Success. You should either save the error code like:

fd = open(dir, O_RDONLY, 0);
prev_error = errno;
printf("fd=%d\n", fd);
errno = prev_error;
if (fd < 0) perror("open");

or just re-order the code so that perror is called before printf.

Upvotes: 0

fpereda
fpereda

Reputation: 31

Something is resetting errno inside printf. Try commenting it out and you'll see something meaningful from perror.

Upvotes: 3

Related Questions