karl@umb.umb.edu (Karl Berry.) (07/09/88)
The title says it all. Am I missing something obvious? The pathname doesn't seem to be a field in either the _iobuf or the structure returned by stat. ttyname or ctermid will give you the pathname of your terminal, but I want the pathname of an arbitrary FILE* I have fopen. Or am I missing some reason why this is not feasible? Karl. karl@umb.edu ...!harvard!umb!karl
gandalf@csli.STANFORD.EDU (Juergen Wagner) (07/09/88)
The _iobuf structure as defined in <stdio.h> includes a component _file which is supposed to hold the file descriptor number. With fdopen() you can create a FILE* structure from an arbitrary file descriptor (which may refer to a UNIX file, a socket, or whatsoever), so the FILE* structure may access something else than a plain UNIX file. fstat(fd, &statbuf) gives information about the open file descriptor, so you can find out the device the inode is on, the inode's number, and a few other attributes of interest. With that you should be able to find out the information wanted by looking at the st_mode field (check the fd type), and eventually by walking through the file system the inode is on. I know, it's a painful procedure but as far as I know, there is no other way to obtain the information you're looking for, other than by fiddling around with statbuf. -- Juergen "Gandalf" Wagner, gandalf@csli.stanford.edu Center for the Study of Language and Information (CSLI), Stanford CA
budd@bu-cs.BU.EDU (Philip Budne) (07/09/88)
Names are a property of directory entries, not files (inodes). Un*x files do not have "names" since many directory entries can reference the same file. The stdio library echos this. Since you called fopen() you can save the info. The real pain is figuring out what an fd from a parent is, or chasing down what file finally was opened after 3 symlinks. Philip Budne, Boston U (Ahh for JFNS%)
cjc@ulysses.homer.nj.att.com (Chris Calabrese[rs]) (07/10/88)
In article <651@umb.umb.edu>, karl@umb.umb.edu (Karl Berry.) writes: > > The title says it all. Am I missing something obvious? > The pathname doesn't seem to be a field in either the > _iobuf or the structure returned by stat. > ttyname or ctermid will give you the pathname > of your terminal, but I want the pathname of an > arbitrary FILE* I have fopen. Or am I missing some > reason why this is not feasible? If _you_ have fopened the file, then _you_ already know what the name is (just have it sitting around in your program), but if the file is inheritted(sp?) how do you even know it's a file??? If you rsh or rlogin, then the stdin to any process created on the remote machine is a socket (mabee it's something similar, but you get the idea), or a stream (ditto) for sysV. Even if you don't have any kind of a network, then stdin could be a pipe, which has no name for unnamed pipes. These are, infact, files in most versions of sysV, but they have no names, just inodes. -- Christopher Calabrese AT&T Bell Laboratories ulysses!cjc
leo@philmds.UUCP (Leo de Wit) (07/10/88)
In article <651@umb.umb.edu> karl@umb.umb.edu (Karl Berry.) writes: > >The title says it all. Am I missing something obvious? >The pathname doesn't seem to be a field in either the >_iobuf or the structure returned by stat. >ttyname or ctermid will give you the pathname >of your terminal, but I want the pathname of an >arbitrary FILE* I have fopen. Or am I missing some >reason why this is not feasible? This is not trivial. Think for instance of multiple links to a file (either hard or symbolic links); which name will you use? Or what if one of the directories in the path has multiple links - apart from the trivial ones (for example /usr/include/sys, which on our system == /usr/sys/h) ? Or what if the FILE * is connected to a pipe? Or what if the file is already gone (i.e. unlinked but still open) ? VMS has a function for it: fgetname(). On Unix you could fstat the file descriptor (the char _file member from the _iobuf struct). This gives you the inode number; now go look for the filename(s). What is the use? If you have opened the file, you used the filename already (unless the open file is inherited from a parent process). Leo.
guest@osiris.UUCP (Guest account) (07/10/88)
In article <4531@csli.STANFORD.EDU> gandalf@csli.stanford.edu (Juergen Wagner) writes: >The _iobuf structure as defined in <stdio.h> includes a component _file >which is supposed to hold the file descriptor number. *PLEASE* - if you are going to do things like using internal elements of "standard" libraries, try to access them in a more or less "standard" way. Most stdio libraries I've seen have a macro (but could be func, I guess) called fileno(myfd) - which returns just the information you are referring to. This way, your code won't break if someone does something cute or clever to the stdio library and include files. >fstat(fd, &statbuf) gives information about the open file descriptor, so >you can find out the device the inode is on, the inode's number, and a >few other attributes of interest. With that you should be able to find >out the information wanted by looking at the st_mode field (check the >fd type), and eventually by walking through the file system the inode is >on. Does this work if the file system is NFSsed, or something like that ? It almost seems to me that this is a case which stdio is not designed to handle. So - I'd say add another level of indirection. Write a routine that acts like fopen() - and one that acts like fclose(), etc. Have it store the name someplace, using only the "standard" interface to stdio, and then write another routine, or macro, that allows you to get the information back. I can't imagine that would be hard, and I expect it will work a LOT faster than reading your file system. Then again, maybe I don't understand what you're trying to do. 'V'.
gandalf@csli.STANFORD.EDU (Juergen Wagner) (07/11/88)
In article <1645@osiris.UUCP> guest@osiris.UUCP (Guest account) writes: >... >*PLEASE* - if you are going to do things like using internal elements of >"standard" libraries, try to access them in a more or less "standard" >way. Most stdio libraries I've seen have a macro (but could be func, I >guess) called fileno(myfd) - which returns just the information you are >referring to. This way, your code won't break if someone does something >cute or clever to the stdio library and include files. I am aware of the fact that there is fileno(f). The point is: there is a way to find out the file descriptor associated with FILE *f. >Does this work if the file system is NFSsed, or something like that ? If you do it properly: yes. Otherwise: no! The problem with NFS file systems is that you have to walk through something other than the local file system. I have a small program which determines the file system a file resides on, and in case of NFS just returnes the remote host's name and the remote file system's name. This allows you to walk through the directories as before. At the time I posted my article, I didn't think of files being deleted while they are still open somewhere else... This shouldn't cause any problems because your function determining the file name could then just say so. Sockets, pipes, ptys, and other stuff like raw devices can be handled with fstat. The inode type will give you the information needed. As for files having multiple links, I can only ask the question "what do you want the routine to do?" Do you want a list of all names the file can be accessed under, or are you merely looking for some way to associate this FILE * structure with *SOME* file name on your UNIX system? Personally, I would be happy with the latter solution. If you get your hands on one of the file's names, you've got the file in your grip! >It almost seems to me that this is a case which stdio is not designed to >handle. So - I'd say add another level of indirection. Write a routine >that acts like fopen() - and one that acts like fclose(), etc. Have it >store the name someplace, using only the "standard" interface to stdio, >and then write another routine, or macro, that allows you to get the >information back. I can't imagine that would be hard, and I expect it >will work a LOT faster than reading your file system. That's not always possible, as I've explained above. You can only find out the names of files *YOU* have opened yourself. You will never be able to find out what stdin/stdout/stderr are connected to... >Then again, maybe I don't understand what you're trying to do. I guess, understanding a tool is not a necessary precondition for being able to use this tool. I can fairly well work with UNIX but don't claim to have understood all the bits of it! The issue is to provide some function which performs its task in a way opaque to the user. One reason to do so is that what this function really does is operating-system dependent. And there we are again at the same point where you flamed at me because I preferred to mention _file instead of fileno(f). Opaqueness is a very important means of keeping things understandable. If somebody knew that a certain function would work more efficient under some circumstances than under other, he/she would use that knowledge in his/her programs. However, you know as well as I do that this may turn out to be much less efficient on other systems. # include <disclaimers/strawberry.h> -- Juergen "Gandalf" Wagner, gandalf@csli.stanford.edu Center for the Study of Language and Information (CSLI), Stanford CA
rwhite@nusdhub.UUCP (Robert C. White Jr.) (07/13/88)
in article <651@umb.umb.edu>, karl@umb.umb.edu (Karl Berry.) says: > The title says it all. Am I missing something obvious? > The pathname doesn't seem to be a field in either the > _iobuf or the structure returned by stat. > ttyname or ctermid will give you the pathname > of your terminal, but I want the pathname of an > arbitrary FILE* I have fopen. Or am I missing some > reason why this is not feasible? At great risk of being wrong... Since one i-node may have many file names I think that the individual file name is disposed of as useless after the object in question is opened. The closest I can even picture you getting is to retreive the inode number. All else would seem to be un-workable. Rob. Disclaimer: Then again, maby not.
jc@minya.UUCP (John Chambers) (07/21/88)
In article <560@philmds.UUCP>, leo@philmds.UUCP (Leo de Wit) writes: > In article <651@umb.umb.edu> karl@umb.umb.edu (Karl Berry.) writes: > > > >The title says it all. Am I missing something obvious? > >The pathname doesn't seem to be a field in either the > >_iobuf or the structure returned by stat. > >ttyname or ctermid will give you the pathname > >of your terminal, but I want the pathname of an > >arbitrary FILE* I have fopen. Or am I missing some > >reason why this is not feasible? > > What is the use? If you have opened the file, you used the filename > already (unless the open file is inherited from a parent process). There are lots of uses. Consider a problem I am having on a current project: A program running on a Sun is running out of files. My code opens maybe 6 or 8 files at the most. So where do the others come from? Easy - they are opened by library subroutines. My code can't remember the names of those files; my code didn't open them. This makes debugging very difficult. Sun hasn't been very helpful, either. Sure, I have a routine to fstat() all the open files and print out the magic numbers. That doesn't help me much in getting the answer to the question "What's causing all those @#$*^% files to be opened?" For debugging, it would be very useful if I could use a library that would keep around a copy of the name used to open a file. For inherited files, the info *could* be passed in the environment. The fact that some files have no valid name isn't a valid counter-argument. For debugging purposes, it would be useful if some pseudo-names ("<stdin>", "<socket>") were returned. Some of us occasionally write code that doesn't work the first time, and we sometimes have a few problems figuring out what we did wrong. Having the libraries so secretive about what they're doing isn't very helpful. -- John Chambers <{adelie,ima,maynard,mit-eddie}!minya!{jc,root}> (617/484-6393) [Any errors in the above are due to failures in the logic of the keyboard, not in the fingers that did the typing.]
mesard@bbn.com (Wayne Mesard) (07/21/88)
From article <49@minya.UUCP>, by jc@minya.UUCP (John Chambers): > There are lots of uses. Consider a problem I am having on a current > project: A program running on a Sun is running out of files. My code > opens maybe 6 or 8 files at the most. So where do the others come from? > Easy - they are opened by library subroutines. My code can't remember > the names of those files; my code didn't open them. This makes debugging > very difficult. This isn't by any chance a SunView program is it? Since SunView windows are actually devices, client programs access them via file descriptors. It's amazing how fast 4.2BSD's limit of 30 can get eaten up in a fair-sized [full-screen] application. -- unsigned *Wayne_Mesard(); MESARD@BBN.COM BBN, Cambridge, MA "When Martin Sheen visited me, he was smoking again after his heart attack, and I asked why. He said, 'It is my friend it is always there and doesn't pass judgment.' I said, 'Your friend is going to kill you.'" - Larry King
allbery@ncoast.UUCP (Brandon S. Allbery) (07/22/88)
As quoted from <1645@osiris.UUCP> by guest@osiris.UUCP (Guest account): +--------------- | It almost seems to me that this is a case which stdio is not designed to | handle. So - I'd say add another level of indirection. Write a routine | that acts like fopen() - and one that acts like fclose(), etc. Have it | store the name someplace, using only the "standard" interface to stdio, | and then write another routine, or macro, that allows you to get the | information back. I can't imagine that would be hard, and I expect it | will work a LOT faster than reading your file system. +--------------- But it won't work in the case of stdin, stdout, stderr -- which are implicitly fdopen()'ed from fd's 0, 1, and 2. And stdin is usually the one you want the name for. ++Brandon -- Brandon S. Allbery, uunet!marque!ncoast!allbery DELPHI: ALLBERY For comp.sources.misc send mail to ncoast!sources-misc