[tlbuild] dvi test?
Bruno Haible
bruno at clisp.org
Wed Feb 2 02:53:32 CET 2022
Karl Berry wrote:
> I think it's the implementation of ftruncate that is doing that lseek
I don't think so: ftruncate is marked as a "system call" in macOS [1];
if ftruncate() would change the file descriptor's position, you wouldn't
see it in the dtruss log.
Rather, the situation is that the OS provides two subsystems:
* the file descriptors, nearly entirely handled in the kernel,
* the FILE streams, implemented in libc, based on file descriptor
system calls. In particular, a FILE stream typically has a file
descriptor, a cache for the position of that file descriptor, a
buffer and a "next byte to read" pointer into that buffer.
fseek() on buffered FILE streams is typically implemented as follows:
- if the new position is inside the buffer region, it just updates
some fields in the FILE struct,
- otherwise it invalidates the buffer and makes an lseek() call on
the file descriptor.
IMPORTANT: The FILE stream implementation assumes that it owns
the file descriptor, that is, that the application does not do
system calls with the file descriptor.
It could well be that the make_backup_fp function, especially
through
target_fp = try_fdopen(tmp_fd, "wb+")
and continued use of tmp_fd, violates this assumption.
John Hawkinson wrote:
> with my current tree which does the fseek() before the ftruncate(), EINVAL (Err#22) is still returned by lseek()
> This happens
>
> lseek(0x6, 0xFFFFFFFFFFFFF7CF, 0x1) = -1 Err#22
>
> right when I step over
>
> -> 1188 if (fseek(target_fp, 0L, SEEK_SET)) {
Per the lseek() documentation [2], the argument that fseek() passes
to lseek() would lead to a negative file descriptor position.
Here are two guesses about the cause:
- Maybe the FILE stream implementation assumes that the fd passed
to fdopen() is at position 0 ?
- Maybe xdvi is changing the position of tmp_fd after fdopen(tmp_fd)
has been called, thus disturbing the position cache in the FILE
struct?
> On the other hand, it seems to point to https://github.com/apple-oss-distributions/Libc/blob/rel/Libc-1439/stdio/FreeBSD/fseek.c which looks not to have updated since 2014 (before this issue was introduced) and does not implement fseek() in terms of lseek().
fseek() does call lseek(), but on BSD systems this does not happen
directly, but through _ftello or _sseek.
Bruno
[1] https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/ftruncate.2.html
[2] https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/lseek.2.html
More information about the tlbuild
mailing list.