linux-c-programming.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Steve Graegert <graegerts@gmail.com>
To: kaushal@rocsys.com
Cc: linux prg <linux-c-programming@vger.kernel.org>
Subject: Re: how to the filename
Date: Thu, 14 Apr 2005 12:37:41 +0200	[thread overview]
Message-ID: <6a00c8d5050414033770f1ab96@mail.gmail.com> (raw)
In-Reply-To: <1113472539.5952.62.camel@localhost.localdomain>

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

  reply	other threads:[~2005-04-14 10:37 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 [this message]
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

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=6a00c8d5050414033770f1ab96@mail.gmail.com \
    --to=graegerts@gmail.com \
    --cc=kaushal@rocsys.com \
    --cc=linux-c-programming@vger.kernel.org \
    /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).