Menu

#2308 Created and Accessed timestamps are not stored correctly under macOS

open
nobody
None
1
2021-08-26
2021-08-24
ungrek
No

1)

stat -f "Modified: %Sm%nCreated: %SB%nAccessed: %Sa%n" /Users/anna/Desktop/test.txt 
Modified: Aug 24 09:21:50 2021
Created: Aug 23 07:35:37 2021
Accessed: Aug 24 09:21:50 2021

2)

/Users/anna/Desktop/7z2103-mac/7zz a -mtm -mtc -mta test.7z /Users/anna/Desktop/test.txt 

7-Zip (z) 21.03 beta (x64) : Copyright (c) 1999-2021 Igor Pavlov : 2021-07-20
 64-bit locale=en_US.UTF-8 Threads:2

Scanning the drive:
1 file, 4 bytes (1 KiB)        

Creating archive: test.7z

Add new data to archive: 1 file, 4 bytes (1 KiB)


Files read from disk: 1
Archive size: 162 bytes (1 KiB)
Everything is Ok

3)

/Users/anna/Desktop/7z2103-mac/7zz l -slt /Users/anna/Desktop/test.7z 

7-Zip (z) 21.03 beta (x64) : Copyright (c) 1999-2021 Igor Pavlov : 2021-07-20
 64-bit locale=en_US.UTF-8 Threads:2

Scanning the drive for archives:
1 file, 162 bytes (1 KiB)     

Listing archive: /Users/anna/Desktop/test.7z

--
Path = /Users/anna/Desktop/test.7z
Type = 7z
Physical Size = 162
Headers Size = 154
Method = LZMA2:12
Solid = -
Blocks = 1

----------
Path = test.txt
Size = 4
Packed Size = 8
Modified = 2021-08-24 09:21:50
Created = 2021-08-24 09:21:50
Accessed = 2021-08-24 09:33:04
Attributes = A -rw-r--r--
CRC = D87F7E0C
Encrypted = -
Method = LZMA2:12
Block = 0

The problems:
- Created timestamp has the same as Modified timestamp
- Accessed timestamp has the current system time when an archive was created

Discussion

  • ungrek

    ungrek - 2021-08-25

    I have tested it with macOS 10.13.6 (Darwin kernel version 17.7.0) and HFS+ filesystem.

    Now new results with the current macOS 12.0 Beta 5 (Darwin kernel version 21.0.0) and APFS filesystem.

    1) Have now additionally added Changed

    stat -f "Modified: %Sm%nCreated: %SB%nAccessed: %Sa%nChanged: %Sc%n" /Users/anna/Desktop/1234.rtf
    Modified: Aug 25 13:59:01 2021
    Created: Aug 25 13:57:02 2021
    Accessed: Aug 25 13:59:01 2021
    Changed: Aug 25 14:00:15 2021
    

    2)

    /Users/anna/Desktop/7z2103-mac/7zz a -mtm -mtc -mta 1234.7z /Users/anna/Desktop/1234.rtf 
    
    7-Zip (z) 21.03 beta (x64) : Copyright (c) 1999-2021 Igor Pavlov : 2021-07-20
     64-bit locale=en_US.UTF-8 Threads:2
    
    Scanning the drive:
    1 file, 379 bytes (1 KiB)        
    
    Creating archive: 1234.7z
    
    Add new data to archive: 1 file, 379 bytes (1 KiB)
    
    
    Files read from disk: 1
    Archive size: 428 bytes (1 KiB)
    Everything is Ok
    

    3)

    /Users/anna/Desktop/7z2103-mac/7zz l -slt /Users/anna/Desktop/1234.7z 
    
    7-Zip (z) 21.03 beta (x64) : Copyright (c) 1999-2021 Igor Pavlov : 2021-07-20
     64-bit locale=en_US.UTF-8 Threads:2
    
    Scanning the drive for archives:
    1 file, 428 bytes (1 KiB)     
    
    Listing archive: /Users/anna/Desktop/1234.7z
    
    --
    Path = /Users/anna/Desktop/1234.7z
    Type = 7z
    Physical Size = 428
    Headers Size = 162
    Method = LZMA2:12
    Solid = -
    Blocks = 1
    
    ----------
    Path = 1234.rtf
    Size = 379
    Packed Size = 266
    Modified = 2021-08-25 13:59:01
    Created = 2021-08-25 14:00:15
    Accessed = 2021-08-25 13:59:01
    Attributes = A -rw-r--r--
    CRC = 974211BF
    Encrypted = -
    Method = LZMA2:12
    Block = 0
    

    Additional details:
    According to this page there are 4 timestamps.
    https://github.com/apple/darwin-xnu/blob/main/bsd/man/man2/stat.2

        struct timespec st_atimespec;     /* time of last access */
        struct timespec st_mtimespec;     /* time of last data modification */
        struct timespec st_ctimespec;     /* time of last status change */
        struct timespec st_birthtimespec; /* time of file creation(birth) */
    

    If you see the results with Darwin kernel version 21.0.0, the 7-Zip for macOS console version does not store birthtime (another word for creation time) in this case. It incorrectly stores ctime (time of last status change). atime (Accessed) was stored correctly.

    @ipavlov
    Can you reproduce the problem on your side as well?

     
    • Igor Pavlov

      Igor Pavlov - 2021-08-26

      birthtimespec is not standard field for linux, as I suppose.
      So the simplest solution was to store linux timestamp ctime (changed in linux) to ctime (created in Windows) in 7-Zip.
      Maybe we should fix it some way. But the compatibility problems are possible when we have different old/new archives and different systems.

       
  • ungrek

    ungrek - 2021-08-26

    birthtimespec is not standard field for linux, as I suppose.

    Since Linux 4.11 (released 30 Apr 2017) the system call stat can also display file creation time. In Linux it is called btime = Windows ctime.
    https://kernelnewbies.org/Linux_4.11
    https://lwn.net/Articles/707602/

    struct statx_timestamp  stx_atime;  /* Last access time */
    struct statx_timestamp  stx_btime;  /* File creation time */
    struct statx_timestamp  stx_ctime;  /* Last attribute change time */
    struct statx_timestamp  stx_mtime;  /* Last data modification time */
    

    So the simplest solution was to store linux timestamp ctime (changed in linux) to ctime (created in Windows) in 7-Zip.

    This behavior should be changed because ctime on Linux is not the same as ctime on Windows.

    ctime on Linux is already updated when renaming the file. Tested with Fedora 34 Workstation - Linux Kernel version 5.11.12-300.fc34.x86_64.

    1) Create a .txt file with touch command
    touch Linux.txt
    
    2) Run stat command
    stat '/home/anna/Linux.txt' 
      File: /home/anna/Linux.txt
      Size: 0           Blocks: 0          IO Block: 4096   regular empty file
    Device: 25h/37d Inode: 494         Links: 1
    Access: (0664/-rw-rw-r--)  Uid: ( 1000/    anna)   Gid: ( 1000/    anna)
    Context: unconfined_u:object_r:user_home_t:s0
    Access: 2021-08-26 08:49:37.894543533 -0400
    Modify: 2021-08-26 08:49:37.894543533 -0400
    Change: 2021-08-26 08:49:37.894543533 -0400
     Birth: 2021-08-26 08:49:37.894543533 -0400
    
    3) Rename file name
    mv '/home/anna/Linux.txt' '/home/anna/Linux2.txt'
    
    4) Run stat command
    stat '/home/anna/Linux2.txt' 
      File: /home/anna/Linux2.txt
      Size: 0           Blocks: 0          IO Block: 4096   regular empty file
    Device: 25h/37d Inode: 494         Links: 1
    Access: (0664/-rw-rw-r--)  Uid: ( 1000/    anna)   Gid: ( 1000/    anna)
    Context: unconfined_u:object_r:user_home_t:s0
    Access: 2021-08-26 08:49:37.894543533 -0400
    Modify: 2021-08-26 08:49:37.894543533 -0400
    Change: 2021-08-26 08:56:14.901016675 -0400
     Birth: 2021-08-26 08:49:37.894543533 -0400
    

    Note: If I do the same on macOS 12.0, the result is the same. ctime on macOS behaves exactly like Linux when renaming the file name.

    Maybe we should fix it some way.

    I don't think it can be fixed for Linux because there is no system call to set btime = Windows ctime to any value. This is important because of the extraction to set the file creation time correctly. There is a discussion and the Linux kernel developers decline this for personal reasons. The Linux kernel developers will not include this in the upstream kernel.
    https://patchwork.kernel.org/project/linux-btrfs/cover/cover.1550136164.git.osandov@fb.com/

    On Linux, when I copy files locally from the source to the destination, Linux sets btime to the current copy time for the destination. There is no way to change this behavior. The software Windows Explorer also behaves like this by default. But on Windows there is generally the possibility to change this behavior.

    Under macOS it is different: "birthtimespec" is kept by default when copying files from source to destination.

    Additional info:
    After editing a .txt file on Linux, btime always has the same value as mtime. On Windows this is not so, here Windows ctime has the original value and only modified time has been updated, on macOS it is the same as on Windows.

    Therefore, the suggestion is that in the next Linux/Unix 7-Zip console version to remove the storing of Linux/Unix ctime to avoid misunderstandings. When the switch mtc is run, this note should appear: This 7-Zip does not support mtc.

    But the compatibility problems are possible when we have different old/new archives and different systems.

    That could be, I think the problems are only for users who use Windows.

    If a Windows user has a .7z file created with an older 7-Zip Linux/Unix console version with the mtc switch. The user on Windows will usually see an equal or higher value for creation time than modified time. Here the Windows user has to take care himself and keep his archive up to date and use Windows instead of Linux/Unix if he wants to store file creation time correctly.

    What about macOS and other Unix systems?

    According to this site https://apple.stackexchange.com/a/99599 "birthtimespec" can be changed on macOS with Xcode Command Line Tools.

    SetFile -d '12/31/1999 23:59:59' file.txt
    

    I can confirm that it works. I also tested with a very old macOS version in 2011 (OS X 10.7). It looks like macOS supports it for a very long time, probably at least since Windows XP (year 2001). Here could be improved only for the 7-Zip macOS console version that it has the same behavior on Windows.

    For other Unix systems, like NetBSD or FreeBSD I have not found anything.

    What about other systems?

    Haiku (successor of BeOS) can do this. It uses ctime which is just like Windows ctime.
    https://www.haiku-os.org/docs/api/classBStatable.html#a6a92b04cda608babf49f70ef4e3a2f36

     

    Last edit: ungrek 2021-08-26

Log in to post a comment.