I have a program that reads from a file and writes to a file. I'd like to prevent the user from specifying the same file for both (for obvious reasons). Lets say the first path is in char* path1
and the second path is in char* path2
. can I fopen()
both paths, call fileno()
on each and get the same number?
To explain more clearly:
char* path1 = "/asdf"
char* path2 = "/asdf"
FILE* f1 = fopen(path1, "r");
FILE* f2 = fopen(path2, "w");
int fd1 = fileno(f1);
int fd2 = fileno(f2);
if(fd1 == fd2) {
printf("These are the same file, you really shouldn't do this\n");
}
I do not want to compare filenames because one could easily defeat that with paths like /asdf/./asdf
or by using symlinks. Ultimately, I do not want to write my output into the file that I'm reading from (could cause serious issues).
Pointers to the Open File Table: One process can have multiple file descriptors point to the same entry (e.g., as a result of a call to dup() ) Multiple processes (e.g., a parent and child) can have file descriptors that point to the same entry.
A FILE pointer is a C standard library-level construct, used to represent a file. The FILE wraps the file descriptor, and adds buffering and other features to make I/O easier.
fcntl(fd, F_GETFD) is the canonical cheapest way to check that fd is a valid open file descriptor. If you need to batch-check a lot, using poll with a zero timeout and the events member set to 0 and checking for POLLNVAL in revents after it returns is more efficient.
Yes - compare the file device ID and inode. Per the <sys/stat.h>
specification:
The st_ino and st_dev fields taken together uniquely identify the file within the system.
Use
int same_file(int fd1, int fd2) {
struct stat stat1, stat2;
if(fstat(fd1, &stat1) < 0) return -1;
if(fstat(fd2, &stat2) < 0) return -1;
return (stat1.st_dev == stat2.st_dev) && (stat1.st_ino == stat2.st_ino);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With