From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from relay4-d.mail.gandi.net ([217.70.183.196]) by ewsd; Sun Nov 3 10:36:01 EST 2019 X-Originating-IP: 185.198.110.254 Received: from jupiter.antares-labs.eu (unknown [185.198.110.254]) (Authenticated sender: rgl@antares-labs.eu) by relay4-d.mail.gandi.net (Postfix) with ESMTPSA id C5568E0004 for <9front@9front.org>; Sun, 3 Nov 2019 15:35:53 +0000 (UTC) Message-ID: Date: Sun, 3 Nov 2019 16:35:24 +0100 From: rgl@antares-labs.eu To: 9front@9front.org Subject: Re: [9front] tar: write directory metadata after file extraction In-Reply-To: AA5BAE62A5C074D149164AEF805412E6@antares-labs.eu MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="upas-xknmmrsiehnhbapkrmkeihykef" List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: managed framework factory SOAP standard-scale realtime-java hardware This is a multi-part message in MIME format. --upas-xknmmrsiehnhbapkrmkeihykef Content-Disposition: inline Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit ok, here's the corrected version to keep the original directory mode intact. --upas-xknmmrsiehnhbapkrmkeihykef Content-Disposition: inline Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit diff -r fe7fc19b1e64 sys/src/cmd/tar.c --- a/sys/src/cmd/tar.c Sun Nov 03 15:20:57 2019 +0100 +++ b/sys/src/cmd/tar.c Sun Nov 03 16:31:09 2019 +0100 @@ -129,6 +129,13 @@ int open; } Pushstate; +typedef struct { + Hdr *hp; + int fd; + long mtime; + ulong mode; +} Leftover; + #define OTHER(rdwr) ((rdwr) == Rd? Wr: Rd) static int fixednblock; @@ -153,6 +160,9 @@ static Hdr *tpblk, *endblk; static Hdr *curblk; +static Leftover *scraps; +static int nscrap; + static void usage(void) { @@ -238,6 +248,40 @@ return docompress? comps: nil; } +/* leftover directories management */ + +static void wrmeta(int, Hdr*, long, int); + +static void +pushleftover(Hdr *hp, int fd, long mtime, ulong mode) +{ + Leftover *l; + + /* looking for a better alloc strategy */ + scraps = realloc(scraps, ++nscrap*sizeof(Leftover)); + if(scraps == nil) + sysfatal("realloc: %r"); + l = scraps+(nscrap-1); + l->hp = hp; + l->fd = fd; + l->mtime = mtime; + l->mode = mode; +} + +static void +flushleftovers(void) +{ + Leftover *l; + + while(nscrap-- > 0){ + l = scraps+nscrap; + wrmeta(l->fd, l->hp, l->mtime, l->mode); + close(l->fd); + } + free(scraps); + scraps = nil; +} + /* * push a filter, cmd, onto fd. if input, it's an input descriptor. * returns a descriptor to replace fd, or -1 on error. @@ -1145,11 +1189,12 @@ { int fd = -1, dir = 0; long mtime = strtol(hp->mtime, nil, 8); - ulong mode = strtoul(hp->mode, nil, 8) & 0777; + ulong mode0 = strtoul(hp->mode, nil, 8) & 0777, mode; Off bytes = hdrsize(hp); /* for printing */ ulong blksleft = BYTES2TBLKS(arsize(hp)); /* fiddle name, figure out mode and blocks */ + mode = mode0; if (isdir(hp)) { mode |= DMDIR|0700; dir = 1; @@ -1182,14 +1227,14 @@ copyfromar(ar, fd, fname, blksleft, bytes); - /* touch up meta data and close */ + /* touch up meta data and close, dirs are saved for later */ if (fd >= 0) { - /* - * directories should be wstated *after* we're done - * creating files in them, but we don't do that. - */ if (settime) - wrmeta(fd, hp, mtime, mode); + if (dir) { + pushleftover(hp, fd, mtime, mode0); + return; + } else + wrmeta(fd, hp, mtime, mode0); close(fd); } } @@ -1275,6 +1320,7 @@ else skip(ar, hp, longname); } + flushleftovers(); if (comp) return pushclose(&ps); --upas-xknmmrsiehnhbapkrmkeihykef--