Exemple #1
0
void setup_watches (const char *dir)
{
	DIR *dirfd = opendir(dir);
	char fullent[PATH_MAX];
	int dirlen = strlen(dir);
	memcpy(fullent, dir, dirlen);
	fullent[dirlen] = '/';
	struct dirent *ent;
	if (!dirfd) {
		if (errno == ENOENT || errno == EACCES)
			return;
		die_errno("opendir");
	}
	while ((ent = xreaddir(dirfd))) {
		int entlen = strlen(ent->d_name);
		if (!strcmp(ent->d_name, ".")
		    || !strcmp(ent->d_name, ".."))
			continue;
		memcpy(fullent+dirlen+1, ent->d_name, entlen);
		fullent[dirlen+1+entlen] = '\0';
		if (is_ignored(fullent))
			continue;
		if (!isdir(fullent))
			continue;
		if (!setup_one_watch(fullent))
			setup_watches(fullent);
	}
	if (closedir(dirfd))
		die_errno("closedir");
}
Exemple #2
0
void handle_event(struct inotify_event *ev)
{
	char *wdp;
	int i, j;
	if (ev->wd < 0)
		return;
	wdp = wdpaths[ev->wd];
	if (!wdp)
		return;
	if (ev->mask & IN_ISDIR && ev->mask & IN_CREATE) {
		char buf[PATH_MAX];
		strcpy(buf, wdp);
		strcat(buf, "/");
		strcat(buf, ev->name);
		if (is_ignored(buf))
			return;
		if (!setup_one_watch(buf))
			setup_watches(buf);
		return;
	}
	/* inotify shows directory events in the parent too; ignore them there */
	if (ev->len && ev->mask & IN_ISDIR)
		return;
	if (ev->mask & IN_IGNORED) {
		wdpaths[ev->wd] = NULL;
		for (i = 0; i < HIST; i++) {
			if (!lru[i])
				break;
			if (strcmp(wdp, lru[i]))
				continue;
			for (j = i; j < HIST-1; j++)
				lru[j] = lru[j+1];
			lru[HIST-1] = NULL;
			break;
		}
		free(wdp);
		return;
	}
#ifdef DEBUG
	if (ev->mask != IN_ACCESS)
		fprintf(stdout, "%08x %s %s %s\n", ev->mask, event_msg(ev->mask), wdp,
			ev->len ? ev->name : "(none)");
#endif
	for (i = 0; i < HIST; i++) {
		if (!lru[i])
			break;
		if (strcmp(wdp, lru[i]))
			continue;
		if (i == 0)
			return;
		for (j = i; j > 0; j--)
			lru[j] = lru[j-1];
		lru[0] = wdp;
		return;
	}
	for (j = HIST-1; j > 0; j--)
		lru[j] = lru[j-1];
	lru[0] = wdp;
}
Exemple #3
0
int
process_subprocess_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options)
{
    struct subprocess_data *mdata = data;
    struct sol_flow_node_type_process_subprocess_options *opts =
        (struct sol_flow_node_type_process_subprocess_options *)options;

    SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options,
        SOL_FLOW_NODE_TYPE_PROCESS_SUBPROCESS_OPTIONS_API_VERSION,
        -EINVAL);

    mdata->node = node;
    sol_vector_init(&mdata->write_data, sizeof(struct write_data));

    if (pipe2(mdata->pipes.out, O_NONBLOCK | O_CLOEXEC) < 0) {
        SOL_WRN("Failed to create out pipe");
        return -errno;
    }

    if (pipe2(mdata->pipes.in, O_NONBLOCK | O_CLOEXEC) < 0) {
        SOL_WRN("Failed to create in pipe");
        goto in_err;
    }

    if (pipe2(mdata->pipes.err, O_NONBLOCK | O_CLOEXEC) < 0) {
        SOL_WRN("Failed to create err pipe");
        goto err_err;
    }

    mdata->command = strdup(opts->command);
    SOL_NULL_CHECK_GOTO(mdata->command, flags_err);

    if (opts->start) {
        if (setup_watches(mdata) < 0)
            goto watch_err;
        mdata->fork_run = sol_platform_linux_fork_run(on_fork, on_fork_exit, mdata);
        SOL_NULL_CHECK_GOTO(mdata->fork_run, err);
    }

    return 0;

err:
    sol_fd_del(mdata->watches.in);
    sol_fd_del(mdata->watches.err);
watch_err:
    free(mdata->command);
flags_err:
    close(mdata->pipes.err[0]);
    close(mdata->pipes.err[1]);
err_err:
    close(mdata->pipes.in[0]);
    close(mdata->pipes.in[1]);
in_err:
    close(mdata->pipes.out[0]);
    close(mdata->pipes.out[1]);
    return -errno;
}
Exemple #4
0
int
process_subprocess_start_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id,
    const struct sol_flow_packet *packet)
{
    struct subprocess_data *mdata = data;

    if (mdata->fork_run)
        return 0;

    if (setup_watches(mdata) < 0)
        return -1;

    mdata->fork_run = sol_platform_linux_fork_run(on_fork, on_fork_exit, mdata);
    SOL_NULL_CHECK_GOTO(mdata->fork_run, fork_err);

    return 0;

fork_err:
    sol_fd_del(mdata->watches.err);
    mdata->watches.err = NULL;
    sol_fd_del(mdata->watches.in);
    mdata->watches.in = NULL;
    return -1;
}
Exemple #5
0
int main (int argc, char *argv[])
{
	int sock, conn;
	char *sockname;
	struct sockaddr_un addr, peer;
	socklen_t peer_sz;
	fd_set rfds;
	int ret;
	int maxfd;

	read_ignore_file();

	ifd = inotify_init();
	if (ifd < 0)
		die_errno("inotify_init");
	setup_watches(expanduser("~"));
	setup_watches("/media");

	sockname = expanduser(SOCKNAME);
	unlink(sockname); /* errors deliberately ignored */
	sock = socket(AF_UNIX, SOCK_STREAM, 0);
	if (sock < 0)
		die_errno("socket");
	memset(&addr, 0, sizeof(addr));
	addr.sun_family = AF_UNIX;
	strncpy(addr.sun_path, sockname, sizeof(addr.sun_path)-1);
	if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)))
		die_errno("bind");
	if (listen(sock, 10))
		die_errno("listen");

	maxfd = sock;
	if (ifd > maxfd)
		maxfd = ifd;
	maxfd++;

	while (1) {
		FD_ZERO(&rfds);
		FD_SET(ifd, &rfds);
		FD_SET(sock, &rfds);
		ret = select(maxfd, &rfds, NULL, NULL, NULL);
		if (ret == -1)
			die_errno("select");
		if (!ret)
			continue;
		if (FD_ISSET(ifd, &rfds))
			handle_inotify();
		if (FD_ISSET(sock, &rfds)) {
			conn = accept(sock, (struct sockaddr *) &peer, &peer_sz);
			if (conn < 0)
				die_errno("accept");
			send_lru(conn);
			close(conn); /* errors ignored */
		}
	}

	/* we never get here, but meh */
	if (close(sock) < 0)
		die_errno("close");

	return 0;
}