From mboxrd@z Thu Jan 1 00:00:00 1970 From: Steve Graegert Subject: Re: how to the filename Date: Thu, 14 Apr 2005 14:07:23 +0200 Message-ID: <6a00c8d50504140507365ce049@mail.gmail.com> References: <1113472539.5952.62.camel@localhost.localdomain> <6a00c8d5050414033770f1ab96@mail.gmail.com> <1113478791.5720.34.camel@localhost.localdomain> Reply-To: Steve Graegert Mime-Version: 1.0 Content-Transfer-Encoding: 7BIT Return-path: In-Reply-To: <1113478791.5720.34.camel@localhost.localdomain> Content-Disposition: inline Sender: linux-c-programming-owner@vger.kernel.org List-Id: Content-Type: text/plain; charset="us-ascii" To: kaushal@rocsys.com Cc: linux prg On 4/14/05, 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 .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 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 > > #include > > #include > > #include > > #include > > #include > > #include > > > > 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 > > Independent Software Consultant {C/C++ && Java && .NET} > > Mobile: +49 (176) 21 24 88 69 > > Office: +49 (9131) 71 26 40 9 > -- Steve Graegert Independent Software Consultant {C/C++ && Java && .NET} Mobile: +49 (176) 21 24 88 69 Office: +49 (9131) 71 26 40 9