Determining the (opened) filename from a FILE * - c

Given a stdio FILE * pointer, is there a method by which I can discover the name of the (opened) file?

It looks (from here) that on POSIX systems you can use fileno() to get the file descriptor from a FILE*, then use fstat to get the stat info from the file descriptor. The stat structure contains the device number and inode number. You can check the filesystem for files which match the inode. This will obviously take some time for a filesystem full of stuff.
The reason that this isn't really possible (as explained in the linked article) is that a stream can have no filename if it's something like stdin or stdout, or if it's an open file that has been deleted. It can have multiple names because of hardlinks as well.
The linked article mentions this comp.lang.c FAQ which outlines the insolubility of this problem in brief.
EDIT: Thanks for the correction.

No, there isn't. Apart from anything else, the FILE * may not refer to a named file. If your application needs this facility, you wil need to maintain some kind of map
from open FILE *s to the file name you used to open them.

There is no standard defined portable solution. However, you can take a look at your OS provided API set. POSIX systems have a fstat function that takes a descriptor (not a FILE *) and returns some information.

Related

linux function openat vs open, what does "at" mean?

I know how to use the two functions, but I do not know what the suffix "at" means. Does it represent the abbreviation of "another"?
At means that the working directory considered for the open call is at the given file descriptor, passed as the parameter. The *at() family of functions are useful so that all path relative operations refer to the same file inode, even if it changes name or someone replaces it.

pstatus_t no found in procfs.h (LINUX)

I am reading the /proc/PID/status file using my C program and I want to use the pstatus_t struct to directly read the values from the file into this struct. However, my compiler is showing that this file is not present in the procfs.h.
I have checked few examples on internet where they are using the same header file but in my case, it is not working.
When you say "reading /proc/PID/status", I'm assuming that you are running in userspace (as opposed to in the kernel). In this case, the pstatus_t structure is worthless to you. Most files under /proc, including status, are a text-formatted representation of the kernel data structures. There is no way to directly get the binary contents of a kernel pstatus_t structure.

Is the remove function guaranteed to delete the file?

The wording of the C99 standard seems a bit ambiguous regarding the behavior of the remove function.
In section 7.19.4.1 paragraph 2:
The remove function causes the file whose name is the string pointed to by filename
to be no longer accessible by that name. A subsequent attempt to open that file using that
name will fail, unless it is created anew.
Does the C99 standard guarantee that the remove function will delete the file on the filesystem, or could an implementation simply ignore the file -- leaving the file on filesystem, but just inaccessible to the current program via that filename-- for the remainder of the program?
I don't think you're guaranteed anything by the C standard, which says (N1570, 7.21.4.1 2):
The remove function causes the file whose name is the string pointed to by filename
to be no longer accessible by that name. A subsequent attempt to open that file using that
name will fail, unless it is created anew. If the file is open, the behavior of the remove
function is implementation-defined.
So, if you had a pathological implementation, it could be interpreted, I suppose, to mean that calling remove() merely has the effect of making the file invisible to this running instance of this program, but that would be, as I said, pathological.
However, all is not utterly stupid! The POSIX specification for remove() says,
If path does not name a directory, remove(path) shall be equivalent to unlink(path).
If path names a directory, remove(path) shall be equivalent to rmdir(path).
And the POSIX documentation for unlink() is pretty clear:
The unlink() function shall remove a link to a file.
Therefore, unless your implementation (a) Does not conform to POSIX requirements, and (b) is extremely pathological, you can be assured that the remove() function will actually try to delete the file, and will return 0 only if the file is actually deleted.
Of course, on most filesystems currently in use, filenames are decoupled from the actual files, so if you've got five links to an inode, that file's going to keep existing until you delete all five of them.
References:
The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
The Open Group Base Specifications Issue 7, IEEE Std 1003.1™, 2013 EditionNote:"IEEE Std 1003.1 2004 Edition" is "IEEE Std 1003.1-2001 with corrigenda incorporated". "IEEE Std 1003.1 2013 Edition" is "IEEE Std 1003.1-2008 with corrigendum incorporated".
The C99 standard does not guarantee anything.
The file could remain there for any of the reasons unlink(2) can fail. For example you don't have permission to do this.
Consult http://linux.die.net/man/2/unlink for examples what can all go wrong.
On Unix / Linux, there are several reasons for the file not to be removed:
You dont't have write permission on the file's directory (in that case, remove() will return ERROR, of course)
there is another hard link on the file. Then the file will remain on disk but only be accessible by the other path name(s)
the file is kept open by any process. In that case the directory entry is removed immediatly, so that no subsequent open() can access the file (or an appropriate call will create a new file), but the file itself will remain on disk as long as any process keeps it open.
Typically, that only unlinks the file from the file system. This means all the data that was in the file, is still there. Given enough experience or time, someone would be able to get that data back.
There are some options to not have the file be read again, ever. The *nix utility shred will do that. If you are looking to do it from within a program, open the file to write, and write nonsense data over what you are looking to 'remove'.

What is difference between file descriptor and file pointer? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What's the difference between a file descriptor and file pointer?
If I open file like this:
FILE *fp = fopen("mr32.txr","r");
then fp is file pointer or file descriptor? What is difference between them?
fp is a FILE pointer
File pointer:
It is high level interface
Passed to fread() and fwrite() functions
Includes buffering,error indication and EOF detection,etc.
Provides higher portability and efficiency.
File descriptor:
Low/Kernel level handler
passe to read() and write() of UNIX System Calls
Doesn't include buffering and such features
Less portable and lacks efficiency
based on this link
It's a pointer to a FILE structure, if that's what you're asking. A file descriptor is an integer. The FILE structure and its related APIs are part of the C standard. File descriptors and their related functions are not. In practice you can use either set of functions interchangeably, though there are some notable differences in default behaviour here and there. You can read the man pages to figure out which functions take which sort of parameters. On systems that have file descriptors, you can usually use the fdopen(3) function to get a FILE structure from an open file descriptor and fileno(3) to go the other way.
FILE is a struct that contains information about the file, including the file descriptor.

How to check if given argument for file reading is valid?

I am taking in an argument using fopen. What are some checks I can do to make sure that fopen actually takes in the string to a valid filename?
The number one method is to try opening the file. If fopen() returns NULL, there was an error. Check the errno variable or function to find out the problem.
Trying to preprocess a file specification is an exercise in futility. The operating system will do every relevant check for you, including those which are hard for you to do, like checking file protection ACLs, etc.
The question isn't clear, but if you want to know if the file name you have points to an existing file, you can use access (Linux documentation) (Windows documentation).

Resources