cdup2

Why do we close the file descriptor after calling dup2?


I cannot for the life of me get my head fully around dup2().

    int fd = open("data", O_RDONLY); 
    /* open the disk file */
    int newfd = dup2(fd,0); 
    /* close 0, dup fd to 0 */
    if( newfd != 0)
    {
        fprintf(stderr,"Could not duplicate fd to 0\n");
        exit(1);
    }
    close(fd);

So I understand that dup2() in this case will close 0 (standard keyboard input for stdin), it will then make stdin read from the file data, but why would you then close(fd)? I thought fd was what stdin is reading from now?


Solution

  • open creates a reference-counted file description (some struct) in the kernel and the returned file descriptor is kind of like a pointer to it (one of the counted references) from userspace, unless it's a negative value in which case open failed. dup2(fd,0) makes 0 also point to the same file description (unless you passed a negative fd or unless you're out of filedescriptors). If your goal was to have 0 point to the filedescription, you can now get rid of the old "pointer"/filedescriptor so you don't waste filedescriptor slots (a process can only allocate a limited number).

    (Additionally closing the last reference to a filedescription may lead to certain desirable actions such as the file being dropped if it's an unliked file or the read end of a pipe receiving EOF if you just closed the last reference to the corresponding write end. Unnecessary references (filedescriptors) lying around get in the way of this.)