Finally, we can also find out about the interrupts that are associated with a process.

We use the DCMD_PROC_IRQS command, and expect to get back zero or more data structures, as we did in the DCMD_PROC_PAGEDATA, DCMD_PROC_MAPINFO, and DCMD_PROC_TIMERS examples above. The structure procfs_irq is the same as the debug_irq_t, which is defined as follows:

typedef struct _debug_irq {
  pid_t             pid;
  pthread_t         tid;
  const struct sigevent *(*handler)(void *area, int id);
  void              *area;
  unsigned          flags;
  unsigned          level;
  unsigned          mask_count;
  int               id;
  unsigned          vector;
  struct sigevent   event;
} debug_irq_t;

To fetch the data, we use code similar to what we used with the timers and memory segments:

#define MAX_IRQS  512

static void
dump_procfs_irq (int fd, int pid)
  procfs_irq    irqs [MAX_IRQS];
  int           nirqs;
  int           i;

  // fetch information about the IRQs for this pid
  if (devctl (fd, DCMD_PROC_IRQS, irqs, sizeof (irqs),
              &nirqs) != EOK) {
    fprintf (stderr, "%s:  IRQS proc %d, errno %d (%s)\n",
             progname, pid, errno, strerror (errno));
    exit (EXIT_FAILURE);

  if (nirqs > MAX_IRQS) {
    fprintf (stderr, "%s: proc %d > %d IRQs (%d) !!! ***\n",
             progname, pid, MAX_IRQS, nirqs);
    exit (EXIT_FAILURE);

  printf ("Info from DCMD_PROC_IRQS\n");
  for (i = 0; i < nirqs; i++) {
    // print information here
  printf ("\n");

Since our pipe command doesn't use interrupts either, I've once again selected devb-eide:

  Buffer       0
    pid        6
    tid        2
    handler    0x00000000
    area       0xEFFF7168
    flags      0x0000000E
    level      14
    mask_count 0
    id         2
    vector     14
    event (sigev_notify type 4)
      SIGEV_PULSE (sigev_coid 1073741826,
                   sigev_value.sival_int 0,
                   sigev_priority 21, sigev_code 2)
  Buffer       1
    pid        6
    tid        3
    handler    0x00000000
    area       0xEFFF71E0
    flags      0x0000000E
    level      15
    mask_count 0
    id         3
    vector     15
    event (sigev_notify type 4)
      SIGEV_PULSE (sigev_coid 1073741829,
                   sigev_value.sival_int 0,
                   sigev_priority 21, sigev_code 2)

The members of the debug_irq_t shown above are as follows:

pid and tid
The pid and tid fields give the process ID and the thread ID (obviously, it will be process ID 6, which is devb-eide).
handler and area
Indicates the interrupt service routine address, and its associated parameter. The fact that the interrupt handler address is zero indicates that there is no real interrupt vector associated with the interrupts; rather, the event (a pulse in both cases) should be returned (i.e. the interrupt was attached with InterruptAttachEvent() rather than InterruptAttach()). In the case of the handler being zero, the area member is not important.
The flags value is hexadecimal 0x0E, which is composed of the bits _NTO_INTR_FLAGS_SMPRDY, _NTO_INTR_FLAGS_PROCESS, and _NTO_INTR_FLAGS_TRK_MSK, meaning, respectively, that the interrupt handler is SMP-capable (this flag is deprecated in version 6.3; everything must be SMP-ready then), the interrupt belongs to the process (rather than the thread), and the number of times the interrupt is masked and unmasked should be kept track of.
level and vector
This is the interrupt level and vector for this particular interrupt. For an x86 architecture, they happen to be the same number. (The level is an internal kernel number and has no meaning for the end-user.) In our example, devb-eide is attached to two interrupt sources (as defined by the vector parameter; i.e. interrupts 14 and 15, the two EIDE controllers on my PC).
Indicates the number of times the interrupt is masked (0 indicates the interrupt is not masked). Useful as a diagnostic aid when you are trying to determine why your interrupt fires only once. :-)
This is the interrupt identification number returned by InterruptAttach() or InterruptAttachEvent().
A standard struct sigevent that determines what the InterruptAttachEvent() should do when it fires.