Note that there are some explanatory texts on larger screens.

plurals
  1. POReading inotify file descriptor fills the buffer with binary garbage
    primarykey
    data
    text
    <p>I was trying my hand at inotify and the following snippet of a code is what I thought would be a good demo of its capabilities:</p> <pre><code>#include &lt;sys/inotify.h&gt; /* inotify_init(), inotify_add_watch(), IN_* */ #include &lt;stdlib.h&gt; /* EXIT_SUCCESS, EXIT_FAILURE, malloc() */ #include &lt;stdio.h&gt; /* printf(), puts(), perror() */ #include &lt;unistd.h&gt; /* read() */ #include &lt;sys/ioctl.h&gt; /* ioctl, FIONREAD */ #define PTRY(expr) if((expr) == -1) #define PGOTO(label, msg) do{\ perror(msg);\ goto label;\ } while(0) int main(void) { int fd; PTRY(fd = inotify_init()) PGOTO(failure, "inotify_init"); PTRY(inotify_add_watch(fd, ".", IN_ALL_EVENTS)) PGOTO(failure, "inotify_add_watch"); while(1) { unsigned int avail; /* We find out how large a buffer we need */ PTRY(ioctl(fd, FIONREAD, &amp;avail)) PGOTO(failure, "ioctl"); char buffer[avail]; ssize_t count = read(fd, buffer, avail); /* We fill the buffer */ if(avail &gt; 0 &amp;&amp; count &lt; avail) PGOTO(failure, "read"); printf("Avail: %d, Read: %d\n", (int)avail, (int)count); if(avail &gt; 0) puts(""); for(ssize_t i = 0; i &lt; count; ) { /* For each event structure in the buffer */ struct inotify_event* event = (struct inotify_event*)buffer + i; printf("Byte: %d - %d out of %d\n", (int)i, (int)(sizeof(struct inotify_event) + event-&gt;len), (int)count); if(event-&gt;len &gt; 0) { /* We print its contents */ printf("Name: %s\n", event-&gt;name); } printf("Cookie: %d\n", event-&gt;cookie); if(event-&gt;mask &amp; IN_ACCESS) puts("IN_ACCESS"); if(event-&gt;mask &amp; IN_ATTRIB) puts("IN_ATTRIB"); if(event-&gt;mask &amp; IN_CLOSE_WRITE) puts("IN_CLOSE_WRITE"); if(event-&gt;mask &amp; IN_CLOSE_NOWRITE) puts("IN_CLOSE_NOWRITE"); if(event-&gt;mask &amp; IN_CREATE) puts("IN_CREATE"); if(event-&gt;mask &amp; IN_DELETE) puts("IN_DELETE"); if(event-&gt;mask &amp; IN_DELETE_SELF) puts("IN_DELETE_SELF"); if(event-&gt;mask &amp; IN_MODIFY) puts("IN_MODIFY"); if(event-&gt;mask &amp; IN_MOVE_SELF) puts("IN_MOVE_SELF"); if(event-&gt;mask &amp; IN_MOVED_FROM) puts("IN_MOVED_FROM"); if(event-&gt;mask &amp; IN_MOVED_TO) puts("IN_MOVED_TO"); if(event-&gt;mask &amp; IN_OPEN) puts("IN_OPEN"); puts(""); i += sizeof(struct inotify_event) + event-&gt;len; } } return EXIT_SUCCESS; failure: return EXIT_FAILURE; } </code></pre> <p>I am, however, receiving some extraneous records from the <code>read(2)</code> call, filled with binary rubbish. Enclosed is the output of the program upon the invocation of <code>cat notifyTest.c</code> from the shell:</p> <pre><code>Avail: 0, Read: -1 Avail: 64, Read: 64 Byte: 0 - 32 out of 64 Name: notifyTest.c Cookie: 0 IN_OPEN Byte: 32 - 32783 out of 64 Name: ▒▒▒ Cookie: 1726459283 IN_ACCESS IN_ATTRIB IN_CLOSE_WRITE IN_CLOSE_NOWRITE IN_CREATE IN_DELETE IN_DELETE_SELF IN_MODIFY IN_MOVE_SELF IN_MOVED_FROM IN_MOVED_TO IN_OPEN Avail: 0, Read: -1 Avail: 32, Read: 32 Byte: 0 - 32 out of 32 Name: notifyTest.c Cookie: 0 IN_CLOSE_NOWRITE </code></pre> <p>This is potentially code-breaking, since the process would be signaled <code>SIGSEGV</code> and killed while reading <code>event-&gt;name</code> if there weren't any terminating <code>'\0'</code> character within the bounds of the statically allocated buffer.</p> <p>Could this be a quirk, or am I just doing something terribly wrong? My <code>uname -a</code> is:</p> <pre><code>Linux witiko-D830 3.8.0-32-generic #47-Ubuntu SMP Tue Oct 1 22:35:23 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux </code></pre> <p>I'll be grateful for any pointers as to what could have gone amiss.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload