Hi Hiltjo

Thanks for the review!

On Sat, Sep 09, 2017 at 01:06:21PM +0200, Hiltjo Posthuma wrote:
> On Sat, Sep 09, 2017 at 11:08:42AM +0200, Silvan Jegen wrote:
> > From: Jim Beveridge <ji...@chromium.org>
> > 
> > The original code is by Jim Beveridge working on Fuchsia. I merged it
> > with slight changes.
> > 
> 
> To be clear: is it under the sbase LICENSE?

Yes, from what I can tell the License for this code is the same as for
the rest of sbase.

> >  #define BLKSIZ 512
> > +// COPY_CHUNK_SIZE must be a power of 2
> > +#define COPY_CHUNK_SIZE 8192
> >  
> 
> Instead of COPY_CHUNK_SIZE is might be worthwhile to query the pagesize, but
> i've not tested it.

Yes, I will have a look.

 
> >  enum Type {
> >     REG       = '0',
> > @@ -236,10 +238,13 @@ archive(const char *path)
> >     ewrite(tarfd, b, BLKSIZ);
> >  
> >     if (fd != -1) {
> > -           while ((l = eread(fd, b, BLKSIZ)) > 0) {
> > -                   if (l < BLKSIZ)
> > -                           memset(b + l, 0, BLKSIZ - l);
> > -                   ewrite(tarfd, b, BLKSIZ);
> > +           char chunk[COPY_CHUNK_SIZE];
> > +           while ((l = eread(fd, chunk, COPY_CHUNK_SIZE)) > 0) {
> > +                   // Ceiling to BLKSIZ boundary
> > +                   int ceilsize = (l + (BLKSIZ-1)) & ~(BLKSIZ-1);
> > +                   if (l < ceilsize)
> > +                           memset(chunk + l, 0, ceilsize - l);
> > +                   ewrite(tarfd, chunk, ceilsize);
> >             }
> >             close(fd);
> >     }
> > @@ -250,7 +255,7 @@ archive(const char *path)
> >  static int
> >  unarchive(char *fname, ssize_t l, char b[BLKSIZ])
> >  {
> > -   char lname[101], *tmp, *p;
> > +   char lname[101], *p;
> >     long mode, major, minor, type, mtime, uid, gid;
> >     struct header *h = (struct header *)b;
> >     int fd = -1;
> > @@ -261,9 +266,13 @@ unarchive(char *fname, ssize_t l, char b[BLKSIZ])
> >     if (remove(fname) < 0 && errno != ENOENT)
> >             weprintf("remove %s:", fname);
> >  
> > -   tmp = estrdup(fname);
> > -   mkdirp(dirname(tmp), 0777, 0777);
> > -   free(tmp);
> > +   // tar files normally create the directory chain. This is a fallback
> > +   // for noncompliant tar files.
> > +   if (h->type != DIRECTORY) {
> > +           char* tmp = estrdup(fname);
> > +           mkdirp(dirname(tmp), 0777, 0777);
> > +           free(tmp);
> > +   }
> >  
> >     switch (h->type) {
> >     case REG:
> > @@ -319,9 +328,25 @@ unarchive(char *fname, ssize_t l, char b[BLKSIZ])
> >             eprintf("strtol %s: invalid number\n", h->gid);
> >  
> >     if (fd != -1) {
> > -           for (; l > 0; l -= BLKSIZ)
> > -                   if (eread(tarfd, b, BLKSIZ) > 0)
> > -                           ewrite(fd, b, MIN(l, BLKSIZ));
> > +           // Ceiling to BLKSIZ boundary
> > +           int readsize = (l + (BLKSIZ-1)) & ~(BLKSIZ-1);
> > +           char chunk[COPY_CHUNK_SIZE];
> > +           int lastread = 0;
> > +
> > +           for (; readsize > 0; l -= lastread, readsize -= lastread) {
> > +                   int chunk_size = MIN(readsize, COPY_CHUNK_SIZE);
> > +                   // Short reads are legal, so don't expect to read
> > +                   // everything that was requested.
> > +                   lastread = eread(tarfd, chunk, chunk_size);
> > +                   if (lastread == 0) {
> > +                           close(fd);
> > +                           remove(fname);
> 
> Do all the tar tools remove the file in this case? It might be better to not
> remove it.

You are right, this code should probably be removed if we use a
ReadAll-like function.


> > +                           eprintf("unexpected end of file reading %s.\n",
> > +                                   fname);
> > +                   }
> > +
> > +                   ewrite(fd, chunk, MIN(l, lastread));
> > +           }
> >             close(fd);
> >     }
> >  
> > @@ -331,7 +356,7 @@ unarchive(char *fname, ssize_t l, char b[BLKSIZ])
> >     times[0].tv_sec = times[1].tv_sec = mtime;
> >     times[0].tv_nsec = times[1].tv_nsec = 0;
> >     if (!mflag && utimensat(AT_FDCWD, fname, times, AT_SYMLINK_NOFOLLOW) < 
> > 0)
> > -           weprintf("utimensat %s:\n", fname);
> > +           weprintf("utimensat %s %d:\n", fname, errno);
> >     if (h->type == SYMLINK) {
> >             if (!getuid() && lchown(fname, uid, gid))
> >                     weprintf("lchown %s:\n", fname);
> > @@ -349,10 +374,23 @@ static void
> >  skipblk(ssize_t l)
> >  {
> >     char b[BLKSIZ];
> > -
> > -   for (; l > 0; l -= BLKSIZ)
> > -           if (!eread(tarfd, b, BLKSIZ))
> > -                   break;
> > +   int lastread = 0;
> > +   // Ceiling to BLKSIZ boundary
> > +   int ceilsize = (l + (BLKSIZ-1)) & ~(BLKSIZ-1);
> > +
> > +   off_t offset = lseek(tarfd, ceilsize, SEEK_CUR);
> > +   if (offset >= ceilsize)
> > +           return;
> > +   if (errno != ESPIPE)
> > +           eprintf("unexpected end of file.\n");
> > +
> > +   // This is a pipe, socket or FIFO. Fall back to a sequential read.
> > +   for (; ceilsize > 0; ceilsize -= lastread) {
> > +           int chunk_size = MIN(ceilsize, BLKSIZ);
> > +           lastread = eread(tarfd, b, chunk_size);
> > +           if (lastread == 0)
> > +                   eprintf("unexpected end of file %d.\n", errno);
> > +        }
> >  }
> >  
> >  static int
> > @@ -370,7 +408,7 @@ c(const char *path, struct stat *st, void *data, struct 
> > recursor *r)
> >     if (vflag)
> >             puts(path);
> >  
> > -   if (S_ISDIR(st->st_mode))
> > +   if (st && S_ISDIR(st->st_mode))
> >             recurse(path, NULL, r);
> >  }
> >  
> > -- 
> > 2.7.4
> > 
> > 
> 
> The C++ comments should be changed to /* */. I'd also prefer all variable
> declarations at the top and the other notes above.

I can change that.


> Nice work though :)

Sadly, it's not really mine :P

I will discuss with Michael and Jim to see what changes would get this
patch (or one based on it) merged.


Cheers,

Silvan 

Reply via email to