From: Steve Graegert <graegerts@gmail.com>
To: kaushal@rocsys.com
Cc: Ron Michael Khu <ronkhu@ntsp.nec.co.jp>,
linux-c <linux-c-programming@vger.kernel.org>
Subject: Re: how to the filename
Date: Fri, 15 Apr 2005 08:59:21 +0200 [thread overview]
Message-ID: <6a00c8d505041423599958164@mail.gmail.com> (raw)
In-Reply-To: <1113547344.5720.90.camel@localhost.localdomain>
On 4/15/05, kaushal <kaushal@rocsys.com> wrote:
> Hi Steve,
>
> On Fri, 2005-04-15 at 11:49, Steve Graegert wrote:
> > On 4/15/05, Ron Michael Khu <ronkhu@ntsp.nec.co.jp> wrote:
> > > Hmm..
> > > Im not familiar with the implementation of lsof... but I do know that
> > > with pstat_getproc-related functions like pstat_getfile2(),
> > > it is possible to retrieve information on all the open files of a
> > > certain process(given it's PID). It is even possible to
> > > retrieve information about how many threads a particular process has
> > > created.
> >
> > The problem I see is, that we all seem to have different thoughts
> > about the application of such szenarios. Why should one try to obtain
> > a filename associated with an FD she did not create herself (assuming
> > user space applications)?
>
> Basically the question was R&D kind.But I would like to build up a
> scenario which may require this feature correct me if Iam wrong:
> A has forked and execed B.A and B are supposed to write to a same file
> and only one of them is supposed.If B finds that the file is already
> opened(execed process has the open descriptors) based on the filename,
> then B may require this application.(Iam jus trying to build the
> scenario.and even guess the same can be achieved using fcntl somebody
> can share their scenarios.)
>
> > Another question is: how can one find such
> > FDs, or to be more specific, how can one find an FD that may be of
> > interest without knowing the PID (assuming that he is interested in
> > the FDs of a particular process). I know it is possible (with little
> > effort under Linux at least) but there is no easy reverse mapping of
> > PIDs to their executables.
> I don't know if you mean this but, I think by printing the
> /proc/pid/cmdline we can get the pid's executable name.
Yeah, that's what I meant with "little effort under Linux" :-)
Don't try this on other operating systems. Sorry, but I really like
to be portable in all situations.
> > There are good reasons not to be able to
> > tweak FDs of other processes that easily.
>
> But how about fds of the self?
Hmm, I don't get it. Could you be more specific, please?
Kind Regards
\Steve
--
Steve Graegert <graegerts@gmail.com>
Independent Software Consultant {C/C++ && Java && .NET}
Mobile: +49 (176) 21 24 88 69
Office: +49 (9131) 71 26 40 9
> >
> > > And like Mr. Ozgur(altunyurt@itu.edu.tr), I dont know how to retrieve
> > > the filename given only a filedescriptor...
> > > because with pstat_getfile2() Im passing PID's.
> > >
> > > -Ron
> > >
> > >
> > > ,kaushal wrote:
> > >
> > > >Hi Steve,
> > > > Thanks for the response.But how will lsof work for a particular PID.If
> > > >lsof can print all the files by their names then why can't any c
> > > >program?The idea was to prove that the file /dev/pts/9 or some no. is
> > > >opened by the bash and to it are the stdin,stdout and stderr
> > > >associated.For that ,the fds 0,1,and 2 are supposed to point to the same
> > > >file /dev/pts/9 or say /dev/tty3 ....
> > > >This can be proved using lsof -p <PID OF THE BASH> .But how to prove
> > > >that from within a c program?This lead to the sol if we can get the
> > > >filename from the file descriptor and print it on the screen.
> > > >
> > > >regards-
> > > >kaushal.
> > > >On Thu, 2005-04-14 at 16:07, Steve Graegert wrote:
> > > >
> > > >
> > > >>On 4/14/05, kaushal <kaushal@rocsys.com> wrote:
> > > >>
> > > >>
> > > >>>Hello all,
> > > >>> How can I get the filename/pathname given the open file descriptor?Does
> > > >>>fstat provide this feature internally?Can somebody give the code snippet
> > > >>>for this.
> > > >>>
> > > >>>
> > > >>There is no such thing. It is not possible to obtain a FD's filename
> > > >>reliably. Unless you are absolutely sure that this particular FD
> > > >>points to a file (or directory) and not to a socket, pipe or
> > > >>something similar, you will not be able to use fstat reliably. Which
> > > >>of stat's fields are suggesting to be helpful reagarding to your
> > > >>problem? st_ino? How would you locate a file based on its file ID?
> > > >>This would require scanning the complete file system (and probably
> > > >>more than one). Another problem is, that an FD might be associated
> > > >>with other files at the same time or files can be stored inside a
> > > >>directory that you can't read due to lack of sufficient permissions.
> > > >>What you are looking for is some kind of reverse lookup to unwind the
> > > >>many-to-one relationship of files and inodes.
> > > >>
> > > >>A couple of years ago Floyd Davidson suggested some code that may
> > > >>point you to the right direction (not tested):
> > > >>
> > > >>/* A demo program to locate file names related to an inode number */
> > > >>
> > > >>#include <stdio.h>
> > > >>#include <stdlib.h>
> > > >>#include <unistd.h>
> > > >>#include <string.h>
> > > >>#include <sys/stat.h>
> > > >>#include <dirent.h>
> > > >>#include <limits.h>
> > > >>
> > > >>void scan_list(char *curdir, struct dirent **ptr_nl, int dirs);
> > > >>int file_select(const struct dirent *nl);
> > > >>
> > > >>ino_t inode;
> > > >>char curdir[PATH_MAX] = "."; /* default search directory */
> > > >>
> > > >>int
> > > >>main(int argc, char **argv)
> > > >>{
> > > >> struct dirent **namelist;
> > > >> struct stat st;
> > > >>
> > > >> if (argc < 2 || argc > 3) {
> > > >> fprintf(stderr,"usage: %s inode [directory]\n", argv[0]);
> > > >> exit(EXIT_FAILURE);
> > > >> }
> > > >> inode = strtoul(argv[1], NULL, 10);
> > > >> if (!inode) {
> > > >> fprintf(stderr,"Error: invalid inode\n");
> > > >> exit(EXIT_FAILURE);
> > > >> }
> > > >> if (argc == 3 && !lstat(argv[2], &st) && S_ISDIR(st.st_mode)) {
> > > >> strcpy(curdir, argv[2]);
> > > >> }
> > > >>
> > > >> scan_list(curdir, namelist,
> > > >> scandir(curdir, &namelist, file_select, alphasort));
> > > >> return EXIT_SUCCESS;
> > > >>}
> > > >>
> > > >>/*
> > > >> * returns 1 for directories, otherwise 0
> > > >> * and displays any filename which matches inode.
> > > >> */
> > > >>int
> > > >>file_select(const struct dirent *nl)
> > > >>{
> > > >> struct stat st;
> > > >> char curfile[PATH_MAX];
> > > >>
> > > >> sprintf(curfile, "%s/%s", curdir, nl->d_name);
> > > >> if (0 == lstat(curfile, &st)) {
> > > >> /* report a matching inode number */
> > > >> if (st.st_ino == inode) {
> > > >> printf(" %6lu %-20s \n", (unsigned long) st.st_ino, curfile);
> > > >> }
> > > >> /* skip these directories */
> > > >> if (!strcmp(nl->d_name, ".") || !strcmp(nl->d_name, "..")) {
> > > >> return 0;
> > > >> }
> > > >> /* otherwise list all directories */
> > > >> if (S_ISDIR(st.st_mode)) {
> > > >> return 1;
> > > >> }
> > > >> } return 0;
> > > >>}
> > > >>
> > > >>/* descend through all directories */
> > > >>void
> > > >>scan_list(char *olddir, struct dirent **ptr_nl, int dirs)
> > > >>{
> > > >> char savedir[PATH_MAX];
> > > >> int i;
> > > >> struct dirent **namelist;
> > > >>
> > > >> if (dirs > 0) {
> > > >> for (i = 0; i < dirs; ++i) {
> > > >> strcpy(savedir, curdir);
> > > >> sprintf(curdir,"%s/%s", olddir, ptr_nl[i]->d_name);
> > > >> scan_list(curdir, namelist,
> > > >> scandir(curdir, &namelist, file_select, alphasort));
> > > >> strcpy(curdir, savedir);
> > > >> }
> > > >> }
> > > >>}
> > > >>
> > > >>/* End of demo program */
> > > >>
> > > >>Kind Regards
> > > >>
> > > >> \Steve
> > > >>
> > > >>--
> > > >>
> > > >>Steve Graegert <graegerts@gmail.com>
> > > >>Independent Software Consultant {C/C++ && Java && .NET}
> > > >>Mobile: +49 (176) 21 24 88 69
> > > >>Office: +49 (9131) 71 26 40 9
> > > >>
> > > >>
> > > >
> > > >-
> > > >To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
> > > >the body of a message to majordomo@vger.kernel.org
> > > >More majordomo info at http://vger.kernel.org/majordomo-info.html
> > > >
> > > >
> > > >
> > > >
> > >
> > >
> > > #include <sys/param.h>
> > > #include <sys/pstat.h>
> > > #include <sys/unistd.h>
> > > #include <stdio.h>
> > >
> > > int main( int argc, char *argv[] )
> > > {
> > > #define BURST ((size_t)10)
> > > struct pst_fileinfo2 psf[BURST];
> > > int i, count;
> > > int idx = 0; /* index within the context */
> > >
> > > if ( argc != 2 )
> > > {
> > > printf( "args: <pid>\n" );
> > > exit( 1 );
> > > }
> > > pid_t target = atoi( argv[1] );
> > >
> > > (void)printf("Open files for process PID %d\n", target);
> > >
> > > /* loop until all fetched */
> > > while ((count = pstat_getfile2(psf, sizeof(struct pst_fileinfo2),
> > > BURST, idx, target)) > 0) {
> > > /* process them (max of BURST) at a time */
> > > for (i = 0; i < count; i++) {
> > > (void)printf("fd #%d\tFSid %x:%x\tfileid %d\n",
> > > psf[i].psf_fd,
> > > psf[i].psf_id.psf_fsid.psfs_id,
> > > psf[i].psf_id.psf_fsid.psfs_type,
> > > psf[i].psf_id.psf_fileid);
> > > }
> > >
> > > /*
> > > * Now go back and do it again, using the
> > > * next index after the current 'burst'
> > > */
> > > idx = psf[count-1].psf_fd + 1;
> > > }
> > > if (count == -1)
> > > perror("pstat_getfile2()");
> > >
> > > #undef BURST
> > > }
> > >
> > >
> > >
>
next prev parent reply other threads:[~2005-04-15 6:59 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-04-14 9:56 how to the filename kaushal
2005-04-14 10:37 ` Steve Graegert
2005-04-14 11:39 ` kaushal
2005-04-14 12:07 ` Steve Graegert
2005-04-15 1:45 ` Ron Michael Khu
2005-04-15 4:39 ` kaushal
2005-04-15 6:19 ` Steve Graegert
2005-04-15 6:42 ` kaushal
2005-04-15 6:59 ` Steve Graegert [this message]
2005-04-15 6:36 ` Steve Graegert
2005-04-15 6:43 ` kaushal
2005-04-15 7:04 ` Steve Graegert
2005-04-15 9:54 ` kaushal
2005-04-14 21:10 ` Glynn Clements
2005-04-14 21:31 ` Ozgur Sefik Altunyurt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=6a00c8d505041423599958164@mail.gmail.com \
--to=graegerts@gmail.com \
--cc=kaushal@rocsys.com \
--cc=linux-c-programming@vger.kernel.org \
--cc=ronkhu@ntsp.nec.co.jp \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).