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