Пример #1
0
int
ni_process_run_and_capture_output(ni_process_t *pi, ni_buffer_t *out_buffer)
{
	int pfd[2],  rv;

	if (pipe(pfd) < 0) {
		ni_error("%s: unable to create pipe: %m", __func__);
		return -1;
	}

	rv = __ni_process_run(pi, pfd);
	if (rv < 0) {
		close(pfd[0]);
		close(pfd[1]);
		return rv;
	}

	close(pfd[1]);
	while (1) {
		int cnt;

		if (ni_buffer_tailroom(out_buffer) < 256)
			ni_buffer_ensure_tailroom(out_buffer, 4096);

		cnt = read(pfd[0], ni_buffer_tail(out_buffer), ni_buffer_tailroom(out_buffer));
		if (cnt == 0) {
			break;
		} else if (cnt > 0) {
			out_buffer->tail += cnt;
		} else if (errno != EINTR) {
			ni_error("read error on subprocess pipe: %m");
			return -1;
		}
	}

	while (waitpid(pi->pid, &pi->status, 0) < 0) {
		if (errno == EINTR)
			continue;
		ni_error("%s: waitpid returns error (%m)", __func__);
		return -1;
	}

	pi->pid = 0;
	if (pi->notify_callback)
		pi->notify_callback(pi);

	if (!ni_process_exit_status_okay(pi)) {
		ni_error("subprocesses exited with error");
		return -1;
	}

	return rv;
}
Пример #2
0
ni_buffer_t *
ni_file_read(FILE *fp)
{
	struct stat stb;
	unsigned int count, done, size;
	ni_buffer_t *result;

	if (fstat(fileno(fp), &stb) < 0)
		return NULL;

	if (S_ISREG(stb.st_mode)) {
		size = stb.st_size;

		result = ni_buffer_new_dynamic(size);
		if (result == NULL)
			return NULL;

		for (done = 0; done < size; done += count) {
			void *buffer = ni_buffer_tail(result);

			count = fread(buffer, 1, size - done, fp);
			if (count == 0)
				break;
			ni_buffer_push_tail(result, count);
		}
	} else {
		/* Could be a pipe or tty or socket */
		result = ni_buffer_new_dynamic(4096);
		if (result == NULL)
			return NULL;

		while (TRUE) {
			void *buffer;

			ni_buffer_ensure_tailroom(result, 4096);
			buffer = ni_buffer_tail(result);

			count = fread(buffer, 1, ni_buffer_tailroom(result), fp);
			if (count == 0)
				break;
			ni_buffer_push_tail(result, count);
		}
	}

	if (ferror(fp)) {
		ni_error("%s: read error on file", __func__);
		ni_buffer_free(result);
		return NULL;
	}

	return result;
}
Пример #3
0
int
ni_process_run_and_capture_output(ni_process_t *pi, ni_buffer_t *out_buffer)
{
	int pfd[2], rv;

	if (pipe(pfd) < 0) {
		ni_error("%s: unable to create pipe: %m", __func__);
		return NI_PROCESS_FAILURE;
	}

	rv = __ni_process_run(pi, pfd);
	if (rv < NI_PROCESS_SUCCESS) {
		close(pfd[0]);
		close(pfd[1]);
		return rv;
	}

	rv = NI_PROCESS_SUCCESS;
	close(pfd[1]);
	while (1) {
		int cnt;

		if (ni_buffer_tailroom(out_buffer) < 256)
			ni_buffer_ensure_tailroom(out_buffer, 4096);

		cnt = read(pfd[0], ni_buffer_tail(out_buffer), ni_buffer_tailroom(out_buffer));
		if (cnt == 0) {
			break;
		} else if (cnt > 0) {
			out_buffer->tail += cnt;
		} else if (errno != EINTR) {
			ni_error("read error on subprocess pipe: %m");
			rv = NI_PROCESS_IOERROR;
			break;
		}
	}
	close(pfd[0]);

	while (waitpid(pi->pid, &pi->status, 0) < 0) {
		if (errno == EINTR)
			continue;
		ni_error("%s: waitpid returns error (%m)", __func__);
		rv = NI_PROCESS_WAITPID;
	}

	if (pi->notify_callback)
		pi->notify_callback(pi);

	if (rv != NI_PROCESS_SUCCESS)
		return rv;
	return __ni_process_run_info(pi);
}
Пример #4
0
/*
 * Connect the subprocess output to our I/O handling loop
 */
static void
__ni_process_output_recv(ni_socket_t *sock)
{
	ni_process_t *pi = sock->user_data;
	ni_buffer_t *rbuf = &sock->rbuf;
	int cnt;

	ni_assert(pi);
	if (ni_buffer_tailroom(rbuf) < 256)
		ni_buffer_ensure_tailroom(rbuf, 4096);

	cnt = recv(sock->__fd, ni_buffer_tail(rbuf), ni_buffer_tailroom(rbuf), MSG_DONTWAIT);
	if (cnt >= 0) {
		rbuf->tail += cnt;
	} else if (errno != EWOULDBLOCK) {
		ni_error("read error on subprocess pipe: %m");
		ni_socket_deactivate(sock);
	}
}
Пример #5
0
/*
 * Connect the subprocess output to our I/O handling loop
 */
static void
__ni_process_output_recv(ni_socket_t *sock)
{
	ni_process_t *pi = sock->user_data;
	ni_buffer_t *rbuf = &sock->rbuf;
	int cnt;

	ni_assert(pi);

	/* Grow socket input buffer as needed.
	 * NB: we may put an upper limit on how much process output we capture.
	 * Anything beyond a few MB is insane...
	 */
	if (ni_buffer_tailroom(rbuf) < 256)
		ni_buffer_ensure_tailroom(rbuf, 4096);

	cnt = recv(sock->__fd, ni_buffer_tail(rbuf), ni_buffer_tailroom(rbuf), MSG_DONTWAIT);
	if (cnt >= 0) {
		rbuf->tail += cnt;
	} else if (errno != EWOULDBLOCK) {
		ni_error("read error on subprocess pipe: %m");
		ni_socket_deactivate(sock);
	}
}
Пример #6
0
ni_iaid_map_t *
ni_iaid_map_load(const char *filename)
{
	ni_iaid_map_t *map;
	const char *type;
	ni_buffer_t buff;
	struct stat stb;
	ssize_t len;

	if (!(map = ni_iaid_map_new())) {
		ni_error("unable to allocate memory for iaid map: %m");
		return NULL;
	}

	if (filename) {
		type = "given";
		if (!ni_string_dup(&map->file, filename)) {
			ni_error("unable to copy %s iaid map file name (%s): %m", type, filename);
			goto failure;
		}

		if (!ni_iaid_map_open(map)) {
			ni_error("unable to open %s iaid map file name (%s): %m", type, map->file);
			goto failure;
		}
	} else {
		type = "default";
		if (!ni_iaid_map_set_default_file(&map->file)) {
			ni_error("unable to construct %s iaid map file name: %m", type);
			goto failure;
		}

		if (!ni_iaid_map_open(map)) {
			ni_debug_readwrite("unable to open %s iaid map file name (%s): %m", type, map->file);

			type = "fallback";
			if (!ni_iaid_map_set_fallback_file(&map->file)) {
				ni_error("unable to construct %s iaid map file name: %m", type);
				goto failure;
			}
			
			if (!ni_iaid_map_open(map)) {
				ni_error("unable to open iaid map file name (%s): %m", map->file);
				goto failure;
			}
		}
	}

	if (!ni_iaid_map_lock(map)) {
		ni_error("unable to lock %s iaid map file name (%s): %m", type, map->file);
		goto failure;
	}

	if (fstat(map->fd, &stb) < 0)
		stb.st_size = BUFSIZ;

	ni_buffer_init_dynamic(&buff, stb.st_size + 1);
	do {
		if (!ni_buffer_tailroom(&buff))
			ni_buffer_ensure_tailroom(&buff, BUFSIZ);

		do {
			 len = read(map->fd, ni_buffer_tail(&buff), ni_buffer_tailroom(&buff));
			 if (len > 0)
				 ni_buffer_push_tail(&buff, len);
		} while (len < 0 && errno == EINTR);
	} while (len > 0);

	if (len < 0) {
		ni_error("unable to read %s iaid map file name (%s): %m", type, map->file);
	} else {
		map->doc = xml_document_from_buffer(&buff, map->file);
		ni_buffer_destroy(&buff);
		if (!map->doc) {
			map->doc = xml_document_new();
			ni_warn("unable to parse %s iaid map file name (%s): %m", type, map->file);
		}
		return map;
	}

failure:
	ni_iaid_map_free(map);
	return NULL;
}