?
Solved

getting inode from filename and its associated fds

Posted on 2005-03-07
11
Medium Priority
?
577 Views
Last Modified: 2008-02-20
hello,
           I want to know is there any command on LINUX that will do following or I have to write a C program?
          if i know filename how to get its inode no. and if that file is open what is its no. of FD's (in case file is opened in many programs)

0
Comment
Question by:b123coder
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 2
  • +1
11 Comments
 
LVL 45

Assisted Solution

by:sunnycoder
sunnycoder earned 80 total points
ID: 13475525
> I want to know is there any command on LINUX that will do following or I have to write a C program?
There is a command
$] stat <filename>

0
 

Author Comment

by:b123coder
ID: 13475919
hello sunnycoder,
               So there's a command stat that gives all info about file.   can you tell me please how to use that in my C program? Actually what i want  is that my program is receving filename and i want to print its inode no. in my C program also want to print pid's of processes that are using this filename?
0
 
LVL 45

Expert Comment

by:sunnycoder
ID: 13476986
use popen to read from the command and parse the results

man popen
man pclose
man fgets
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 22

Expert Comment

by:NovaDenizen
ID: 13480224
In Linux, you have two stats:  a command-line program and a C stdlib call.  Since this is the C programming category, I'm assuming you want the C call.

Check out the stat(2) man page with the command "man -s2 stat".  (don't just use "man stat" because that will give you the command-line program).

       #include <sys/types.h>
       #include <sys/stat.h>
       #include <unistd.h>

       int stat(const char *file_name, struct stat *buf);
       int fstat(int filedes, struct stat *buf);
       int lstat(const char *file_name, struct stat *buf);

It's pretty easy.  Pass the filename to stat in the file_name parameter, along with a struct stat.  The OS will stick the information in your struct stat.  Note the 'st_ino' field.




              struct stat {
                  dev_t         st_dev;      /* device */
                  ino_t         st_ino;      /* inode */
                  mode_t        st_mode;     /* protection */
                  nlink_t       st_nlink;    /* number of hard links */
                  uid_t         st_uid;      /* user ID of owner */
                  gid_t         st_gid;      /* group ID of owner */
                  dev_t         st_rdev;     /* device type (if inode device) */
                  off_t         st_size;     /* total size, in bytes */
                  blksize_t     st_blksize;  /* blocksize for filesystem I/O */
                  blkcnt_t      st_blocks;   /* number of blocks allocated */
                  time_t        st_atime;    /* time of last access */
                  time_t        st_mtime;    /* time of last modification */
                  time_t        st_ctime;    /* time of last status change */
              };



0
 

Author Comment

by:b123coder
ID: 13493631
Hello ,
           I am getting segmentation fault in following code.
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

main()
{
long int err=0;
struct stat *buf;
err=stat("/root/install.log",buf);
if(err!=0)
exit(1);
printf("inode no. is =%ld\n",buf->st_ino);
}

Also how to modify this to find File descriptors and PID of processes that uses the filename given to function stat
0
 
LVL 45

Expert Comment

by:sunnycoder
ID: 13493640
you did not allocate any memory for struct stat

struct stat buf;
err=stat("/root/install.log",&buf);
0
 

Author Comment

by:b123coder
ID: 13495301
Hello sunnycoder,
          Sorry for asking silly thing of not allocating struct stat well. But please can it be possible to modify my program to find File descriptors and PID of processes that uses the filename given to function stat
0
 
LVL 45

Expert Comment

by:sunnycoder
ID: 13496505
file descriptors are local to a process .. the information regarding file descriptors, as to which descriptor of a process refers to which file is available either to the process or needs to be dug in from the kernel ...

If I remember correctly, you can inspect the file descriptor table in the proc filesystem somewhere under /proc/<PID> ... but that would mean examining the table for each and every process (and you will need root permission for that) and shortlisting the PIDs which have that particular file open ... Also this method is likely to be less portable as proc filesystem is not standard (but fairly common in the Linux world)
0
 
LVL 22

Expert Comment

by:NovaDenizen
ID: 13496588
Just a couple small changes.  You need to provide the struct stat for stat() to write into.

main()
{
long int err=0;
struct stat buf;
err=stat("/root/install.log",&buf);
if(err!=0)
exit(1);
printf("inode no. is =%ld\n",buf.st_ino);
}
0
 
LVL 5

Accepted Solution

by:
crazycomputers earned 120 total points
ID: 13503999
You can get a list of fds used by a process in /proc/nnn/fd where nnn is the process ID.  You can't DO anything with these, of course, since they belong to that process only, but you can look.  So one possible solution is to search the entire /proc/[0-9]*/fd/ tree and look for symlinks that target the file you want to check.

If you're into the popen thing, you can use lsof to get a list of all open files for all processes that you have permissions to examine.  So if you want to get an exhaustive list, you must run lsof as root.  Note that on most distributions of Linux, lsof is in /sbin and not /bin, so you will need to specify the full path when you use popen.

To narrow down the results, run lsof like "/sbin/lsof -F f /path/to/your/file".  lsof will output multiple lines.  If a line starts with "p" then the rest of the line contains a process ID, and all of the lines up to the next "p" will be about this process.  If a line starts with "f" then it means that the rest of the line is an fd held by the process identified on the last "p" line.  If the fd is numeric, then it is just that: the fd.  If it is not, then it will be one of:

* cwd: This is the process' current working folder, which (logically enough) will only show up when the file you have in question is a folder.

* jld: This process is jailed in this directory (i.e. the / folder from this process' perspective is actually the folder you have asked about).

* mem: The file is mapped into memory with a call to mmap(), and therefore has no fd.

* mmap: Same as mem, except that the file is a device node.

* There are a few others that are too obscure to be worth mentioning here.  If you see them, ignore them.

So your job amounts to writing code that will parse the output of lsof.  If you're only after fds, then this simple pseudo-code should work:

popen lsof;
while (still have a line) {
    read the line;
    a_number = decode number starting at line[1];

    switch (first character of line) {
        case 'p':
            allocate fd buffer for "process a_number";

        case 'f':
             append "a_number" to the list of fds for the last process;
    }
}

Yeah, something like that, I guess.

Still wondering /why/ you would ever /want/ this information... and what you plan on /using/ it for...
0
 
LVL 5

Expert Comment

by:crazycomputers
ID: 13504030
Okay, now I feel kinda dumb... looking back on your question:

> I want to know is there any command on LINUX that will do following or I have to write a C program?

Then the simple answer is "yes, you can use lsof."  The columns /should/ be:

* Process name.
* Process ID.
* Real user.
* FD.
* File type (file, char special, block special, fifo...).
* Major/minor numbers for special nodes.
* File size for real files.
* Inode.
* The filename.

Now that was a bit easier than I made it out to be, wasn't it?  =)
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
Examines three attack vectors, specifically, the different types of malware used in malicious attacks, web application attacks, and finally, network based attacks.  Concludes by examining the means of securing and protecting critical systems and inf…
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.
Suggested Courses
Course of the Month9 days, 17 hours left to enroll

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question