Module Name:    othersrc
Committed By:   agc
Date:           Sun Nov 25 20:20:36 UTC 2012

Modified Files:
        othersrc/external/bsd/mat/dist: mat.c mat.h
        othersrc/external/bsd/mat/libmat: shlib_version

Log Message:
Use mmap(2) to write files, where possible.

Fallback to write(2) when not possible.


To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 othersrc/external/bsd/mat/dist/mat.c \
    othersrc/external/bsd/mat/dist/mat.h
cvs rdiff -u -r1.1.1.1 -r1.2 othersrc/external/bsd/mat/libmat/shlib_version

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: othersrc/external/bsd/mat/dist/mat.c
diff -u othersrc/external/bsd/mat/dist/mat.c:1.5 othersrc/external/bsd/mat/dist/mat.c:1.6
--- othersrc/external/bsd/mat/dist/mat.c:1.5	Sun Aug 12 01:42:24 2012
+++ othersrc/external/bsd/mat/dist/mat.c	Sun Nov 25 20:20:36 2012
@@ -180,9 +180,44 @@ fillmeta(matent_t *ent, const char *f, s
 	ent->meta.flags = st->st_flags;
 }
 
+/* write to file */
+static int
+memwrite(FILE *fp, uint64_t off, const void *p, size_t size)
+{
+	char	*mapped;
+
+	mapped = mmap(NULL, size, PROT_WRITE, MAP_SHARED, fileno(fp), (off_t)off);
+	if (mapped == MAP_FAILED) {
+		if (write(fileno(fp), p, size) != (ssize_t)size) {
+			fprintf(stderr, "short write %zu chars\n", size);
+			return 0;
+		}
+	} else {
+		lseek(fileno(fp), (off_t)(off + size - 1), SEEK_SET);
+		if (write(fileno(fp), "", 1) != 1) {
+			fprintf(stderr, "short write %" PRIu64 " chars\n", size);
+			return 0;
+		}
+		memcpy(mapped, p, size);
+		munmap(mapped, size);
+	}
+	return 1;
+}
+
+/* write to mat archive */
+static int
+archive_write(mat_t *mat, const void *p, size_t size)
+{
+	if (memwrite(mat->fp, mat->off, p, size)) {
+		mat->off += size;
+		return 1;
+	}
+	return 0;
+}
+
 /* write the entry's meta information to the archive */
 static int
-writemeta(int fd, matent_t *ent)
+writemeta(mat_t *mat, matent_t *ent)
 {
 	matent_t	lent;
 
@@ -199,7 +234,7 @@ writemeta(int fd, matent_t *ent)
 	lent.meta.flags = local_htobe32(ent->meta.flags);
 	lent.meta.linklen = local_htobe32(ent->meta.linklen);
 	lent.meta.type = ent->meta.type;
-	return write(fd, &lent, sizeof(lent.meta)) == sizeof(lent.meta);
+	return archive_write(mat, &lent, sizeof(lent.meta)) == sizeof(lent.meta);
 }
 
 /* read the entry's meta information from the archive */
@@ -420,7 +455,10 @@ extract_file(mat_t *mat, extract_t *arch
 			(void) fprintf(stderr, "can't create '%s'\n", name);
 			return 0;
 		}
-		write(fileno(fp), &archive->s[archive->off], ent->meta.size);
+		if (!memwrite(fp, 0, &archive->s[archive->off], ent->meta.size)) {
+			fprintf(stderr, "short write %" PRIu64 " chars\n", ent->meta.size);
+			return 0;
+		}
 		tv[0].tv_sec = ent->meta.atime;
 		tv[0].tv_usec = 0;
 		tv[1].tv_sec = ent->meta.mtime;
@@ -548,8 +586,8 @@ write_meta_info(mat_t *mat, matent_t *en
 			(int)strlen(&f[matches[0].rm_eo]), &f[matches[0].rm_eo]) + 1;
 		f = newpath;
 	}
-	writemeta(fileno(mat->fp), ent);
-	write(fileno(mat->fp), f, ent->meta.namelen);
+	writemeta(mat, ent);
+	archive_write(mat, f, ent->meta.namelen);
 	return 1;
 }
 
@@ -629,13 +667,13 @@ mat_add(mat_t *mat, const char *f)
 			return 0;
 		}
 		write_meta_info(mat, &ent, f);
-		write(fileno(mat->fp), mapped, (size_t)st.st_size);
+		archive_write(mat, mapped, (size_t)st.st_size);
 		digest_update(ent.digest, mapped, (size_t)st.st_size);
 		if (ent.meta.nlink > 1 && original) {
 			/* multi-linked, and we're the primary */
 			(void) memcpy(&mat->links[primary].digest, ent.digest, sizeof(ent.digest));
 		}
-		write(fileno(mat->fp), ent.digest, sizeof(ent.digest));
+		archive_write(mat, ent.digest, sizeof(ent.digest));
 		munmap(mapped, (size_t)st.st_size);
 		(void) fclose(fp);
 		break;
@@ -643,10 +681,10 @@ mat_add(mat_t *mat, const char *f)
 		/* store hardlink to primary */
 		ent.meta.linklen = mat->links[primary].namelen;
 		write_meta_info(mat, &ent, f);
-		write(fileno(mat->fp), mat->links[primary].name, (size_t)ent.meta.linklen);
+		archive_write(mat, mat->links[primary].name, (size_t)ent.meta.linklen);
 		/* get digest from primary */
 		(void) memcpy(ent.digest, mat->links[primary].digest, sizeof(ent.digest));
-		write(fileno(mat->fp), ent.digest, sizeof(ent.digest));
+		archive_write(mat, ent.digest, sizeof(ent.digest));
 		break;
 	case 'l':
 		if ((cc = readlink(f, newpath, sizeof(newpath))) < 0) {
@@ -656,9 +694,9 @@ mat_add(mat_t *mat, const char *f)
 		newpath[cc] = 0x0;
 		ent.meta.linklen = (uint32_t)(cc + 1);
 		write_meta_info(mat, &ent, f);
-		write(fileno(mat->fp), newpath, (size_t)ent.meta.linklen);
+		archive_write(mat, newpath, (size_t)ent.meta.linklen);
 		digest_update(ent.digest, (uint8_t *)newpath, (size_t)ent.meta.linklen);
-		write(fileno(mat->fp), ent.digest, sizeof(ent.digest));
+		archive_write(mat, ent.digest, sizeof(ent.digest));
 		break;
 	case 'b':
 	case 'c':
@@ -965,7 +1003,7 @@ mat_init(mat_t *mat, const char *f, cons
 		mat->archive = st.st_ino;
 		(void) memset(&header, 0x0, sizeof(header));
 		header.magic = local_htobe32(MAT_MAGIC);
-		write(fileno(mat->fp), &header, sizeof(header));
+		archive_write(mat, &header, sizeof(header));
 		return 1;
 	}
 	if ((mat->fp = fopen(f, "r")) == NULL) {
Index: othersrc/external/bsd/mat/dist/mat.h
diff -u othersrc/external/bsd/mat/dist/mat.h:1.5 othersrc/external/bsd/mat/dist/mat.h:1.6
--- othersrc/external/bsd/mat/dist/mat.h:1.5	Thu Oct 13 17:20:47 2011
+++ othersrc/external/bsd/mat/dist/mat.h	Sun Nov 25 20:20:36 2012
@@ -64,9 +64,7 @@ typedef struct matmeta_t {
 	uint32_t	 namelen;		/* size of name */
 	uint32_t	 linklen;		/* size of link target */
 	uint32_t	 flags;			/* fs flags */
-#if 0
 	uint32_t	 xasize;		/* extattr size */
-#endif
 	char		 type;			/* single char type */
 } matmeta_t;
 
@@ -75,9 +73,7 @@ typedef struct matent_t {
 	matmeta_t	 meta;			/* meta data */
 	char		*name;			/* name of entry */
 	uint8_t		*data;			/* associated data */
-#if 0
 	uint8_t		*extattrs;		/* extended attributes */
-#endif
 	uint8_t		 digest[MAT_DIGEST_LEN]; /* sha256 */
 } matent_t;
 
@@ -99,6 +95,7 @@ typedef struct mat_t {
 	const char	*action;	/* what action we're doing */
 	FILE		*fp;		/* archive pointer */
 	uint8_t		*mapped;	/* memory mapped archive */
+	uint64_t	 off;		/* offset from start */
 	size_t		 size;		/* size of mmap */
 	int		 verbose;	/* be gobby */
 	uint64_t	 archive;	/* inode of the archive */

Index: othersrc/external/bsd/mat/libmat/shlib_version
diff -u othersrc/external/bsd/mat/libmat/shlib_version:1.1.1.1 othersrc/external/bsd/mat/libmat/shlib_version:1.2
--- othersrc/external/bsd/mat/libmat/shlib_version:1.1.1.1	Sat Jun 18 04:53:13 2011
+++ othersrc/external/bsd/mat/libmat/shlib_version	Sun Nov 25 20:20:36 2012
@@ -1,2 +1,2 @@
-major=0
+major=1
 minor=0

Reply via email to