2014-07-04 1 views
2

inotify를 테스트하고 싶었 기 때문에 인터넷에서 몇 가지 예제를 가져 와서 다양한 측면을 배우기 위해 수정했지만 실패한 것처럼 작동하지 않았습니다. 처음에는 꽤 잘 작동하는 디렉토리를 살펴 보았습니다. inotify api가 한 두 번보고 한 후에 작동을 멈 춥니 다.

그래서 내가 약간의 수정과 파일이 예를 확장하지만 한 번만 작동하고

#include <sys/inotify.h> 
#include <unistd.h> 
#include <stdio.h> 

#define EVENT_SIZE (sizeof (struct inotify_event)) 
#define BUF_LEN  (16 * (EVENT_SIZE + 16)) 

int main() 
{ 
    int fd; 
    fd = inotify_init(); 
    if (fd < 0) 
     perror("inotify_init()"); 
     int wd; 
     wd = inotify_add_watch(fd, "target", IN_CLOSE_WRITE); 
    if (wd < 0) 
     perror("inotify_add_watch"); 

    char buf[BUF_LEN]; 
    int len; 

    while(1) { 

     len = read(fd, buf, BUF_LEN); 

     printf("after read\n"); 

     if (len > 0) 
     { 
      int i = 0; 
      while (i < len) 
      { 
       struct inotify_event *event; 
       event = (struct inotify_event *) &buf[i]; 

       printf("wd=%d mask=%x cookie=%u len=%u\n", 
        event->wd, event->mask, 
        event->cookie, event->len); 

       if (event->mask & IN_MODIFY) 
       printf("file modified %s", event->name); 

       if (event->len) 
       printf("name=%s\n", event->name); 

       i += EVENT_SIZE + event->len; 
      } 
     } 

    } 

    return 0; 
} 

그래서 읽기 기능이 차단됩니다, i)는 (선택 이동하지만, 여기 또한, 그것은 작동 한 번, 두 번 신고 한 다음 변경 사항을보고하지 않습니다.

#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <sys/types.h> 
#include <sys/inotify.h> 

#define EVENT_SIZE (sizeof (struct inotify_event)) 
#define BUF_LEN  (1024 * (EVENT_SIZE + 16)) 

int main(int argc, char **argv) 
{ 
int length, i = 0; 
int fd; 
int wd; 
char buffer[BUF_LEN]; 

struct timeval timeout; 

fd = inotify_init(); 

if (fd < 0) { 
    perror("inotify_init"); 
} 

wd = inotify_add_watch(fd, "target", 
         IN_CLOSE_WRITE); 
fd_set rfds,rfdss; 
int ret; 

/* zero-out the fd_set */ 
FD_ZERO (&rfds); 
FD_ZERO (&rfdss); 
FD_SET (fd, &rfds); 

timeout.tv_sec = 5;  
timeout.tv_usec = 0; 

while(1){ 
    printf("Before select\n"); 
    //rfds = rfdss; 
    ret = select (fd + 1, &rfds, NULL, NULL, NULL); 
    printf("After Select\n"); 
    timeout.tv_sec = 5;  
    timeout.tv_usec = 0; 
    if (ret < 0) 
      perror ("select"); 
    else if (!ret){ 
    } 
      /* timed out! */ 
    else if (FD_ISSET (fd, &rfds)){ 
      printf("file changed============\n"); 
      length = read(fd, buffer, BUF_LEN); 
    } 
} 

    (void) inotify_rm_watch(fd, wd); 
(void) close(fd); 

exit(0); 
} 

답변

1

인기있는 편집자는 다른 방식으로이를 저장한다는 것을 보여주었습니다.

직접 파일을 덮어 쓰지 않고 실제로 임시 파일을 만든 다음 원본 파일을 새 임시 파일로 바꿉니다. 그래서 실제로 일어나는 일은 당신이 실제로보고 있던 파일이 더 이상 존재하지 않으므로 어떤 변경도 반영되지 않습니다. 실제로이 방법을 수행

편집자는 (더 많은 존재)의 gedit, Geany 직접 파일을 덮어 VI

편집자가 따라서

심지어 코드 비록 나노 (더 많은 존재) 편집자의 비정상적인 동작이 차단 읽기 호출에 대한

0

문제가 올바른 될 수 있었다, 참조 : https://stackoverflow.com/a/914520/149111

당신은 또한 전환 할 수 있습니다 IN_CLOSE_WRITE에서 IN_ALL_EVENTS (으)로 뭔가를 놓치지 않았는지 확인하십시오. 가능성이있는 삭제 :

개별 파일이 아닌 관심있는 파일이 포함 된 디렉토리를 보는 것이 좋습니다. 커널의 리소스를 적게 사용하기 때문입니다. 또한 작성자가 파일 시스템에 임시 파일을 작성하고 (동일한 디렉토리에있을 수도 있음) 임시 파일에 쓰고 마지막에 rename(2) 원본의 맨 위에있는 "원자"파일 대체 작업을 관찰 할 수 있습니다 파일.

이 대체 스타일은 파일의 옵서버가 파일의 전체 내용 만 인식하고 절반 만 작성된 버전은 아닌 것을 확인합니다.

관련 문제