Closed tomyun closed 5 years ago
Is this only in PC-98 mode or is this a problem with general DOS emulation?
Does this happen in the IBM PC/XT/AT mode?
That's a good question. I didn't test it on IBM PC mode and a quick testing confirms that it also has a similar issue.
A new file created in an IMGMOUNT-ed disk image has timestamp of 00-00-1980 0:00
. Once it's copied out to a regular MOUNT point, its timestamp is shown as 30-11-2107 0:00
in dosbox-x. Interestingly, the same file seen from Finder has a different timestamp like Nov 30, 1979 at 12:00 AM
.
A file copied from MOUNT to IMGMOUNT shows 00-00-1980 0:00
on dosbox-x. Once its copied out to MOUNT back, its timestamp becomes 30-11-2107 0:00
as above.
Confirmed, on Linux, given a floppy image.
However copying it back to C: gives today's date.
Well, the first hint is that in src/dos/drive_fat.cpp, the function to create a new file uses memset() to create a new directory entry and then only fills in the attributes.
So a date/time field of 0x0000 0x0000 is Jan 1st, 1980 midnight as you'd expect.
I see an interesting problem here: The FAT driver is using the "created" file time/date fields that were added by Windows 95, not the original MS-DOS "modified" file time/date fields.
I made corrections to the FAT driver in the latest commit that corrects this issue.
Newly created files have the current date/time from the system.
If the DOS program writes to the file, the date/time is updated when the file is closed.
If a call is made to set the file date/time, then that time is written when the file is closed, so that COPY.EXE can preserve the file's date/time on the disk image.
Finally, the code was modified to use the MS-DOS "last modified" field that has existed since MS-DOS 1.0 rather than the "created" field that Windows 95 added.
It's great that you figured it out! Testing the latest HEAD confirms now it mostly works, yet there seems to be still some edge cases that need attention. For example, one of my HDI images had a few files with original timestamp set to 1980-01-01 00:00
, then these were copied to MOUNT volume with timestamp changed to the current time (i.e. 2019-02-16 17:42
).
FYI, extracting the same files with NDC gave me correct timestamps of 1980-01-01 00:00
.
I just booted an MS-DOS bootdisk and did a few tests with DEBUG.EXE.
My guess was correct in that opening the file read/write does nothing to the dirent, but writing the file updates the modified time.
I'm wondering if somehow the set time/date INT 21h call supercedes the date/time written to the dirent even if further writes are made to the file after the date/time call.
The latest commit allows the set time/date call to override the final date written to the dirent instead of forcing the current time after writing the file.
The issue seems to remain with the latest commit (b6c13940eeb0cd64f98ea1425b603ca4375683ba). Timestamp 1980-01-01 00:00
still changed to the current time after files copied into MOUNT volume.
I'm not able to reproduce this here on Linux.
Here's how I test:
However according to your description this is an issue on Mac OS X, so I will pull out a mac system and try the same there.
Using touch, like this:
bash-4.3# touch -d '1980-01-01 00:00:00' AAA bash-4.3# ls -l AAA -rw-r--r-- 1 root root 14 Jan 1 1980 AAA bash-4.3# stat AAA File: AAA Size: 14 Blocks: 8 IO Block: 4096 regular file Device: 807h/2055d Inode: 32778918 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) Access: 1980-01-01 00:00:00.000000000 -0800 Modify: 1980-01-01 00:00:00.000000000 -0800 Change: 2019-02-21 00:38:45.811595397 -0800 Birth: - bash-4.3#
Following the steps you did with touch
, I was not able to reproduce the issue on macOS either. Maybe this issue is only specific to certain files stored in the image (particularly HDI?).
Here is a disk image contains the file (TEST
in the root) that causes timestamp modification on copying. It's '1980-01-01 0:00' in IMGMOUNT then changed to '2107-11-30 0:00' in MOUNT. Confirmed that happens on both svga_s3
and pc98
machines.
Before I look at the image, I just had a thought what might be the problem.
Does the file have a date of "Jan 1st, 1980" or does the date field in the FAT filesystem actually contain 0x0000, which is technically an invalid date since you can't say the 0th of the month and month -1 does not exist (January is struct tm.tm_mon == 0 and DOSBox-X's conversion ends up setting tm_mon == -1)?
I ask because it's possible mktime() fails to produce a correct result when DOSBox-X converts the DOS date to a date for use with mktime() and mktime() is probably returning -1 (invalid time) which then comes out as 2107-11-30 when used to set the file timestamp on the local system.
Or, it's possible mktime() succeeds but cannot handle struct tm.tm_mon == -1
By the way DOSBox and DOSBox-X prior to this fix always set the date/time fields in the FAT filesystem to zero. The code to set the timestamp was not there in the code before this fix.
Hm, looking at DIR, my hunch is correct:
EDIT: 00-00-1980 could only happen if the date field is set to 0x0000. That's an invalid date and when given to mktime() produces an invalid date on the host.
So the fix to the issue is to range-check the date after conversion so that the date and time given to the file on the host filesystem is either the intended date/time or close enough if invalid.
Try the latest commit.
My bad I had hard time distinguishing between 1980-00-00
and 1980-01-01
. Anyways, confirmed 1980-00-00
got sanitized to 1980-01-01
with the latest commit. Now everything looks good to me. Thanks!
Describe the bug New files copied/created on IMGMOUNT-ed disk on PC-98 mode have incorrect timestamps.
I first found out this issue when copying some files out of IMGMOUNT-ed disk to regular MOUNT-ed disk. Further testing showed it also happens when creating a new file in IMGMOUNT-ed disk itself.
To Reproduce Steps to reproduce the behavior:
timestamp is "06-03-2095 4:47" when the original file was "05-07-2018 10:06"
C:> mkdir temp C:> cd temp C:\TEMP> echo abc > test.txt
timestamp is "00-00-1980 0:00"