0

I can't understand what's wrong with the following code. I perform exactly the same actions twice. It works for the first time, and fails for the second.

  1. open FD
  2. duplicate to stdin.
  3. close stdin
  4. close the original fd

At the second time I get an error, at stage 4, which means the FD is already closed.

  int fd =open("/path/to/some/file",0,"r");
  if (dup2(fd,STDIN_FILENO)<0)
    perror("dup_in");
  if (close(STDIN_FILENO)<0)
    perror("close_in");
  if (close(fd)<0)
    perror("close_fd");

  //Up to here it works fine.

  fd =open("/path/to/some/file",0,"r");
  if (dup2(fd,STDIN_FILENO)<0)
    perror("dup_in2");
  if (close(STDIN_FILENO)<0)
    perror("close_in2");
  if (close(fd)<0) //<-- ERROR!
    perror("close_fd2"); //<--close_fd2: Bad file descriptor
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Tzafrir
  • 639
  • 8
  • 15
  • 1
    The [`dup2`](http://man7.org/linux/man-pages/man2/dup2.2.html) call closes the current destination file descriptor, so when you close `STDIN_FILENO` you close the duplicate you just made. – Some programmer dude Mar 31 '15 at 11:38
  • Whether `fd ` is opened in the first instance?. Check for the value – Nerdy Mar 31 '15 at 11:38
  • 2
    Possibly related to your problem, you *really* need to read [the `open` manual page](http://man7.org/linux/man-pages/man2/open.2.html), because you're not using it correctly. In fact the compiler should complain about those calls, and if not then add the flag `-Wall` to enable more warnings. – Some programmer dude Mar 31 '15 at 11:39
  • Joachim - dup2 duplicate the fd to a new fd. Meaning I have to close original and the new one when I finish. What is wrong with this use of open? – Tzafrir Mar 31 '15 at 11:48

1 Answers1

3

As per the man page

int dup2(int oldfd, int newfd);

If oldfd is a valid file descriptor, and newfd has the same value as oldfd, then dup2() does nothing, and returns newfd.

So, in your second case, open() uses the least available FD, 0 [free'd by last call to close()]. That's how oldFD and newFD becomes the same, creating the error.

Note: Before using the fd returned by open(), you should always verify the sucess of open() call.

Community
  • 1
  • 1
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • Thank You! My original problem was with FD created by socket accept call. For which I don't see in the man page that is uses the lowest available FD (but after checking it is the same problem). – Tzafrir Mar 31 '15 at 11:51