Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Use getline instead of mmap when parsing the manifest
Baptiste Daroussin committed 9 years ago
commit 6812f8a0012cf70598d930988829bedb1d411f8a
parent 4ee1f0d
3 files changed +24 -53
modified libpkg/pkg_repo.c
@@ -675,13 +675,14 @@ cleanup:
	return rc;
}

-
static int
+
int
pkg_repo_fetch_remote_extract_fd(struct pkg_repo *repo, const char *filename,
-
    time_t *t, int *rc)
+
    time_t *t, int *rc, size_t *sz)
{
	int fd, dest_fd;
	const char *tmpdir;
	char tmp[MAXPATHLEN];
+
	struct stat st;

	fd = pkg_repo_fetch_remote_tmp(repo, filename,
			packing_format_to_string(repo->meta->packing_format), t, rc);
@@ -713,44 +714,14 @@ pkg_repo_fetch_remote_extract_fd(struct pkg_repo *repo, const char *filename,

	/* Thus removing archived file as well */
	close(fd);
-

-
	return (dest_fd);
-
}
-

-
unsigned char *
-
pkg_repo_fetch_remote_extract_mmap(struct pkg_repo *repo, const char *filename,
-
    time_t *t, int *rc, size_t *sz)
-
{
-
	int fd;
-
	struct stat st;
-
	unsigned char *map;
-

-
	fd = pkg_repo_fetch_remote_extract_fd(repo, filename, t, rc);
-
	if (fd == -1) {
-
		return (NULL);
-
	}
-

-
	if (fstat(fd, &st) == -1) {
-
		close(fd);
-
		return (MAP_FAILED);
+
	if (fstat(dest_fd, &st) == -1) {
+
		close(dest_fd);
+
		return (-1);
	}

	*sz = st.st_size;
-
	if (st.st_size > SSIZE_MAX) {
-
		pkg_emit_error("%s too large", filename);
-
		close(fd);
-
		return (MAP_FAILED);
-
	}

-
	map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
-
	close(fd);
-
	if (map == MAP_FAILED) {
-
		pkg_emit_errno("pkg_repo_fetch_remote_mmap", "cannot mmap fetched");
-
		*rc = EPKG_FATAL;
-
		return (MAP_FAILED);
-
	}
-

-
	return (map);
+
	return (dest_fd);
}

struct pkg_repo_check_cbdata {
modified libpkg/private/pkg.h
@@ -635,7 +635,7 @@ int pkg_fetch_file_to_fd(struct pkg_repo *repo, const char *url, int dest,
    time_t *t, ssize_t offset, int64_t size);
int pkg_repo_fetch_package(struct pkg *pkg);
int pkg_repo_mirror_package(struct pkg *pkg, const char *destdir);
-
unsigned char *pkg_repo_fetch_remote_extract_mmap(struct pkg_repo *repo,
+
int pkg_repo_fetch_remote_extract_fd(struct pkg_repo *repo,
    const char *filename, time_t *t, int *rc, size_t *sz);
int pkg_repo_fetch_meta(struct pkg_repo *repo, time_t *t);

modified libpkg/repo/binary/update.c
@@ -26,7 +26,6 @@

#include <sys/stat.h>
#include <sys/param.h>
-
#include <sys/mman.h>
#include <sys/time.h>

#include <stdio.h>
@@ -459,16 +458,19 @@ pkg_repo_binary_update_proceed(const char *name, struct pkg_repo *repo,
	time_t *mtime, bool force)
{
	struct pkg *pkg = NULL;
-
	unsigned char *walk;
	int rc = EPKG_FATAL;
	sqlite3 *sqlite = NULL;
	int cnt = 0;
	time_t local_t;
	struct pkg_manifest_key *keys = NULL;
-
	unsigned char *map = MAP_FAILED;
	size_t len = 0;
	bool in_trans = false;
	char *path = NULL;
+
	FILE *f = NULL;
+
	int fd;
+
	char *line = NULL;
+
	size_t linecap = 0;
+
	ssize_t linelen, totallen = 0;

	pkg_debug(1, "Pkgrepo, begin update of '%s'", name);

@@ -484,10 +486,12 @@ pkg_repo_binary_update_proceed(const char *name, struct pkg_repo *repo,

	/* Fetch packagesite */
	local_t = *mtime;
-
	map = pkg_repo_fetch_remote_extract_mmap(repo,
+
	fd = pkg_repo_fetch_remote_extract_fd(repo,
		repo->meta->manifests, &local_t, &rc, &len);
-
	if (map == NULL || map == MAP_FAILED)
+
	if (fd == -1)
		goto cleanup;
+
	f = fdopen(fd, "r");
+
	rewind(f);

	*mtime = local_t;
	/*fconflicts = repo_fetch_remote_extract_tmp(repo,
@@ -522,22 +526,17 @@ pkg_repo_binary_update_proceed(const char *name, struct pkg_repo *repo,
		goto cleanup;

	in_trans = true;
-

-
	walk = map;
-
	unsigned char *next;
-

-
	while (walk -map < len) {
+
	while ((linelen = getline(&line, &linecap, f)) > 0) {
		cnt++;
-
		next = strchr(walk, '\n');
+
		totallen += linelen;
		if ((cnt % 10 ) == 0)
-
			pkg_emit_progress_tick(next - map, len);
-
		rc = pkg_repo_binary_add_from_manifest(walk, sqlite, next - walk,
+
			pkg_emit_progress_tick(totallen, len);
+
		rc = pkg_repo_binary_add_from_manifest(line, sqlite, linelen,
		    &keys, &pkg, repo);
		if (rc != EPKG_OK) {
			pkg_emit_progress_tick(len, len);
			break;
		}
-
		walk = next + 1;
	}
	pkg_emit_progress_tick(len, len);

@@ -575,8 +574,9 @@ cleanup:
	pkg_unregister_cleanup_callback(rollback_repo, (void *)name);
	pkg_manifest_keys_free(keys);
	pkg_free(pkg);
-
	if (map != NULL && map != MAP_FAILED)
-
		munmap(map, len);
+
	free(line);
+
	if (f != NULL)
+
		fclose(f);

	return (rc);
}