2013-11-24 44 views
0

我在inotify的尝试我的手的以下代码段是什么,我认为将是其功能良好的演示缓冲区:读的inotify文件描述符填充二进制垃圾

#include <sys/inotify.h> /* inotify_init(), inotify_add_watch(), IN_* */ 
#include <stdlib.h>  /* EXIT_SUCCESS, EXIT_FAILURE, malloc() */ 
#include <stdio.h>  /* printf(), puts(), perror() */ 
#include <unistd.h>  /* read() */ 
#include <sys/ioctl.h> /* 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, &avail))    PGOTO(failure, "ioctl"); 

    char buffer[avail]; 
    ssize_t count = read(fd, buffer, avail);  /* We fill the buffer */ 
    if(avail > 0 && count < avail)    PGOTO(failure, "read"); 

    printf("Avail: %d, Read: %d\n", (int)avail, (int)count); 
    if(avail > 0) puts(""); 

    for(ssize_t i = 0; i < 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->len), (int)count); 

     if(event->len > 0) {      /* We print its contents */ 
     printf("Name: %s\n", event->name); 
     } printf("Cookie: %d\n", event->cookie); 

     if(event->mask & IN_ACCESS)   puts("IN_ACCESS"); 
     if(event->mask & IN_ATTRIB)   puts("IN_ATTRIB"); 
     if(event->mask & IN_CLOSE_WRITE) puts("IN_CLOSE_WRITE"); 
     if(event->mask & IN_CLOSE_NOWRITE) puts("IN_CLOSE_NOWRITE"); 
     if(event->mask & IN_CREATE)   puts("IN_CREATE"); 
     if(event->mask & IN_DELETE)   puts("IN_DELETE"); 
     if(event->mask & IN_DELETE_SELF) puts("IN_DELETE_SELF"); 
     if(event->mask & IN_MODIFY)   puts("IN_MODIFY"); 
     if(event->mask & IN_MOVE_SELF)  puts("IN_MOVE_SELF"); 
     if(event->mask & IN_MOVED_FROM)  puts("IN_MOVED_FROM"); 
     if(event->mask & IN_MOVED_TO)  puts("IN_MOVED_TO"); 
     if(event->mask & IN_OPEN)   puts("IN_OPEN"); 
     puts(""); 

     i += sizeof(struct inotify_event) + event->len; 

    } 

    } 

    return EXIT_SUCCESS; 

    failure: 
    return EXIT_FAILURE; 

} 

我,然而,从read(2)调用中收到一些无关记录,充满了二进制垃圾。内附有程序后的cat notifyTest.c调用从shell输出:

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 

这是潜在的密码破译,因为该进程将信号SIGSEGV打死,而读event->name如果没有发现任何终止'\0'字符在静态分配的缓冲区的范围内。

这可能是一个怪癖,或者我只是做一些可怕的错误?我uname -a是:

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 

我会为任何指针,以什么可能已经不对劲感谢。

回答

1

你的问题是在这条线:

struct inotify_event* event = (struct inotify_event*)buffer + i; 

该行是铸造指针buffer键入struct inotify_event*,然后在做加法的i,其中,在第二次的迭代,是32那然后递增值由32 * sizeof(struct inotify_event)

的修复将是:

struct inotify_event* event = (struct inotify_event*)(buffer + i); 
+0

显然,谢谢。 – Witiko