notify.c revision dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdint.h> 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h> 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/ioctl.h> 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/inotify.h> 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint notify_main(int argc, char *argv[]) 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int c; 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int nfd, ffd; 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int res; 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char event_buf[512]; 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct inotify_event *event; 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int event_mask = IN_ALL_EVENTS; 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int event_count = 1; 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int print_files = 0; 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int verbose = 2; 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int width = 80; 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char **file_names; 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int file_count; 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int id_offset = 0; 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i; 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *buf; 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do { 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c = getopt(argc, argv, "m:c:pv:w:"); 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (c == EOF) 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch (c) { 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'm': 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project event_mask = strtol(optarg, NULL, 0); 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'c': 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project event_count = atoi(optarg); 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'p': 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project print_files = 1; 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'v': 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project verbose = atoi(optarg); 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'w': 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project width = atoi(optarg); 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case '?': 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "%s: invalid option -%c\n", 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project argv[0], optopt); 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(1); 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } while (1); 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (argc <= optind) { 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "Usage: %s [-m eventmask] [-c count] [-p] [-v verbosity] path [path ...]\n", argv[0]); 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project nfd = inotify_init(); 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(nfd < 0) { 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "inotify_init failed, %s\n", strerror(errno)); 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project file_names = argv + optind; 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project file_count = argc - optind; 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(i = 0; i < file_count; i++) { 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project res = inotify_add_watch(nfd, file_names[i], event_mask); 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(res < 0) { 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "inotify_add_watch failed for %s, %s\n", file_names[i], strerror(errno)); 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(i == 0) 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project id_offset = -res; 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(res + id_offset != i) { 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "%s got unexpected id %d instead of %d\n", file_names[i], res, i); 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buf = malloc(width + 2); 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(1) { 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int event_pos = 0; 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project res = read(nfd, event_buf, sizeof(event_buf)); 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(res < (int)sizeof(*event)) { 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(errno == EINTR) 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "could not get event, %s\n", strerror(errno)); 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //printf("got %d bytes of event information\n", res); 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(res >= (int)sizeof(*event)) { 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int event_size; 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project event = (struct inotify_event *)(event_buf + event_pos); 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(verbose >= 2) 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("%s: %08x %08x \"%s\"\n", file_names[event->wd + id_offset], event->mask, event->cookie, event->len ? event->name : ""); 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else if(verbose >= 2) 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("%s: %08x \"%s\"\n", file_names[event->wd + id_offset], event->mask, event->len ? event->name : ""); 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else if(verbose >= 1) 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("%d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : ""); 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(print_files && (event->mask & IN_MODIFY)) { 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char filename[512]; 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ssize_t read_len; 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *display_name; 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int buflen; 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy(filename, file_names[event->wd + id_offset]); 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(event->len) { 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcat(filename, "/"); 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcat(filename, event->name); 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ffd = open(filename, O_RDONLY); 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project display_name = (verbose >= 2 || event->len == 0) ? filename : event->name; 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buflen = width - strlen(display_name); 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project read_len = read(ffd, buf, buflen); 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(read_len > 0) { 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(read_len < buflen && buf[read_len-1] != '\n') { 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buf[read_len] = '\n'; 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project read_len++; 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(read_len == buflen) { 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buf[--read_len] = '\0'; 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buf[--read_len] = '\n'; 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buf[--read_len] = '.'; 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buf[--read_len] = '.'; 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buf[--read_len] = '.'; 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else { 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buf[read_len] = '\0'; 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("%s: %s", display_name, buf); 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(ffd); 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(event_count && --event_count == 0) 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project event_size = sizeof(*event) + event->len; 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project res -= event_size; 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project event_pos += event_size; 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 145