See comments inline...

> 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;
> +}

memwrite() can return with the file still being mapped (successful mmap(), then 
a short write).  Is that intended?  No big problem if the calling program exits 
when memwrite() returns 0, but I did not check that.

Then different formats are uses to print the size, "%u" in one case, "%" PRlu64 
"" in the second case.  Could be nicer if it was consistent, maybe.

> +
> +/* 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