2013-11-24 72 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