Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Following what happened in fetch(3) replace select(2) by poll(2) for ssh://
Baptiste Daroussin committed 12 years ago
commit b9140829c196c644ad56232c2a8b2c77de8347a4
parent 3a12b68
2 files changed +23 -97
modified libpkg/fetch.c
@@ -39,6 +39,7 @@
#include <unistd.h>
#include <fetch.h>
#include <paths.h>
+
#include <poll.h>

#include "pkg.h"
#include "private/event.h"
@@ -122,33 +123,13 @@ pkg_fetch_file(struct pkg_repo *repo, const char *url, char *dest, time_t t)
}

static int
-
ssh_cache_data(struct pkg_repo *repo, char *src, size_t nbytes)
-
{
-
	char *tmp;
-

-
	if (repo->sshio.cache.size < nbytes) {
-
		tmp = realloc(repo->sshio.cache.buf, nbytes);
-
		if (tmp == NULL)
-
			return (-1);
-

-
		repo->sshio.cache.buf = tmp;
-
		repo->sshio.cache.size = nbytes;
-
	}
-
	memcpy(repo->sshio.cache.buf, src, nbytes);
-
	repo->sshio.cache.len = nbytes;
-
	repo->sshio.cache.pos = 0;
-

-
	return (0);
-
}
-

-
static int
ssh_read(void *data, char *buf, int len)
{
	struct pkg_repo *repo = (struct pkg_repo *) data;
	struct timeval now, timeout, delta;
-
	fd_set readfds;
-
	ssize_t rlen, total;
-
	char *start;
+
	struct pollfd pfd;
+
	ssize_t rlen;
+
	int deltams;

	pkg_debug(2, "ssh: start reading");

@@ -157,78 +138,42 @@ ssh_read(void *data, char *buf, int len)
		timeout.tv_sec += fetchTimeout;
	}

-
	total = 0;
-
	start = buf;
-

-
	if (repo->sshio.cache.len > 0) {
-
		/*
-
		 * The last invocation of fetch_read was interrupted by a
-
		 * signal after some data had been read from the socket. Copy
-
		 * the cached data into the supplied buffer before trying to
-
		 * read from the socket again.
-
		 */
-
		total = (repo->sshio.cache.len < (size_t)len) ? repo->sshio.cache.len : (size_t)len;
-
		memcpy(buf, repo->sshio.cache.buf, total);
-

-
		repo->sshio.cache.len -= total;
-
		repo->sshio.cache.pos += total;
-
		len -= total;
-
		buf += total;
-
	}
+
	deltams = INFTIM;
+
	memset(&pfd, 0, sizeof pfd);
+
	pfd.fd = repo->sshio.in;
+
	pfd.events = POLLIN | POLLERR;

-

-
	while (len > 0) {
-
		if (repo->tofetch > 0 && repo->tofetch == repo->fetched)
-
			break;
-

-
		rlen = read(repo->sshio.in, buf, len);
-
		if (rlen == 0) {
+
	for (;;) {
+
		rlen = read(pfd.fd, buf, len);
+
		if (rlen > 0) {
			break;
-
		} else if (rlen > 0) {
-
			len -= rlen;
-
			buf += rlen;
-
			if (repo->tofetch > 0)
-
				repo->fetched += rlen;
-
			total += rlen;
-
			continue;
		} else if (rlen == -1) {
			if (errno == EINTR)
-
				ssh_cache_data(repo, start, total);
+
				break;
			if (errno != EAGAIN) {
				pkg_emit_errno("timeout", "ssh");
				return (-1);
			}
-
			if (errno == EAGAIN && total > 0) {
+
			if (errno == EAGAIN) {
				break;
			}
		}

-
		FD_ZERO(&readfds);
-
		while (!FD_ISSET(repo->sshio.in, &readfds)) {
-
			FD_SET(repo->sshio.in, &readfds);
-
			if (fetchTimeout > 0) {
-
				gettimeofday(&now, NULL);
-
				if (!timercmp(&timeout, &now, >)) {
-
					errno = ETIMEDOUT;
-
					return (-1);
-
				}
-
				timersub(&timeout, &now, &delta);
-
			}
-
			errno = 0;
-
			if (select(repo->sshio.in + 1, &readfds, NULL, NULL,
-
			    fetchTimeout > 0 ? &delta : NULL) < 0) {
-
				if (errno == EINTR) {
-
					/* Save anything that was read. */
-
					ssh_cache_data(repo, start, total);
-
					continue;
-
				}
+
		if (fetchTimeout > 0) {
+
			gettimeofday(&now, NULL);
+
			if (!timercmp(&timeout, &now, >)) {
+
				errno = ETIMEDOUT;
				return (-1);
			}
+
			timersub(&timeout, &now, &delta);
+
			deltams = delta.tv_sec * 1000 +
+
				delta.tv_usec / 1000;
		}
	}

-
	pkg_debug(2, "ssh: have read %d bytes", total);
-
	return (total);
+
	pkg_debug(2, "ssh: have read %d bytes", rlen);
+

+
	return (rlen);
}

static int
@@ -245,8 +190,6 @@ ssh_close(void *data)
	struct pkg_repo *repo = (struct pkg_repo *)data;
	int pstat;

-
	free(repo->sshio.cache.buf);
-

	write(repo->sshio.out, "quit\n", 5);

	while (waitpid(repo->sshio.pid, &pstat, 0) == -1) {
@@ -255,8 +198,6 @@ ssh_close(void *data)
	}

	repo->ssh = NULL;
-
	repo->tofetch = 0;
-
	repo->fetched = 0;

	return (WEXITSTATUS(pstat));
}
@@ -350,7 +291,6 @@ start_ssh(struct pkg_repo *repo, struct url *u, off_t *sz)
		}
	}
	fprintf(repo->ssh, "get %s %" PRIdMAX "\n", u->doc, (intmax_t)u->ims_time);
-
	repo->tofetch = 0;
	if ((linelen = getline(&line, &linecap, repo->ssh)) > 0) {
		if (line[linelen -1 ] == '\n')
			line[linelen -1 ] = '\0';
@@ -533,10 +473,6 @@ pkg_fetch_file_to_fd(struct pkg_repo *repo, const char *url, int dest, time_t *t
	}

	begin_dl = time(NULL);
-
	if (repo != NULL) {
-
		repo->tofetch = sz;
-
		repo->fetched = 0;
-
	}
	while (done < sz) {
		time_t	now;

@@ -557,8 +493,6 @@ pkg_fetch_file_to_fd(struct pkg_repo *repo, const char *url, int dest, time_t *t
			last = now;
		}
	}
-
	if (repo != NULL)
-
		repo->tofetch = 0;

	if (done < sz) {
		pkg_emit_error("An error occurred while fetching package");
modified libpkg/private/pkg.h
@@ -320,15 +320,7 @@ struct pkg_repo {
		int in;
		int out;
		pid_t pid;
-
		struct {
-
			char *buf;
-
			size_t size;
-
			size_t pos;
-
			size_t len;
-
		} cache;
	} sshio;
-
	size_t fetched;
-
	size_t tofetch;

	int (*update)(struct pkg_repo *, bool);