proc_pid_fdinfo(5)

๐Ÿ’– proc_pid_fdinfo(5) โ€” the /proc/pid/fdinfo/ glow-up ๐Ÿ’–

okay bestie, this one lives in the File Formats Manual section of the man pages, and it's genuinely one of the cutest little corners of procfs. let's get into it โœจ


๐ŸŒธ NAME ๐ŸŒธ

/proc/pid/fdinfo/ โ€” all the tea about your file descriptors ๐Ÿซ–


โœจ DESCRIPTION โœจ

so, /proc/pid/fdinfo/ is a subdirectory, right? and inside it there's one entry for every single file the process has open, and each entry is named after that file's file descriptor. no cap. ๐ŸŽ€

heads up: these files are readable only by the owner of the process. it's giving exclusivity, it's giving VIP only ๐Ÿ’…

you can read the contents of each file to get info about the corresponding file descriptor. and here's the thing โ€” the content depends on the type of file that the file descriptor points at. so the vibe check changes depending on what you're looking at ๐Ÿ‘‘


๐Ÿ“ for regular files and directories

you'll see something like this:

$ cat /proc/12015/fdinfo/4
pos:    1000
flags:  01002002
mnt_id: 21
ino:    63107

and here's what every field is doing:

  • pos โ€” a decimal number showing the file offset. literally just where you're at in the file ๐Ÿ“
  • flags โ€” an octal number showing the file access mode and the file status flags (peep open(2) for the deets). and if the close-on-exec file descriptor flag is set, then flags will also include the value O_CLOEXEC ๐Ÿ’ซ
    • warning bestie: before Linux 3.1, this field was a whole liar โ€” it incorrectly displayed the setting of O_CLOEXEC at the time the file was opened, rather than the current setting of the close-on-exec flag. glow-up came in 3.1, we love to see it ๐Ÿ’€
  • mnt_id โ€” present since Linux 3.15, this is the decimal ID of the mount containing this file. see the description of /proc/pid/mountinfo for more ๐Ÿ—‚๏ธ
  • ino โ€” present since Linux 5.14, this is the decimal inode number of the file. iconic number behavior โญ

๐ŸŒˆ for eventfd file descriptors

(see eventfd(2)) โ€” since Linux 3.8, we get these fields:

pos:    0
flags:  02
mnt_id: 10
ino:    63107
eventfd-count:               40

eventfd-count is the current value of the eventfd counter, expressed in hexadecimal. slay ๐Ÿ”ฅ


๐Ÿฆ‹ for epoll file descriptors

(see epoll(7)) โ€” since Linux 3.8, we get:

pos:    0
flags:  02
mnt_id: 10
ino:    63107
tfd:        9 events:       19 data: 74253d2500000009
tfd:        7 events:       19 data: 74253d2500000007

every line starting with tfd describes one of the file descriptors being monitored through that epoll file descriptor (check epoll_ctl(2) for some details). and the fields break down like this:

  • tfd โ€” the number of the file descriptor ๐ŸŽฏ
  • events โ€” a hexadecimal mask of the events being monitored for this file descriptor ๐Ÿ‘€
  • data โ€” the data value associated with this file descriptor ๐Ÿ“ฆ

๐Ÿงš for signalfd file descriptors

(see signalfd(2)) โ€” since Linux 3.8, here's what we see:

pos:    0
flags:  02
mnt_id: 10
ino:    63107
sigmask:        0000000000000006

sigmask is the hexadecimal mask of signals that are accepted via this signalfd file descriptor. (in this little example here, bits 2 and 3 are set, which corresponds to the signals SIGINT and SIGQUIT โ€” check signal(7) for the lore.) ๐Ÿ“ก


๐ŸŽ€ for inotify file descriptors

(see inotify(7)) โ€” since Linux 3.8, we get:

pos:    0
flags:  00
mnt_id: 11
ino:    63107
inotify wd:2 ino:7ef82a sdev:800001 mask:800afff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:2af87e00220ffd73
inotify wd:1 ino:192627 sdev:800001 mask:800afff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:27261900802dfd73

every line that starts with "inotify" is spilling info about one file or directory being monitored. the fields go like this:

  • wd โ€” a watch descriptor number (in decimal) ๐Ÿ‘๏ธ
  • ino โ€” the inode number of the target file (in hexadecimal) ๐Ÿ”ข
  • sdev โ€” the ID of the device where the target file resides (in hexadecimal) ๐Ÿ’พ
  • mask โ€” the mask of events being monitored for the target file (in hexadecimal) ๐ŸŽญ

and if the kernel was built with exportfs support, the path to the target file is exposed as a file handle, via three hexadecimal fields: fhandle-bytes, fhandle-type, and f_handle. ok slay ๐Ÿซถ


๐Ÿ‘‘ for fanotify file descriptors

(see fanotify(7)) โ€” since Linux 3.8, we see:

pos:    0
flags:  02
mnt_id: 11
ino:    63107
fanotify flags:0 event-flags:88002
fanotify ino:19264f sdev:800001 mflags:0 mask:1 ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:4f261900a82dfd73

the fourth line here is showing off information that was defined when the fanotify group was created via fanotify_init(2):

  • flags โ€” the flags argument that was given to fanotify_init(2) (expressed in hexadecimal) ๐Ÿšฉ
  • event-flags โ€” the event_f_flags argument that was given to fanotify_init(2) (expressed in hexadecimal) ๐Ÿด

and then each additional line shown in the file contains info about one of the marks in the fanotify group. most of these fields are exactly as for inotify โ€” except:

  • mflags โ€” the flags associated with the mark (expressed in hexadecimal) ๐Ÿท๏ธ
  • mask โ€” the events mask for this mark (expressed in hexadecimal) ๐ŸŽญ
  • ignored_mask โ€” the mask of events that are ignored for this mark (expressed in hexadecimal) ๐Ÿ™ˆ

for details on all these fields, go read fanotify_mark(2). iykyk ๐Ÿ“š


โฐ for timerfd file descriptors

(see timerfd(2)) โ€” since Linux 3.17, we get these fields:

pos:    0
flags:  02004002
mnt_id: 13
ino:    63107
clockid: 0
ticks: 0
settime flags: 03
it_value: (7695568592, 640020877)
it_interval: (0, 0)
  • clockid โ€” this is the numeric value of the clock ID (corresponding to one of the CLOCK_* constants defined via <time.h>) that's used to mark the progress of the timer. (in this example, 0 is CLOCK_REALTIME.) ๐Ÿ•ฐ๏ธ
  • ticks โ€” this is the number of timer expirations that have occurred โ€” like, the value that read(2) on it would return. ๐Ÿ””
  • settime flags โ€” this field lists the flags with which the timerfd was last armed (see timerfd_settime(2)), in octal. (in this example, both TFD_TIMER_ABSTIME and TFD_TIMER_CANCEL_ON_SET are set.) โš™๏ธ
  • it_value โ€” this field contains the amount of time until the timer will next expire, expressed in seconds and nanoseconds. and listen โ€” this is always expressed as a relative value, regardless of whether the timer was created using the TFD_TIMER_ABSTIME flag. no wiggle room bestie โณ
  • it_interval โ€” this field contains the interval of the timer, in seconds and nanoseconds. (both it_value and it_interval contain the values that timerfd_gettime(2) on this file descriptor would return.) ๐Ÿ”

๐Ÿ“œ HISTORY ๐Ÿ“œ

Linux 2.6.22. vintage but still serving ๐Ÿ’


๐Ÿซถ SEE ALSO ๐Ÿซถ


aaaand that's the whole page, bestie ๐Ÿ’– this has been the proc_pid_fdinfo(5) manual page from Linux man-pages 6.20, dated 2026-07-18 โ€” go read your file descriptors, they're literally waiting for you โœจ๐Ÿ‘‘๐Ÿ’…

๐Ÿ“ฆ where this page comes from
  • arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
  • nixpkgs unstable: man-pages 6.20
  • ๐Ÿ“œ the page's license: GPL-3.0-or-later
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms