Skip to content

Commit c4d812a

Browse files
authored
Merge pull request #63 from zweger/develop-birthtime
Add support for birthtime field
2 parents e15d221 + e49ff04 commit c4d812a

3 files changed

Lines changed: 33 additions & 9 deletions

File tree

libarchive/entry.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,16 @@ def set_ctime(self, timestamp_sec, timestamp_nsec):
134134
return ffi.entry_set_ctime(self._entry_p,
135135
timestamp_sec, timestamp_nsec)
136136

137+
@property
138+
def birthtime(self):
139+
sec_val = ffi.entry_birthtime(self._entry_p)
140+
nsec_val = ffi.entry_birthtime_nsec(self._entry_p)
141+
return format_time(sec_val, nsec_val)
142+
143+
def set_birthtime(self, timestamp_sec, timestamp_nsec):
144+
return ffi.entry_set_birthtime(self._entry_p,
145+
timestamp_sec, timestamp_nsec)
146+
137147
def _getpathname(self):
138148
return (ffi.entry_pathname_w(self._entry_p) or
139149
ffi.entry_pathname(self._entry_p))

libarchive/ffi.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,11 @@ def ffi(name, argtypes, restype, errcheck=None):
114114

115115
ffi('entry_filetype', [c_archive_entry_p], c_int)
116116
ffi('entry_atime', [c_archive_entry_p], c_int)
117+
ffi('entry_birthtime', [c_archive_entry_p], c_int)
117118
ffi('entry_mtime', [c_archive_entry_p], c_int)
118119
ffi('entry_ctime', [c_archive_entry_p], c_int)
119120
ffi('entry_atime_nsec', [c_archive_entry_p], c_long)
121+
ffi('entry_birthtime_nsec', [c_archive_entry_p], c_long)
120122
ffi('entry_mtime_nsec', [c_archive_entry_p], c_long)
121123
ffi('entry_ctime_nsec', [c_archive_entry_p], c_long)
122124
ffi('entry_pathname', [c_archive_entry_p], c_char_p)
@@ -141,6 +143,7 @@ def ffi(name, argtypes, restype, errcheck=None):
141143
ffi('entry_set_atime', [c_archive_entry_p, c_int, c_long], None)
142144
ffi('entry_set_mtime', [c_archive_entry_p, c_int, c_long], None)
143145
ffi('entry_set_ctime', [c_archive_entry_p, c_int, c_long], None)
146+
ffi('entry_set_birthtime', [c_archive_entry_p, c_int, c_long], None)
144147

145148
ffi('entry_update_pathname_utf8', [c_archive_entry_p, c_char_p], None)
146149

tests/test_atime_mtime_ctime.py

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
from copy import copy
44
from os import stat
55

6-
from libarchive import (file_reader, file_writer, memory_reader,
7-
memory_writer)
6+
from libarchive import (file_reader, file_writer, memory_reader, memory_writer)
87

98
import pytest
109

@@ -66,53 +65,65 @@ def test_file_atime_ctime(archfmt, timefmt, tmpdir):
6665

6766
@pytest.mark.parametrize('archfmt,timefmt', [('zip', int), ('pax', float)])
6867
def test_memory_time_setters(archfmt, timefmt):
69-
# Create an archive of our libarchive/ directory
68+
has_birthtime = archfmt != 'zip'
7069

71-
atimestamp = (1482144741, 495628118)
72-
mtimestamp = (1482155417, 659017086)
73-
ctimestamp = (1482145211, 536858081)
70+
# Create an archive of our libarchive/ directory
7471
buf = bytes(bytearray(1000000))
7572
with memory_writer(buf, archfmt) as archive1:
7673
archive1.add_files('libarchive/')
7774

75+
atimestamp = (1482144741, 495628118)
76+
mtimestamp = (1482155417, 659017086)
77+
ctimestamp = (1482145211, 536858081)
78+
btimestamp = (1482144740, 495628118)
7879
buf2 = bytes(bytearray(1000000))
7980
with memory_reader(buf) as archive1:
8081
with memory_writer(buf2, archfmt) as archive2:
8182
for entry in archive1:
8283
entry.set_atime(*atimestamp)
8384
entry.set_mtime(*mtimestamp)
8485
entry.set_ctime(*ctimestamp)
86+
if has_birthtime:
87+
entry.set_birthtime(*btimestamp)
8588
archive2.add_entries([entry])
8689

8790
with memory_reader(buf2) as archive2:
8891
for entry in archive2:
8992
assert entry.atime == time_check(atimestamp, timefmt)
9093
assert entry.mtime == time_check(mtimestamp, timefmt)
9194
assert entry.ctime == time_check(ctimestamp, timefmt)
95+
if has_birthtime:
96+
assert entry.birthtime == time_check(btimestamp, timefmt)
9297

9398

9499
@pytest.mark.parametrize('archfmt,timefmt', [('zip', int), ('pax', float)])
95100
def test_file_time_setters(archfmt, timefmt, tmpdir):
101+
has_birthtime = archfmt != 'zip'
102+
96103
# Create an archive of our libarchive/ directory
97104
archive_path = tmpdir.join('/test.{0}'.format(archfmt)).strpath
98105
archive2_path = tmpdir.join('/test2.{0}'.format(archfmt)).strpath
106+
with file_writer(archive_path, archfmt) as archive1:
107+
archive1.add_files('libarchive/')
99108

100109
atimestamp = (1482144741, 495628118)
101110
mtimestamp = (1482155417, 659017086)
102111
ctimestamp = (1482145211, 536858081)
103-
with file_writer(archive_path, archfmt) as archive1:
104-
archive1.add_files('libarchive/')
105-
112+
btimestamp = (1482144740, 495628118)
106113
with file_reader(archive_path) as archive1:
107114
with file_writer(archive2_path, archfmt) as archive2:
108115
for entry in archive1:
109116
entry.set_atime(*atimestamp)
110117
entry.set_mtime(*mtimestamp)
111118
entry.set_ctime(*ctimestamp)
119+
if has_birthtime:
120+
entry.set_birthtime(*btimestamp)
112121
archive2.add_entries([entry])
113122

114123
with file_reader(archive2_path) as archive2:
115124
for entry in archive2:
116125
assert entry.atime == time_check(atimestamp, timefmt)
117126
assert entry.mtime == time_check(mtimestamp, timefmt)
118127
assert entry.ctime == time_check(ctimestamp, timefmt)
128+
if has_birthtime:
129+
assert entry.birthtime == time_check(btimestamp, timefmt)

0 commit comments

Comments
 (0)