Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 581
  • Last Modified:

getting inode from filename and its associated fds

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
b123coder
Asked:
b123coder
  • 4
  • 3
  • 2
  • +1
2 Solutions
 
sunnycoderCommented:
> 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
 
b123coderAuthor Commented:
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
 
sunnycoderCommented:
use popen to read from the command and parse the results

man popen
man pclose
man fgets
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
NovaDenizenCommented:
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
 
b123coderAuthor Commented:
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
 
sunnycoderCommented:
you did not allocate any memory for struct stat

struct stat buf;
err=stat("/root/install.log",&buf);
0
 
b123coderAuthor Commented:
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
 
sunnycoderCommented:
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
 
NovaDenizenCommented:
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
 
crazycomputersCommented:
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
 
crazycomputersCommented:
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

Industry Leaders: 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!

  • 4
  • 3
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now