Post by Paul KI'd like to come back to Daurnimator's suggestion to add a file
truncation function to Lua
(http://lua-users.org/lists/lua-l/2011-12/msg00111.html).
I know Luiz responded "truncating to zero length is the same as
opening for writing, except for dates", but it's beneficial in many
cases to write to the same file, as it preserves its attributes,
metadata, permissions, etc.
Paul.
At least on macOS there's no difference between truncate+0 and fopen:
inode atime mtime ctime
creat 8597642368 20:39:57 20:39:57 20:39:57
truncate 8597642368 20:39:57 20:39:59 20:39:59
fopen 8597642368 20:39:57 20:40:01 20:40:01
Perhaps truncate behaves differently on different POSIX systems or Windows
chsize behaves differently than POSIX truncate. But in either case there's
no consistency so it's not something you can depend on. Perhaps Luiz was
mistaken or being intentionally vague because he knew there was some
difference but wouldn't remember
FWIW, here's my test code using Lua 5.3:
local unix = require"unix"
local function stat_and_print(path, test)
local st = assert(unix.stat(path))
print(test,
st.ino,
os.date("%H:%M:%S", st.atime // 1),
os.date("%H:%M:%S", st.mtime // 1),
os.date("%H:%M:%S", st.ctime // 1))
end
-- basically the same as fopen(path, "w")
local function creat(path, mode)
local oflag = unix.O_CREAT | unix.O_TRUNC | unix.O_WRONLY
local fd, why, errno = unix.open(path, oflag, mode)
if not fd then return false, why, errno end
unix.close(fd)
return true
end
local path = os.tmpname()
print(" ", "inode ", "atime ", "mtime ", "ctime ")
do
assert(creat(path, tonumber("666", 8)))
stat_and_print(path, "creat ")
end
unix.sleep(2)
do
assert(unix.truncate(path))
stat_and_print(path, "truncate")
end
unix.sleep(2)
do
local fh = assert(io.open(path, "w"))
stat_and_print(path, "fopen ")
fh:close()
end
assert(os.remove(path))