diff --git a/usr.sbin/makefs/makefs.8 b/usr.sbin/makefs/makefs.8 --- a/usr.sbin/makefs/makefs.8 +++ b/usr.sbin/makefs/makefs.8 @@ -33,7 +33,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd January 19, 2024 +.Dd April 7, 2025 .Dt MAKEFS 8 .Os @@ -594,6 +594,24 @@ .It setuid .El .El +.Sh ENVIRONMENT +.Bl -tag +.It Ev SOURCE_DATE_EPOCH +The +.Ev SOURCE_DATE_EPOCH +environment variable can be used to specify a timestamp +in the same way as the +.Fl T +flag. When both +.Ev SOURCE_DATE_EPOCH +and +.Fl T +are present, the timestamp specified by the +.Ev SOURCE_DATE_EPOCH +variable overrides the timestamp specified by the +.Fl T +flag. +.Pp .Sh SEE ALSO .Xr mtree 5 , .Xr rc.conf 5 , diff --git a/usr.sbin/makefs/makefs.c b/usr.sbin/makefs/makefs.c --- a/usr.sbin/makefs/makefs.c +++ b/usr.sbin/makefs/makefs.c @@ -98,6 +98,7 @@ fsinfo_t fsoptions; fsnode *root; int ch, i, len; + const char *env; const char *subtree; const char *specfile; @@ -126,6 +127,9 @@ if (ch == -1) err(1, "Unable to get system time"); + env = getenv("SOURCE_DATE_EPOCH"); + if (env != NULL && get_tstamp(env, &stampst) == -1) + errx(1, "Cannot get timestamp from SOURCE_DATE_EPOCH"); while ((ch = getopt(argc, argv, "B:b:Dd:f:F:M:m:N:O:o:pR:s:S:t:T:xZ")) != -1) { switch (ch) { diff --git a/usr.sbin/makefs/tests/makefs_ffs_tests.sh b/usr.sbin/makefs/tests/makefs_ffs_tests.sh --- a/usr.sbin/makefs/tests/makefs_ffs_tests.sh +++ b/usr.sbin/makefs/tests/makefs_ffs_tests.sh @@ -288,6 +288,53 @@ common_cleanup } +atf_test_case source_date_epoch cleanup +source_date_epoch_body() +{ + timestamp=1742574909 + create_test_dirs + + mkdir -p $TEST_INPUTS_DIR/dir1 + export SOURCE_DATE_EPOCH=$timestamp + atf_check -e empty -o not-empty -s exit:0 \ + $MAKEFS -M 1m $TEST_IMAGE $TEST_INPUTS_DIR + + mount_image + eval $(stat -s $TEST_MOUNT_DIR/dir1) + atf_check_equal $st_atime $timestamp + atf_check_equal $st_mtime $timestamp + atf_check_equal $st_ctime $timestamp +} + +source_date_epoch_cleanup() +{ + common_cleanup +} + +atf_test_case T_flag_source_date_epoch cleanup +T_flag_source_date_epoch_body() +{ + timestamp_env=1742574909 + timestamp_T=1742574910 + create_test_dirs + + mkdir -p $TEST_INPUTS_DIR/dir1 + export SOURCE_DATE_EPOCH=$timestamp_env + atf_check -e empty -o not-empty -s exit:0 \ + $MAKEFS -T $timestamp_T -M 1m $TEST_IMAGE $TEST_INPUTS_DIR + + mount_image + eval $(stat -s $TEST_MOUNT_DIR/dir1) + atf_check_equal $st_atime $timestamp_T + atf_check_equal $st_mtime $timestamp_T + atf_check_equal $st_ctime $timestamp_T +} + +T_flag_source_date_epoch_cleanup() +{ + common_cleanup +} + atf_init_test_cases() { @@ -299,9 +346,11 @@ atf_add_test_case from_mtree_spec_file atf_add_test_case from_multiple_dirs atf_add_test_case from_single_dir + atf_add_test_case source_date_epoch atf_add_test_case o_flag_version_1 atf_add_test_case o_flag_version_2 atf_add_test_case T_flag_dir atf_add_test_case T_flag_mtree + atf_add_test_case T_flag_source_date_epoch }