I'm using OpenBSD 7.0 GENERIC.MP#232 amd64. OpenBSD's tar and pax seem to always think mtimes are zero when extracting tar files created by OpenBSD's python3 (python-3.8.12).
These tar files have correct mtimes when opened by python3 itself or read by gtar from ports. Similarly, Linux tar sees correct mtimes. `file` claims the tar files are 'POSIX tar archive'. OpenBSD's python2 doesn't seem to have this probelem - it creates tar files that work correctly with OpenBSD's tar and pax. When loading a python3-created tar file in python3, it says the format is 2, which is tarfile.PAX_FORMAT, so i would have expected things to work with tar and pax. Python-3.8 changed the default from GNU_FORMAT to PAX_FORMAT (https://docs.python.org/3/library/tarfile.html#tar-formats "Changed in version 3.8: The default format for new archives was changed to PAX_FORMAT from GNU_FORMAT."). [So could it be possible that python3 is actually generating GNU_FORMAT tar archives, but claiming that they are PAX_FORMAT? I've had a quick look at Python-3.8.12/Lib/tarfile.py and it doesn't seem to have any obvious error like this.] The attached tarmtime.py script demonstrates the problem - it creates various tar archives and extracts with `tar` and `pax` and shows the `Jan 1 1970` mtimes. Thanks for any advice here, - Julian -- http://op59.net
#!/usr/bin/env python3 import io import os import sys import tarfile import time def system( command): print( 'running: %s' % command) sys.stdout.flush() return os.system( command) with tarfile.open('tarmtime1.tgz', 'w:gz') as t: t.add( 'tarmtime.py', 'tarmtime1/tarmtime.py') system( 'tar -xzf tarmtime1.tgz') system( 'ls -l tarmtime1/*') with tarfile.open('tarmtime2.tar', 'w') as t: t.add( 'tarmtime.py', 'tarmtime2/tarmtime.py') system( 'tar -xf tarmtime2.tar') system( 'ls -l tarmtime2/*') if 1: with tarfile.open('tarmtime2.tar', 'r') as t: ti = t.getmember( 'tarmtime2/tarmtime.py') print( 'ti: name=%s size=%s mtime=%s' % (ti.name, ti.size, ti.mtime)) with tarfile.open('tarmtime3.tar', 'w') as t: data = b'123' ti = tarfile.TarInfo( 'tarmtime3/foo') ti.size = len( data) #ti.mtime = time.time() data2 = io.BytesIO(data) t.addfile(ti, data2) ti = tarfile.TarInfo( 'tarmtime3/bar') ti.size = len( data) ti.mtime = time.time() data2 = io.BytesIO(data) t.addfile(ti, data2) system( 'tar -xf tarmtime3.tar') system( 'ls -l tarmtime3/*') system( 'pax -r -f tarmtime3.tar') system( 'ls -l tarmtime3/*') system( 'rm -r tarmtime3') system( 'gtar -xf tarmtime3.tar') system( 'ls -l tarmtime3/*') if 1: with tarfile.open('tarmtime3.tar', 'r') as t: ti = t.getmember( 'tarmtime3/foo') print( 'ti: name=%s size=%s mtime=%s' % (ti.name, ti.size, ti.mtime)) ti = t.getmember( 'tarmtime3/bar') print( 'ti: name=%s size=%s mtime=%s' % (ti.name, ti.size, ti.mtime)) print( 'Cleanup with: rm -r tarmtime1* tarmtime2* tarmtime3*')