From 575ea5c2365336ca15ced10a200e4a9f02094f0b Mon Sep 17 00:00:00 2001 From: Norayr Chilingarian Date: Fri, 18 Sep 2026 01:46:06 +0400 Subject: [PATCH] Platform.SetFileMtime and oocFiles.SetModTime. --- src/library/ooc/oocFiles.Mod | 24 ++++++++++++++++++++++-- src/library/ooc/oocFilesHost.Mod | 6 ++++++ src/runtime/Platformunix.Mod | 28 ++++++++++++++++++++++++++++ src/runtime/Platformwindows.Mod | 31 ++++++++++++++++++++++++++++++- 4 files changed, 86 insertions(+), 3 deletions(-) diff --git a/src/library/ooc/oocFiles.Mod b/src/library/ooc/oocFiles.Mod index 1bb04ce1..5096d75c 100644 --- a/src/library/ooc/oocFiles.Mod +++ b/src/library/ooc/oocFiles.Mod @@ -566,9 +566,29 @@ BEGIN END Tmp; PROCEDURE SetModTime* (file: ARRAY OF CHAR; mtime: Time.TimeStamp; VAR res: Result); + VAR + name: ARRAY maxPath OF CHAR; + day, month: SHORTINT; + year: INTEGER; + hour, minute, second, seconds: LONGINT; + error: Host.Error; BEGIN - (* The current host interface exposes modification-time queries only. *) - res := GetError(noModTime) + IF (mtime.msecs < 0) OR (mtime.msecs >= Time.msecPerDay) THEN + res := GetError(invalidTime); + RETURN + END; + JulianDay.DaysToDate(mtime.days, day, month, year); + IF year <= 0 THEN + res := GetError(invalidTime); + RETURN + END; + seconds := mtime.msecs DIV Time.msecPerSec; + hour := seconds DIV 3600; + minute := (seconds DIV 60) MOD 60; + second := seconds MOD 60; + COPY(file, name); + error := Host.SetModTime(name, year, month, day, hour, minute, second); + IF error = 0 THEN res := done ELSE res := OpenError(error) END END SetModTime; PROCEDURE GetModTime* (file: ARRAY OF CHAR; VAR mtime: Time.TimeStamp; VAR res: Result); diff --git a/src/library/ooc/oocFilesHost.Mod b/src/library/ooc/oocFilesHost.Mod index 769cf280..3f601192 100644 --- a/src/library/ooc/oocFilesHost.Mod +++ b/src/library/ooc/oocFilesHost.Mod @@ -109,6 +109,12 @@ BEGIN RETURN error END GetModTime; +PROCEDURE SetModTime* (VAR name: ARRAY OF CHAR; year, month, day, + hour, minute, second: LONGINT): Error; +BEGIN + RETURN Platform.SetFileMTime(name, year, month, day, hour, minute, second) +END SetModTime; + PROCEDURE CurrentDirectory* (VAR path: ARRAY OF CHAR); BEGIN COPY(Platform.CWD, path) diff --git a/src/runtime/Platformunix.Mod b/src/runtime/Platformunix.Mod index bcf11137..0fc15bff 100644 --- a/src/runtime/Platformunix.Mod +++ b/src/runtime/Platformunix.Mod @@ -41,6 +41,7 @@ PROCEDURE -Aincludeunistd '#include '; PROCEDURE -Aincludesysstat '#include '; PROCEDURE -Aincludefcntl '#include '; PROCEDURE -Aincludeerrno '#include '; +PROCEDURE -Aincludeutime '#include '; PROCEDURE -Astdlib '#include '; PROCEDURE -Astdio '#include '; PROCEDURE -Aerrno '#include '; @@ -262,6 +263,33 @@ BEGIN END Close; +PROCEDURE -mtimevars "struct tm mtm = {0}; struct utimbuf mtimes"; +PROCEDURE -setmtimedate(year, month, day: LONGINT) +"mtm.tm_year = (int)year-1900; mtm.tm_mon = (int)month-1; mtm.tm_mday = (int)day"; +PROCEDURE -setmtimetime(hour, minute, second: LONGINT) +"mtm.tm_hour = (int)hour; mtm.tm_min = (int)minute; mtm.tm_sec = (int)second; mtm.tm_isdst = -1"; +PROCEDURE -makemtime(): INTEGER "(mtimes.modtime = mktime(&mtm)) != (time_t)-1"; +PROCEDURE -invalidmtime "errno = EINVAL"; +PROCEDURE -applymtime(n: ARRAY OF CHAR): INTEGER +"(mtimes.actime = mtimes.modtime, utime((char*)n, &mtimes))"; + +PROCEDURE SetFileMTime* (VAR n: ARRAY OF CHAR; year, month, day, + hour, minute, second: LONGINT): ErrorCode; +BEGIN + mtimevars; + setmtimedate(year, month, day); + setmtimetime(hour, minute, second); + IF makemtime() = 0 THEN + invalidmtime; + RETURN err() + ELSIF applymtime(n) < 0 THEN + RETURN err() + ELSE + RETURN 0 + END +END SetFileMTime; + + PROCEDURE -isatty(fd: LONGINT): INTEGER "isatty(fd)"; PROCEDURE IsConsole*(h: FileHandle): BOOLEAN; diff --git a/src/runtime/Platformwindows.Mod b/src/runtime/Platformwindows.Mod index 63c90a69..3d2f7729 100644 --- a/src/runtime/Platformwindows.Mod +++ b/src/runtime/Platformwindows.Mod @@ -171,7 +171,7 @@ PROCEDURE -styear(): INTEGER "(INTEGER)st.wYear"; PROCEDURE YMDHMStoClock(ye,mo,da,ho,mi,se: INTEGER; VAR t, d: LONGINT); BEGIN - d := ASH(ye MOD 100, 9) + ASH(mo+1, 5) + da; + d := ASH(ye MOD 100, 9) + ASH(mo, 5) + da; t := ASH(ho, 12) + ASH(mi, 6) + se; END YMDHMStoClock; @@ -289,6 +289,35 @@ BEGIN END Close; +PROCEDURE -openwriteattributes(n: ARRAY OF CHAR): FileHandle +"(ADDRESS)CreateFile((char*)n, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)"; + +PROCEDURE -mtimevars "SYSTEMTIME mst = {0}; FILETIME mft"; +PROCEDURE -setmtimedate(year, month, day: LONGINT) +"mst.wYear = (WORD)year; mst.wMonth = (WORD)month; mst.wDay = (WORD)day"; +PROCEDURE -setmtimetime(hour, minute, second: LONGINT) +"mst.wHour = (WORD)hour; mst.wMinute = (WORD)minute; mst.wSecond = (WORD)second"; +PROCEDURE -makemtime(): INTEGER "(INTEGER)SystemTimeToFileTime(&mst, &mft)"; +PROCEDURE -applymtime(h: FileHandle): INTEGER +"(INTEGER)SetFileTime((HANDLE)h, 0, 0, &mft)"; + +PROCEDURE SetFileMTime* (VAR n: ARRAY OF CHAR; year, month, day, + hour, minute, second: LONGINT): ErrorCode; + VAR handle: FileHandle; result: INTEGER; error, closeError: ErrorCode; +BEGIN + handle := openwriteattributes(n); + IF handle = invalidHandleValue() THEN RETURN err() END; + mtimevars; + setmtimedate(year, month, day); + setmtimetime(hour, minute, second); + result := makemtime(); + IF result # 0 THEN result := applymtime(handle) END; + IF result = 0 THEN error := err() ELSE error := 0 END; + closeError := Close(handle); + IF error # 0 THEN RETURN error ELSE RETURN closeError END +END SetFileMTime; + + PROCEDURE -byHandleFileInformation "BY_HANDLE_FILE_INFORMATION bhfi"; PROCEDURE -getFileInformationByHandle(h: FileHandle): INTEGER "(INTEGER)GetFileInformationByHandle((HANDLE)h, &bhfi)";