Some Name
Some Name

Reputation: 9521

Duplicating file descriptor and seeking through both of them independently

I have an open file descriptor which I want to duplicate in order to perform reading and seeking through both of them independently. I looked at the

int dup(int old_fd)

syscall. The problem is it does not really fit here. Man page states the following http://man7.org/linux/man-pages/man2/dup.2.html :

After a successful return, the old and new file descriptors may be used interchangeably. They refer to the same open file description (see open(2)) and thus share file offset and file status flags; for example, if the file offset is modified by using lseek(2) on one of the file descriptors, the offset is also changed for the other.

Is there a way to duplicate a file descriptor so they are completely independent?

Upvotes: 5

Views: 2279

Answers (2)

ilkkachu
ilkkachu

Reputation: 6527

In Linux, opening /proc/<pid>/fd/<n> opens the file that's currently open at fd N, but this is a new copy, not a linked duplicate like the one you get with dup() and friends.

This should create a file that contains bar, a bunch of zero bytes, then foo. Contrast with the version using dup().

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>

int main(void)
{
    int fd1, fd2;
    char buffer[50];

    fd1 = open("testfile", O_CREAT | O_TRUNC | O_RDWR, 0600);
    sprintf(buffer, "/proc/self/fd/%d", fd1);
#ifndef USE_DUP
    fd2 = open(buffer, O_RDWR);
    if (fd2 == -1) {
        perror("open");
    }
#else
    fd2 = dup(fd1);
#endif
    if (lseek(fd1, 16, SEEK_SET) == -1) {
        perror("lseek");
    }
    if (write(fd1, "foo", 3) == -1) {
        perror("write(fd1)");
    }
    if (write(fd2, "bar", 3) == -1) {
        perror("write(fd2)");
    }
}

Upvotes: 5

Jonathan Leffler
Jonathan Leffler

Reputation: 753725

No — at least, not in POSIX-defined mechanisms.

If you want complete independence of the file descriptors, you need to avoid the shared open file description, which means an independent open() or equivalent.

There's a chance that there's a Linux-specific mechanism that does the job that I've not heard of. However, looking through the system calls for Linux at http://man7.org/linux/man-pages/man2/ didn't provide enlightenment.

Upvotes: 3

Related Questions