|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| lloydchristmas759 (71) | |||||
|
Hi all, I was wondering if there is a way to determine if two file descriptors point to the same file description. E.g. if you have:
how can I write a function bool compareFds(int fd1, int fd2) such that:
? It would be quite useful to implement a FileDescriptor class with operator= and the copy constructor implemented with dup(), but I need this comparison to implement operator==. | |||||
|
|
|||||
| jsmith (5804) | |
|
What would be the point of such a class? What would the copy semantics be if the FileDescriptor were: 1) a UDP socket bound to port X? 2) a TCP socket bound to port X? 3) a UNIX socket bound to an abstract name? 4) a disk file opened for writing? 5) a disk file opened for reading and writing? | |
|
|
|
| lloydchristmas759 (71) | |||
|
Err ... you realize that dup() is a standard POSIX function that makes a copy of a file descriptor ? So the semantics for a FileDescriptor class would be exactly the same for the dup() function. Basically, with a simple FileDescriptor class like that:
you cannot have e.g. a std::vector of FileDescriptors because when you add an element to the vector, a copy is made and the original FileDescriptor is likely going to be destructed, and thus close() will be called on the fd. If however the operator= and the copy constructor of FileDescriptor are overloaded and use dup(), the problem is solved, except that I don't know how to implement operator==, which makes the whole thing pretty much useless. | |||
|
|
|||
| jsmith (5804) | |
|
I do realize that. But understand that the most common uses of dup (and dup2) are to programmatically redirect stderr, stdout, and/or stdin to a different location (perhaps to a file, or perhaps piping the output from a fork/exec'ed program back to the parent). It is not, in general, used to create two different file descriptors to the same disk file or the same UDP or TCP port, or the same UNIX socket. I only ask the questions because I think there are far more ways to abuse/misuse a general FileDescriptor class than there are uses of it. Personally I'd think about writing some sort of "smart fd" class that mimics the way boost::shared_ptr works. | |
|
|
|
| lloydchristmas759 (71) | |||
I think something needs to be clarified: a file descriptor does not point to a disk file or to a TCP/UDP port. It points to an open file description, i.e an open disk file, or an open TCP/UDP port, or an open TCP connection, etc. From the dup() manpage:
And from the close() manpage:
So it means that the "smart fd" you propose could be very easily implemented using dup(), whereas a shared_ptr-like implementation would be quite complex (because the implementation of shared_ptr itself is quite complex). Hence my original question... | |||
|
Last edited on
|
|||
| jsmith (5804) | ||||
|
So if I create 2 TCP sockets, but don't bind them to a port, and compare them, they are equal. But as soon as I bind one to port X, they are no longer equal. If I open() "foo.txt" read only twice, they are equal. As soon as I read one character using one of the file descriptors (but not the other), they are not equal? (Since your quoted man page includes the file offset as part of the file description). If I open() "foo.txt" twice, once as read-only and once as, say, read-write, they are not equal (again, see man page).
If those are the semantics you want, I think the answer to your question is no, you can't know that, because the file descriptor table is not exposed to you (it is held by the kernel). But if this is the problem you are trying to solve:
That problem should be solved via a "smart fd" class. I suggested it not only because it is the right solution, but also because I have an implementation of one (it is less than 100 lines of actual C++ code and mimics the APIs provided by the boost smart_ptr library), but I cannot post it here. | ||||
|
|
||||
| lloydchristmas759 (71) | |||||||
|
Either I did not make my problem clear enough, or you don't understand the concepts of file descriptors vs file descriptions vs files. When you have:
fd1 and fd2 are different file descriptors which refer to different open file descriptions, which can have different offsets, etc, although they refer to the same file. The thing is, I don't want to know if two file descriptors refer to the same TCP port or the same file. I want to compare two file descriptors to know if they refer to the same socket or open file description. Again, I don't care if they refer to the same file/TCP port or not. My FileDescriptor class is not meant to open a file or create a socket, it is meant to help dealing with a file descriptor in a "RAII way". In other words, I don't want my FileDescriptor to do something like that (as you suggested):
but rather like that:
I agree with you that a "smart fd" class which would include a reference counter would work. But I find the solution quite complicated, since the (UNIX) operating system already implements a reference counter for each open file description, which is incremented each time you call dup() on a file descriptor referencing this file description, and decremented each time you call close() on such a file descriptor. | |||||||
|
Last edited on
|
|||||||
| jsmith (5804) | |
|
Ok, the answer to your question is no, you can't do the comparison you want. | |
|
|
|