114: free(file->name);
115:
116: if (!prev) {
117: /* удалить головной узел */
118: list = file->next;
119: free(file);
120: file = list;
121: } else {
122: prev->next = file->next;
123: free(file);
124: file = prev->next;
125: }
126: } else {
127: prev = file;
128: file = file->next;
129: }
130: }
131:
132: *listPtr = list;
133:
134: return 0;
135: }
136:
137: void handler(int sig, siginfo_t * siginfo, void * context) {
138: int i;
139:
140: for (i = 0; directoryList[i].path; i++) {
141: if (directoryList[i].fd == siginfo->si_fd) {
142: directoryList[i].changed = 1;
143: return;
144: }
145: }
146: }
147:
148: int main(int argc, char ** argv) {
149: struct sigaction act;
150: sigset_t mask, sigio;
151: int i;
152:
153: /* Блокировать SIGRTMIN. Мы не хотим получать его нигде,
154: кроме как внутри системного вызова sigsuspend(). */
155: sigemptyset(&sigio);
156: sigaddset(&sigio, SIGRTMIN);
157: sigprocmask(SIG_BLOCK, &sigio, &mask);
158:
159: act.sa_sigaction = handler;
160: act.sa_flags = SA_SIGINFO;
161: sigemptyset(&act.sa_mask);
162: sigaction(SIGRTMIN, &act, NULL);
163:
164: if (!argv[1]) {
165: /* ни одного аргумента не передано, привести argc/argv
166: к виду '.', как будто передается единственный аргумент */
167: argv[1] = '.';
168: argc++;
169: }
170:
171: /* каждый аргумент представляет собой отслеживаемый каталог */
172: directoryList = malloc(sizeof(*directoryList) * argc);
173: directoryList[argc - 1].path = NULL;
174:
175: for (i = 0; i < (argc - 1); i++) {
176: directoryList[i].path = argv[i + 1];
177: if ((directoryList[i].fd =
178: open(directoryList[i].path, O_RDONLY)) < 0) {
179: fprintf(stderr, 'ошибка при открытии %s: %s
',
180: directoryList[i].path, strerror(errno));
181: return 1;
182: }
183:
184: /* Отслеживание каталога перед первым сканированием;
185: это гарантирует, что мы захватим файлы, созданные кем-то
186: во время сканирования каталога. Если кто-то изменит его,
187: будет сгенерирован сигнал (и заблокирован, пока
188: мы не будем готовы принять его) */
189: if (fcntl(directoryList[i].fd, F_NOTIFY, DN_DELETE |
190: DN_CREATE | DN_RENAME | DN_MULTISHOT) ) {
191: perror('fcntl F_NOTIFY');
192: return 1;
193: }
194:
195: fcntl(directoryList[i].fd, F_SETSIG, SIGRTMIN);
196:
197: if (build DirectoryList(directoryList[i].path,
198: &directoryList[i].contents))
199: return 1;
200: }
201:
202: while (1) {
203: sigsuspend(&mask);
204:
205: for (i = 0; directoryList[i].path; i++)
206: if (directoryList[i].changed)
207: if (updateDirectoryList(directoryList[i].path,
208: &directoryList[i].contents))
209: return 1;
210: }
211:
212: return 0;
