diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
commit | 4f6e8d7a00cbeda1e70cc15be9c4af1018bdad53 (patch) | |
tree | 54fd1b2695a591d2306d41264df67c53077b752c /toolbox/notify.c | |
download | core-4f6e8d7a00cbeda1e70cc15be9c4af1018bdad53.tar.gz core-4f6e8d7a00cbeda1e70cc15be9c4af1018bdad53.tar.bz2 core-4f6e8d7a00cbeda1e70cc15be9c4af1018bdad53.zip |
Initial Contribution
Diffstat (limited to 'toolbox/notify.c')
-rw-r--r-- | toolbox/notify.c | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/toolbox/notify.c b/toolbox/notify.c new file mode 100644 index 000000000..b1761d299 --- /dev/null +++ b/toolbox/notify.c @@ -0,0 +1,144 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <sys/inotify.h> +#include <errno.h> + +int notify_main(int argc, char *argv[]) +{ + int c; + int nfd, ffd; + int res; + char event_buf[512]; + struct inotify_event *event; + int event_mask = IN_ALL_EVENTS; + int event_count = 1; + int print_files = 0; + int verbose = 2; + int width = 80; + char **file_names; + int file_count; + int id_offset = 0; + int i; + char *buf; + + do { + c = getopt(argc, argv, "m:c:pv:w:"); + if (c == EOF) + break; + switch (c) { + case 'm': + event_mask = strtol(optarg, NULL, 0); + break; + case 'c': + event_count = atoi(optarg); + break; + case 'p': + print_files = 1; + break; + case 'v': + verbose = atoi(optarg); + break; + case 'w': + width = atoi(optarg); + break; + case '?': + fprintf(stderr, "%s: invalid option -%c\n", + argv[0], optopt); + exit(1); + } + } while (1); + + if (argc <= optind) { + fprintf(stderr, "Usage: %s [-m eventmask] [-c count] [-p] [-v verbosity] path [path ...]\n", argv[0]); + return 1; + } + + nfd = inotify_init(); + if(nfd < 0) { + fprintf(stderr, "inotify_init failed, %s\n", strerror(errno)); + return 1; + } + file_names = argv + optind; + file_count = argc - optind; + for(i = 0; i < file_count; i++) { + res = inotify_add_watch(nfd, file_names[i], event_mask); + if(res < 0) { + fprintf(stderr, "inotify_add_watch failed for %s, %s\n", file_names[i], strerror(errno)); + return 1; + } + if(i == 0) + id_offset = -res; + if(res + id_offset != i) { + fprintf(stderr, "%s got unexpected id %d instead of %d\n", file_names[i], res, i); + return 1; + } + } + + buf = malloc(width + 2); + + while(1) { + int event_pos = 0; + res = read(nfd, event_buf, sizeof(event_buf)); + if(res < (int)sizeof(*event)) { + if(errno == EINTR) + continue; + fprintf(stderr, "could not get event, %s\n", strerror(errno)); + return 1; + } + //printf("got %d bytes of event information\n", res); + while(res >= (int)sizeof(*event)) { + int event_size; + event = (struct inotify_event *)(event_buf + event_pos); + if(verbose >= 2) + printf("%s: %08x %08x \"%s\"\n", file_names[event->wd + id_offset], event->mask, event->cookie, event->len ? event->name : ""); + else if(verbose >= 2) + printf("%s: %08x \"%s\"\n", file_names[event->wd + id_offset], event->mask, event->len ? event->name : ""); + else if(verbose >= 1) + printf("%d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : ""); + if(print_files && (event->mask & IN_MODIFY)) { + char filename[512]; + ssize_t read_len; + char *display_name; + int buflen; + strcpy(filename, file_names[event->wd + id_offset]); + if(event->len) { + strcat(filename, "/"); + strcat(filename, event->name); + } + ffd = open(filename, O_RDONLY); + display_name = (verbose >= 2 || event->len == 0) ? filename : event->name; + buflen = width - strlen(display_name); + read_len = read(ffd, buf, buflen); + if(read_len > 0) { + if(read_len < buflen && buf[read_len-1] != '\n') { + buf[read_len] = '\n'; + read_len++; + } + if(read_len == buflen) { + buf[--read_len] = '\0'; + buf[--read_len] = '\n'; + buf[--read_len] = '.'; + buf[--read_len] = '.'; + buf[--read_len] = '.'; + } + else { + buf[read_len] = '\0'; + } + printf("%s: %s", display_name, buf); + } + close(ffd); + } + if(event_count && --event_count == 0) + return 0; + event_size = sizeof(*event) + event->len; + res -= event_size; + event_pos += event_size; + } + } + + return 0; +} |