Reputation: 469
I have an open device descriptor, where I don't know the device name and the options passed to open(...). I want to open a new device descriptor with the same options passed to open.
int newFd = copy(referenceFd);
Where copy would do the job. dup() is certainly the wrong choice as a further ioctl() on newFd would also alter the referenceFd, therefore I want to open a new descriptor.
Is there a system call which provides such functionality?
I have not been able to find something yet.
Upvotes: 1
Views: 160
Reputation: 39416
First, get the descriptor flags of file descriptor fd
using
int flags = fcntl(fd, F_GETFL);
Then, reopen the descriptor using the Linux-specific /proc/self/fd/
fd
entry:
int newfd;
char buffer[32];
if (snprintf(buffer, sizeof buffer, "/proc/self/fd/%d", fd) < sizeof buffer) {
do {
newfd = open(buffer, flags & ~(O_TRUNC | O_EXCL), 0666);
} while (newfd == -1 && errno == EINTR);
if (newfd == -1) {
/* Error: Cannot reopen file. Error in errno. */
}
} else {
/* Error: the path does not fit in the buffer. */
}
The reopened file descriptor is then in newfd
.
Note that you most likely want to make sure O_TRUNC
(truncate the file) and O_EXCL
(fail if exists) are not in the flags, to avoid the cases where reopening using the exact original flags would cause unwanted results.
You do not want to use lstat()
, because that opens up a race condition with respect to rename -- a user renaming the target file between the lstat()
and the open()
in above code. The above avoids that completely.
If you don't want to be Linux-specific, add code that tries the same with /dev/fd/
fd
if the above fails. It is supported in some Unix systems (and most Linux distros too).
Upvotes: 1
Reputation: 182714
You can probably do it with a series of fcntl
calls:
F_GETFD
- Get the file descriptor flags defined in that are associated with the file descriptor fildes.
F_GETFL
- Get the file status flags and file access modes, defined in , for the file description associated with fildes.
I linked the SUSv4 page above; you might also be interested in the Linux version.
Upvotes: 3