Example #1
0
int main(int argc, char **argv)
{
	struct sigaction sa;
	int inotify_fd;
	int ret;
	int pid_fd;

	sigemptyset(&sa.sa_mask);
	sa.sa_handler = signal_handler;
	sa.sa_flags = SA_RESTART;

	if (sigaction(SIGHUP, &sa, NULL) < 0) {
		syslog(LOG_ERR, "failed to listen for signal SIGHUP : %m");
		exit(EXIT_FAILURE);
	}

	if (sigaction(SIGTERM, &sa, NULL) < 0) {
		syslog(LOG_ERR, "failed to listen for signal SIGTERM : %m");
		exit(EXIT_FAILURE);
	}

	pid_fd = daemonize();
	if (pid_fd < 0)
		exit(EXIT_FAILURE);

	clear_all_rules();
	load_all_rules();

	inotify_fd = configure_inotify();

	while (inotify_fd >= 0 && !terminate && !restart) {
		ret = monitor(inotify_fd);
		if (ret < 0 && errno == EINTR) {
			continue;
		}
		else if (ret < 0) {
			syslog(LOG_ERR, "Failed to monitor properly : %m");
			break;
		}

		ret = handle_inotify_event(inotify_fd);
		if (ret < 0)
			break;
	}

	close(pid_fd);
	remove(PID_FILE);

	if (restart && execv(argv[0], argv))
		syslog(LOG_ERR, "Failed to restart : %m");

	clear_all_rules();

	syslog(LOG_DEBUG, "Finished %s", argv[0]);
	exit(terminate == 1 ? EXIT_SUCCESS : EXIT_FAILURE);
}
Example #2
0
int process_inotify_event(int fd)
{
    char buffer[512];
    int len;
    int offset = 0;

    if ((len = read(fd, buffer, sizeof(buffer))) < 0) {
        LOGE("Unable to read inotify event (%m)\n");
        return -errno;
    }

    while (len >= (int) sizeof(struct inotify_event)) {
        struct inotify_event *evt = (struct inotify_event *) &buffer[offset];

        if (handle_inotify_event(evt) < 0)
            LOGE("Error handling inotify event (%m)\n");

        len -= sizeof(struct inotify_event) + evt->len;
        offset += sizeof(struct inotify_event) + evt->len;

    }
    return 0;
}
Example #3
0
static int watch_files(struct file_struct *_files, int n_files)
{
	int ifd, i;
	char buf[n_files * INOTIFY_BUFLEN];

	ifd = inotify_init();
	if (errno == ENOSYS) {
		fprintf(stderr, "Error: inotify is not supported by the kernel you're currently running.\n");
		exit(EXIT_FAILURE);
	} else if (unlikely(ifd < 0)) {
		fprintf(stderr, "Error: Could not initialize inotify (%s)\n", strerror(errno));
		exit(EXIT_FAILURE);
	}

	for (i = 0; i < n_files; i++) {
		if (!_files[i].ignore) {
			_files[i].i_watch = inotify_add_watch(ifd, _files[i].name,
						IN_MODIFY|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT);

			if (_files[i].i_watch < 0) {
				fprintf(stderr, "Error: Could not create inotify watch on file '%s' (%s)\n",
						_files[i].name, strerror(errno));
				ignore_file(&_files[i]);
			}
		}
	}

	while (n_ignored < n_files) {
		ssize_t len;
		int ev_idx = 0;

		len = read(ifd, buf, (n_files * INOTIFY_BUFLEN));
		if (unlikely(len < 0)) {
			/* Some signal, likely ^Z/fg's STOP and CONT interrupted the inotify read, retry */
			if (errno == EINTR || errno == EAGAIN)
				continue;
			else {
				fprintf(stderr, "Error: Could not read inotify events (%s)\n", strerror(errno));
				exit(EXIT_FAILURE);
			}
		}

		while (ev_idx < len) {
			struct inotify_event *inev;
			struct file_struct *f = NULL;

			inev = (struct inotify_event *) &buf[ev_idx];

			/* Which file has produced the event? */
			for (i = 0; i < n_files; i++) {
				if (!_files[i].ignore
						&& _files[i].fd >= 0
						&& _files[i].i_watch == inev->wd) {
					f = &_files[i];
					break;
				}
			}

			if (unlikely(!f))
				break;

			if (handle_inotify_event(inev, f) < 0)
				break;

			ev_idx += sizeof(struct inotify_event) + inev->len;
		}
	}

	close(ifd);
	return -1;
}