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