-1

I'm trying to do some work with inotify and better understand C in general. I'm very novice. I was looking over the inotify man page and I saw an example of using inotify. I have some questions around how exactly they use buffers. The code is here:

http://man7.org/linux/man-pages/man7/inotify.7.html

The block I'm most interested is:

       char buf[4096]
           __attribute__ ((aligned(__alignof__(struct inotify_event))));
       const struct inotify_event *event;
       int i;
       ssize_t len;
       char *ptr;

       /* Loop while events can be read from inotify file descriptor. */

       for (;;) {

           /* Read some events. */

           len = read(fd, buf, sizeof buf);
           if (len == -1 && errno != EAGAIN) {
               perror("read");
               exit(EXIT_FAILURE);
           }

           /* If the nonblocking read() found no events to read, then
              it returns -1 with errno set to EAGAIN. In that case,
              we exit the loop. */

           if (len <= 0)
               break;

           /* Loop over all events in the buffer */

           for (ptr = buf; ptr < buf + len;
                   ptr += sizeof(struct inotify_event) + event->len) {

               event = (const struct inotify_event *) ptr;

What I'm trying to understand is is how exactly are the processing the bits in this buffer. This is what I know:

We define a char buf of 4096, which means we have a buffer just about 4kbs of size. When call read(fd, buf, sizeof buf) and len will be anywhere from 0 - 4096 (partial reads can occur).

We do some async checking, that's obvious.

Now we get to the for loop, here is where I'm a little confused. We set ptr equal to buf and then compare ptr's size to buff + len.

At this point does ptr equal the value '4096' ? And if so we are saying; is ptr:4096 < buf:4096 + len:[0-4096]. I'm using a colon here to signify what I think the variable's value is and [] meaning a range.

We then as the iterator expression, increase ptr+= the size of an inotify event.

I'm used to higher level OOP languages, in which I'd declare a buffer of 'inotify_event' objects. However I'm assuming since we are just getting back a byte array from 'read' we need to pull off the bites at the 'inotify_event' boundary and type cast those bits into an event object. Does this sounds correct?

Also I'm not exactly sure how comparison works with a buf[4096] values. We don't have concept of checking an array's current size (allocated indexes) so I'm assuming when used in comparison, we are comparing the size of it's allocated memory space '4096' in this case?

Thanks for the help, this is my first time really working with processing bits off a buffer. Trying to wrap my head around all this. Any further reading would be helpful! I've been finding a good amount of reading on C as a language, a good amount of reading on linux systems programming, but I can't seem to find topics such as 'working with buffers' or the grey area between the two.

DYZ
  • 55,249
  • 10
  • 64
  • 93
Louis_Santos
  • 1
  • 1
  • 3

2 Answers2

0

When you do the assignment ptr = buf in C, you are assigning the address of the first element of buf to ptr. Thus, the comparison is checking whether ptr has gone beyond the end of the buffer.

The loop is jumping by the number of bytes needed to skip over one struct inotify_event, which is defined here, and the length of the name of the event.

merlin2011
  • 71,677
  • 44
  • 195
  • 329
0
ptr = buf

You are assigning the address of the first element of buf (i.e &buf[0]) to the pointer ptr. So you are starting looping through the buf using a pointer starting from the first element.

ptr < buf + len;

This is checking that your ptr pointer is "moving" through the array until the end of buf. It is made using pointer arithmetic. So the loop compare addresses of ptr pointed address with the address of buf + the len of buffer returned by read function.

ptr += sizeof(struct inotify_event) + event->len

Lastly the pointer is moved forward of size of the event struct struct inotify_event plus the event len, that I guess is variable based on the event type.

LPs
  • 16,045
  • 8
  • 30
  • 61