From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from relay12.mail.gandi.net ([217.70.178.232]) by ewsd; Sat Nov 2 14:33:06 EDT 2019 Received: from jupiter.antares-labs.eu (unknown [185.198.110.254]) (Authenticated sender: rgl@antares-labs.eu) by relay12.mail.gandi.net (Postfix) with ESMTPSA id B7F96200003; Sat, 2 Nov 2019 18:32:57 +0000 (UTC) Message-ID: Date: Sat, 2 Nov 2019 19:32:33 +0100 From: rgl@antares-labs.eu To: 9front@9front.org Subject: tar: write directory metadata after file extraction MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="upas-flriqkgludlnyogkyvjjeowcne" List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: social non-blocking hardware session event This is a multi-part message in MIME format. --upas-flriqkgludlnyogkyvjjeowcne Content-Disposition: inline Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit hi community, i implemented the expected behavior for directories when using the T option. cheers, -rodri --upas-flriqkgludlnyogkyvjjeowcne Content-Disposition: inline Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit diff -r 1d6a49358dd8 sys/src/cmd/tar.c --- a/sys/src/cmd/tar.c Sat Nov 02 14:17:34 2019 +0100 +++ b/sys/src/cmd/tar.c Sat Nov 02 19:04:49 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. @@ -1182,14 +1226,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, mode); + return; + } else + wrmeta(fd, hp, mtime, mode); close(fd); } } @@ -1275,6 +1319,7 @@ else skip(ar, hp, longname); } + flushleftovers(); if (comp) return pushclose(&ps); --upas-flriqkgludlnyogkyvjjeowcne--