2

I found a solution here Duplicating file pointers?

FILE *fp2 = fdopen (dup (fileno (fp)), "r");

but according to http://man7.org/linux/man-pages/man2/dup.2.html, the new file descriptor created by dup, they refer to the same open file descriptor, and thus share status. That's not what I want. I want to create a totally new IO object which refers to the file pointed by the old FILE *

Is there any way to do this?

Add: I don't have the filename actually. I'm doing a deep copy of an object, which hold an open FILE pointer, so I have to copy that also.

Ziqi Liu
  • 2,931
  • 5
  • 31
  • 64

1 Answers1

4

I want to create a totally new IO object which refers to the file pointed by the old FILE *

You're assuming that the file associated with the original FILE * has some form of identity distinct from the IO object by which it is accessed. That is true for regular files and some other objects, but false for others, such as sockets and pipes. Thus, there is no general-purpose mechanism for doing what you ask.

For the special case of objects that can be accessed via the file system, the way to create a new IO object associated with the same file is to open() or fopen() the file via a path to it. That's what these functions do. There is no standard way to get a path from a FILE * or file descriptor number, but on Linux (since you tagged that) you can use readlink() on the open file's entry in /proc, as described here.

Do be aware that even for regular files, the readlink approach is not guaranteed to work. In particular, it will not work if the path with which the original file was opened has since been unlinked, and in fact, in that case it could lead to the wrong file being opened instead. You can check for that by running fstat() on both the old and new file descriptor numbers -- if the files are in fact the same, then they will have the same inode numbers on the same host device.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • Thanks for the solution! The readlink approach is what I've thought about before, and as you say it only work for linux, but I hope my program can also run at other platform so I'm considering some better approach. But it seems that there is no better way to do this...maybe I should just keep a record of the filename and open another `FILE *` through that filename – Ziqi Liu Apr 04 '19 at 20:32
  • 2
    @ZiqiLiu, it's unclear to me what purpose is served by having an independent `FILE *` at all, but if indeed you require one then keeping track of the file name so as to be able to open it again would definitely be my recommendation. – John Bollinger Apr 04 '19 at 20:35