linux-c-programming.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* how to the filename
@ 2005-04-14  9:56 kaushal
  2005-04-14 10:37 ` Steve Graegert
                   ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: kaushal @ 2005-04-14  9:56 UTC (permalink / raw)
  To: linux prg

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.

Thanks in advance.

regards-
kaushal.


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: how to the filename
  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 21:10 ` Glynn Clements
  2005-04-14 21:31 ` Ozgur Sefik Altunyurt
  2 siblings, 1 reply; 15+ messages in thread
From: Steve Graegert @ 2005-04-14 10:37 UTC (permalink / raw)
  To: kaushal; +Cc: linux prg

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

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: how to the filename
  2005-04-14 10:37 ` Steve Graegert
@ 2005-04-14 11:39   ` kaushal
  2005-04-14 12:07     ` Steve Graegert
                       ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: kaushal @ 2005-04-14 11:39 UTC (permalink / raw)
  To: Steve Graegert; +Cc: linux prg

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


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: how to the filename
  2005-04-14 11:39   ` kaushal
@ 2005-04-14 12:07     ` Steve Graegert
  2005-04-15  1:45     ` Ron Michael Khu
  2005-04-15  6:36     ` Steve Graegert
  2 siblings, 0 replies; 15+ messages in thread
From: Steve Graegert @ 2005-04-14 12:07 UTC (permalink / raw)
  To: kaushal; +Cc: linux prg

On 4/14/05, kaushal <kaushal@rocsys.com> 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.

Hi Kaushal

I know what you mean.  OK, I admit, there is a _reliable_ way.
Unfortunately, this isn't true for user mode applications.  When
looking at the lsof code you will soon realize that a very
sophisticated (and portable) approach is taken and lots of kernel
structures are involved by accessing to the virtual memory facilities
and the like.  If you are willing to bridge the gap between user space
and kernel space, you can find a reliable solution to your problem. 
Sorry for not being precisely in the first place, but I assumed we are
talking about user space apps relying on system calls only.

Kind regards

    \Steve


> 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
>

--

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

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: how to the filename
  2005-04-14  9:56 how to the filename kaushal
  2005-04-14 10:37 ` Steve Graegert
@ 2005-04-14 21:10 ` Glynn Clements
  2005-04-14 21:31 ` Ozgur Sefik Altunyurt
  2 siblings, 0 replies; 15+ messages in thread
From: Glynn Clements @ 2005-04-14 21:10 UTC (permalink / raw)
  To: kaushal; +Cc: linux prg


kaushal wrote:

> 	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.

If a descriptor corresponds to a file, the kernel records the name
under which the file was opened; the name is available via
the link /proc/<pid>/fd/<descriptor#>. If the file is renamed, the
link will be updated; if the file is deleted, " (deleted)" will be
added to the link.

Note that this is Linux-specific; it won't work on other Unices. Also,
it won't work if the /proc filesystem doesn't exist.

The historical behaviour is that any system calls which accept a
filename as an argument (e.g. open(), stat() etc) immediately resolve
the filename to a device/inode pair, then forget all about the
filename.

The only portable solution is to retrieve the device and inode numbers
via fstat(), locate the mount point for the device, then scan the
entire filesystem beneath the mount point until you find a file with
the correct inode number. If you don't find such a file, it has been
deleted since it was opened (programs which create temporary files
often delete them as soon as they are opened so they don't get left
around if the process terminates abnormally).

[A deleted file will exist so long as it remains open, it just won't
have a filename, so you can't use open(), stat() etc on it.]

-- 
Glynn Clements <glynn@gclements.plus.com>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: how to the filename
  2005-04-14  9:56 how to the filename kaushal
  2005-04-14 10:37 ` Steve Graegert
  2005-04-14 21:10 ` Glynn Clements
@ 2005-04-14 21:31 ` Ozgur Sefik Altunyurt
  2 siblings, 0 replies; 15+ messages in thread
From: Ozgur Sefik Altunyurt @ 2005-04-14 21:31 UTC (permalink / raw)
  Cc: linux prg

kaushal wrote:

>Hello all,
>
hi

>	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.
>
sorry no code snippet :)

IINW a way of doing this may be by getting the process id (PID) of the 
program that opened the file and getting the relevant file name from the 
/proc/$(PID)/fd/$(FILE_DESCRIPTOR)
or in a more technical way you may use "current->files->fd[fd]" 
structure (please refer to asm/current.h and linux/sched.h )
which IMHO requires some more extra working on linux/{proc_fs.h, fs.h, 
sched.h}..
by the way i don't know exactly how you can get the filename from  the 
file descriptor :)
i'm just suggesting..

Ozgur


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: how to the filename
  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:36     ` Steve Graegert
  2 siblings, 2 replies; 15+ messages in thread
From: Ron Michael Khu @ 2005-04-15  1:45 UTC (permalink / raw)
  To: kaushal, linux-c-programming

[-- Attachment #1: Type: text/plain, Size: 5255 bytes --]

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.  

BTW, the attached source code is from the HP/UX man page for 
pstat_getfile2(), I dont know if the pstat functions
of hp/ux is the same or is supported in linux.

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
>
>
>  
>


[-- Attachment #2: countFiles.c --]
[-- Type: text/plain, Size: 1277 bytes --]

#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
}


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: how to the filename
  2005-04-15  1:45     ` Ron Michael Khu
@ 2005-04-15  4:39       ` kaushal
  2005-04-15  6:19       ` Steve Graegert
  1 sibling, 0 replies; 15+ messages in thread
From: kaushal @ 2005-04-15  4:39 UTC (permalink / raw)
  To: Ron Michael Khu; +Cc: linux-c

Hi Ron,
	I manned for the call and is not available in my linux box.
May be I can download that.Thanks for the response.

regards-
kaushal.
On Fri, 2005-04-15 at 07:15, Ron Michael Khu 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.  
> 
> BTW, the attached source code is from the HP/UX man page for 
> pstat_getfile2(), I dont know if the pstat functions
> of hp/ux is the same or is supported in linux.
> 
> 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
> }
> 


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: how to the filename
  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
  1 sibling, 1 reply; 15+ messages in thread
From: Steve Graegert @ 2005-04-15  6:19 UTC (permalink / raw)
  To: Ron Michael Khu; +Cc: kaushal, linux-c-programming

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)?  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.  There are good reasons not to be able to
tweak FDs of other processes that easily.

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
> }
> 
> 
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: how to the filename
  2005-04-14 11:39   ` kaushal
  2005-04-14 12:07     ` Steve Graegert
  2005-04-15  1:45     ` Ron Michael Khu
@ 2005-04-15  6:36     ` Steve Graegert
  2005-04-15  6:43       ` kaushal
  2 siblings, 1 reply; 15+ messages in thread
From: Steve Graegert @ 2005-04-15  6:36 UTC (permalink / raw)
  To: kaushal; +Cc: linux prg

On 4/14/05, kaushal <kaushal@rocsys.com> 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 ....

OK, I understand. Now I know your intention.  First of all, if you
know bash's PID you should be able to find open FDs by using the /proc
approach.  To prove that FD 0, 1 and 2 (or any FD) is associated to a
particular terminal you can use

   #include <unistd.h>
   char *ttyname(int fildes);

Hope this is what you want.

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


> 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
> 
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: how to the filename
  2005-04-15  6:19       ` Steve Graegert
@ 2005-04-15  6:42         ` kaushal
  2005-04-15  6:59           ` Steve Graegert
  0 siblings, 1 reply; 15+ messages in thread
From: kaushal @ 2005-04-15  6:42 UTC (permalink / raw)
  To: Steve Graegert; +Cc: Ron Michael Khu, linux-c

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.
>  There are good reasons not to be able to
> tweak FDs of other processes that easily.

But how about fds of the self?
> 
> 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
> > }
> > 
> > 
> >


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: how to the filename
  2005-04-15  6:36     ` Steve Graegert
@ 2005-04-15  6:43       ` kaushal
  2005-04-15  7:04         ` Steve Graegert
  0 siblings, 1 reply; 15+ messages in thread
From: kaushal @ 2005-04-15  6:43 UTC (permalink / raw)
  To: Steve Graegert; +Cc: linux prg

Hi Steve,
	What I want is not the terminal name but to prove that fd 0 corresponds
to /dev/tty3 (say).

regards-
kaushal.
On Fri, 2005-04-15 at 12:06, Steve Graegert wrote:
> On 4/14/05, kaushal <kaushal@rocsys.com> 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 ....
> 
> OK, I understand. Now I know your intention.  First of all, if you
> know bash's PID you should be able to find open FDs by using the /proc
> approach.  To prove that FD 0, 1 and 2 (or any FD) is associated to a
> particular terminal you can use
> 
>    #include <unistd.h>
>    char *ttyname(int fildes);
> 
> Hope this is what you want.
> 
> 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
> 
> 
> > 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
> > 
> >


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: how to the filename
  2005-04-15  6:42         ` kaushal
@ 2005-04-15  6:59           ` Steve Graegert
  0 siblings, 0 replies; 15+ messages in thread
From: Steve Graegert @ 2005-04-15  6:59 UTC (permalink / raw)
  To: kaushal; +Cc: Ron Michael Khu, linux-c

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
> > > }
> > >
> > >
> > >
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: how to the filename
  2005-04-15  6:43       ` kaushal
@ 2005-04-15  7:04         ` Steve Graegert
  2005-04-15  9:54           ` kaushal
  0 siblings, 1 reply; 15+ messages in thread
From: Steve Graegert @ 2005-04-15  7:04 UTC (permalink / raw)
  To: kaushal; +Cc: linux prg

On 4/15/05, kaushal <kaushal@rocsys.com> wrote:
> Hi Steve,
>        What I want is not the terminal name but to prove that fd 0 corresponds
> to /dev/tty3 (say).

If, say, ttyname(0) returns NULL then FD 0 is not connected to _any_
terminal, and if not, the name is returned for this particular FD
(that could be /dev/tty3 in your case).  Then you can easily prove
that FD 0 corresponds to /dev/tty3 or it does not.

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

> regards-
> kaushal.
> On Fri, 2005-04-15 at 12:06, Steve Graegert wrote:
> > On 4/14/05, kaushal <kaushal@rocsys.com> 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 ....
> >
> > OK, I understand. Now I know your intention.  First of all, if you
> > know bash's PID you should be able to find open FDs by using the /proc
> > approach.  To prove that FD 0, 1 and 2 (or any FD) is associated to a
> > particular terminal you can use
> >
> >    #include <unistd.h>
> >    char *ttyname(int fildes);
> >
> > Hope this is what you want.
> >
> > 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
> >
> >
> > > 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
> > >
> > >
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: how to the filename
  2005-04-15  7:04         ` Steve Graegert
@ 2005-04-15  9:54           ` kaushal
  0 siblings, 0 replies; 15+ messages in thread
From: kaushal @ 2005-04-15  9:54 UTC (permalink / raw)
  To: Steve Graegert; +Cc: linux prg

Hi all,

That was good.Thanks for the response to one and all.It helped me a
lot.Thanks Steve.

regards-
kaushal.

On Fri, 2005-04-15 at 12:34, Steve Graegert wrote:
> On 4/15/05, kaushal <kaushal@rocsys.com> wrote:
> > Hi Steve,
> >        What I want is not the terminal name but to prove that fd 0 corresponds
> > to /dev/tty3 (say).
> 
> If, say, ttyname(0) returns NULL then FD 0 is not connected to _any_
> terminal, and if not, the name is returned for this particular FD
> (that could be /dev/tty3 in your case).  Then you can easily prove
> that FD 0 corresponds to /dev/tty3 or it does not.
> 
> 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
> 
> > regards-
> > kaushal.
> > On Fri, 2005-04-15 at 12:06, Steve Graegert wrote:
> > > On 4/14/05, kaushal <kaushal@rocsys.com> 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 ....
> > >
> > > OK, I understand. Now I know your intention.  First of all, if you
> > > know bash's PID you should be able to find open FDs by using the /proc
> > > approach.  To prove that FD 0, 1 and 2 (or any FD) is associated to a
> > > particular terminal you can use
> > >
> > >    #include <unistd.h>
> > >    char *ttyname(int fildes);
> > >
> > > Hope this is what you want.
> > >
> > > 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
> > >
> > >
> > > > 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
> > > >
> > > >
> >


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2005-04-15  9:54 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
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

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).