Skip to content

Files with pre-1980 timestamps are incorrectly treated as non-existent #464

@pseudofractal

Description

@pseudofractal

I encountered this issue while trying to package IRAF for Nix.

IRAF uses a 1980 epoch internally, converting Unix timestamps via gmt_to_lst() in unix/os/zfinfo.c:

fs->fi_atime = gmt_to_lst (osfile.st_atime);
fs->fi_mtime = gmt_to_lst (osfile.st_mtime);
fs->fi_ctime = gmt_to_lst (osfile.st_ctime);

Files with timestamps before 1980-01-01 result in negative values. In pkg/cl/pfiles.c (lines 260-263), the check:

if ((pkg_ftime = filetime (pkg_pfile, "m")) <= 0) {
    mkpfilename (pkg_pfile, pkgdir, pkname, ltname, ".cl");
    if ((pkg_ftime = filetime (pkg_pfile, "m")) <= 0)
        cl_error (E_UERR, e_nopfile, ltname);
}

treats <= 0 as "file not found", causing valid .par files with pre-1980 timestamps to fail with:

ERROR: Cannot find pfile for task "..."

When can this happen:

  • Nix: All files in /nix/store have timestamp 1 (1970-01-01 00:00:01 UTC) for reproducibility
  • Old archives: Files from tapes/archives predating 1980
  • Reproducible builds: Any other build system that normalize timestamps to epoch

This can probably be fixed by clamping the negative timestamps to 1 in unix/os/zfinfo.c.

fs->fi_atime = gmt_to_lst (osfile.st_atime);
if (fs->fi_atime <= 0) fs->fi_atime = 1;
fs->fi_mtime = gmt_to_lst (osfile.st_mtime);
if (fs->fi_mtime <= 0) fs->fi_mtime = 1;
fs->fi_ctime = gmt_to_lst (osfile.st_ctime);
if (fs->fi_ctime <= 0) fs->fi_ctime = 1;

This should ensure that files with pre-1980 timestamps are still recognized as existing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions