blob: 8ce346c56d1ad11fc8c8f21224967ff89d213f07 [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)) {
Johan Redestig80bf9a42014-11-20 14:26:16 +0100104 char* filename = file_names[event->wd + id_offset];
105 char* alloc_buf = NULL;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800106 ssize_t read_len;
107 char *display_name;
108 int buflen;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800109 if(event->len) {
Johan Redestig80bf9a42014-11-20 14:26:16 +0100110 if(asprintf(&alloc_buf, "%s/%s", filename, event->name) < 0) {
111 fprintf(stderr, "asprintf failed, %s\n", strerror(errno));
112 return 1;
113 }
114 filename = alloc_buf;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800115 }
116 ffd = open(filename, O_RDONLY);
117 display_name = (verbose >= 2 || event->len == 0) ? filename : event->name;
118 buflen = width - strlen(display_name);
119 read_len = read(ffd, buf, buflen);
120 if(read_len > 0) {
121 if(read_len < buflen && buf[read_len-1] != '\n') {
122 buf[read_len] = '\n';
123 read_len++;
124 }
125 if(read_len == buflen) {
126 buf[--read_len] = '\0';
127 buf[--read_len] = '\n';
128 buf[--read_len] = '.';
129 buf[--read_len] = '.';
130 buf[--read_len] = '.';
131 }
132 else {
133 buf[read_len] = '\0';
134 }
135 printf("%s: %s", display_name, buf);
136 }
137 close(ffd);
Johan Redestig80bf9a42014-11-20 14:26:16 +0100138 free(alloc_buf);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800139 }
140 if(event_count && --event_count == 0)
141 return 0;
142 event_size = sizeof(*event) + event->len;
143 res -= event_size;
144 event_pos += event_size;
145 }
146 }
147
148 return 0;
149}