NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/59197: file descriptor seek -> read -> write causes file pos inconsistency
>Number: 59197
>Category: kern
>Synopsis: file descriptor seek -> read -> write causes file pos inconsistency
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Mar 19 12:45:00 +0000 2025
>Originator: Rett Berg
>Release: NetBSD 10.1
>Organization:
civboot.org
>Environment:
NetBSD rettbsd.lan 10.1 NetBSD 10.1 (GENERIC) #0: Mon Dec 16 13:08:11 UTC 2024 mkrepro%mkrepro.NetBSD.org@localhost:/usr/src/sys/arch/amd64/compile/GENERIC amd64
>Description:
See "how to repeat"
Note that the following equivalent C code does NOT fail. I'm going to try again with FILE objects, which I think is what lua uses
```c
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
int fd;
char buf[16];
void fw(const char* s) {
int len = strlen(s);
errno = 0;
int w = write(fd, s, len);
assert(len == w);
}
char* fr(const int n, const char* expect) {
assert(n == read(fd, buf, n));
buf[n] = 0;
assert(0 == strcmp(expect, buf));
}
void fs(const int n) {
assert(n == lseek(fd, n, SEEK_SET));
}
int main() {
int pos;
printf("Started fd.c\n");
fd = open("fd.c.txt", O_RDWR | O_CREAT | O_TRUNC);
assert(fd > 0);
// pos = lseek(fd, 0, SEEK_CUR);
// assert(0 == pos);
fw("11"); fw("22"); fw("33");
pos = lseek(fd, 0, SEEK_CUR);
assert(6 == pos);
fs(0); fr(2, "11");
fr(2, "22");
fr(2, "33");
fs(0); fr(2, "11");
fw("20");
pos = lseek(fd, 0, SEEK_CUR);
printf("pos=%i\n", pos);
assert(4 == pos);
printf("fd.c Done\n");
close(fd);
}
```
>How-To-Repeat:
-- file descriptor bug reproduction in lua 5.4
local f = io.open('/tmp/fd.txt', 'w+')
print('Test abcdef')
f:write'abcdef' -- len=6
f:seek'set'
assert('abcdef' == f:read(6))
f:seek('set', 1); f:write'ghi' -- replace 'bcd'
assert('ef' == f:read'a')
f:seek('set', 0); assert('aghief' == f:read'a')
f:close()
print('Test repo')
local f = io.open('/tmp/repo.txt', 'w+')
local function fr(...) return assert(f:read(...)) end
local function fw(...) return assert(f:write(...)) end
local function fs(pos) return assert(f:seek('set', pos)) end
fw'11'; fw'22'; fw'33'; assert(6 == f:seek'cur')
fs(0); assert('11' == f:read(2))
assert('22' == f:read(2))
assert('33' == f:read(2))
fs(0); assert('11' == f:read(2))
fw'20';
local p = f:seek'cur'
print('pos', p); assert(4 == p)
f:close()
print'Done'
>Fix:
Home |
Main Index |
Thread Index |
Old Index