tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: possible bug in fseek of buffered files shared between processes (example uses stdin)



On Tue, 2 Nov 2021, Carlo Arenas wrote:

while troubleshooting a test failure for pcre2[0] in OpenBSD, tracked
down the problem to code that was inherited from NetBSD for their
fseek implementation in libc.


This isn't actually an fseek issue. Glibc and musl do an explicit lseek()
when closing a file if there is unread data in the buffer:

$ cc -o h head.c
$ (strace -o x.log ./h 1; echo .; ./h 2; echo .; cat) < head.c
#include <stdio.h>
.
#include <stdlib.h>

.
int
main(int argc, char* argv[])
{
        char line[BUFSIZ];
        int n;

        if (argc != 2)
                return EXIT_FAILURE;

        n = atoi(argv[1]);
        while (n-- && fgets(line, sizeof line, stdin))
                printf("%s", line);
        return EXIT_SUCCESS;
}
$ tail x.log
munmap(0x7f0f0e89d000, 78789)           = 0
fstat(0, {st_mode=S_IFREG|0600, st_size=258, ...}) = 0
brk(NULL)                               = 0x5564cc789000
brk(0x5564cc7aa000)                     = 0x5564cc7aa000
read(0, "#include <stdio.h>\n#include <std"..., 4096) = 258
fstat(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 2), ...}) = 0
write(1, "#include <stdio.h>\n", 19)    = 19
lseek(0, -239, SEEK_CUR)                = 19
exit_group(0)                           = ?
+++ exited with 0 +++
$

This looks like a useful behaviour to add to the libc close routines.

-RVP


Home | Main Index | Thread Index | Old Index