Bug 152485 - [patch] seek offset for /dev/null(4) and /dev/zero(4) not reported correctly
Summary: [patch] seek offset for /dev/null(4) and /dev/zero(4) not reported correctly
Status: Open
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: unspecified
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-bugs mailing list
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-11-22 16:10 UTC by Salvatore Sanfilippo
Modified: 2018-05-21 06:48 UTC (History)
0 users

See Also:


Attachments
null.c.diff (889 bytes, patch)
2011-02-24 00:37 UTC, Alexander Best
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Salvatore Sanfilippo 2010-11-22 16:10:13 UTC
The bug was discovered as a result of a bug in Redis data base Virtual Memory implementation when running on FreeBSD.  Opening /dev/null using the libc standard I/O functions and writing against it more than 4096 bytes (one memory page) will result in the seek reported by ftell() to be modulo 4096 (that is, an incorrect value).

Even if /dev/null is not a standard file it should behave correctly and should be able to retain the current seek for the open file in a reliable way. I can't cite standard but I've the feeling the current behavior is not ok, and it's worth fixing even just because other *BSD kernels and Linux will instead behave in the obvious least-surprising way.

Fix: 

The /dev/null implementation in FreeBSD appears to be optimized for speed, it allocates a single page of memory and reads from it, writes are completely discarded. Apparently there is no handling of the offset. But since I've almost zero clues about the FreeBSD char device API I don't know how a correct implementation should look like.
How-To-Repeat: #include <stdio.h>

int main(argc, argv) {

    FILE *fp = fopen("/dev/null","w+");
    rewind(fp);
    
    int i, len;
    for (i=1;i<80000;i++) {
        fwrite("t", 1, 1, fp);
        len = ftello(fp);
        if (len != i) {
            printf("Fail on pos: %d, expected to be %d\n", len, i);
            return 1;
        }
    }
    printf("Pos is: %d\n", len);
    fclose(fp);
    return 0;
}
Comment 1 Alexander Best freebsd_committer 2010-12-15 16:17:41 UTC
the null(4) manual page states that the length of the null device is always
zero, so there's no need to seek into the file really.

however you might want to post a mail to freebsd-hackers@, if you think this
should be changed. maybe some developers share your point of view.

cheers.
alex

-- 
a13x
Comment 2 Alexander Best freebsd_committer 2011-02-24 00:37:54 UTC
does this patch solve the issue for you?

cheers.
alex

-- 
a13x
Comment 3 Alexander Best freebsd_committer 2011-11-16 16:24:40 UTC
Responsible Changed
From-To: freebsd-bugs->arundel

Assign to me. Although i don't have commit rights for "src", i'm working on this 
issue atm.
Comment 4 Alexander Best freebsd_committer 2014-06-02 11:09:46 UTC
Reset assignee -- not working on these PRs atm.
Comment 5 Eitan Adler freebsd_committer freebsd_triage 2018-05-20 23:52:35 UTC
For bugs matching the following conditions:
- Status == In Progress
- Assignee == "bugs@FreeBSD.org"
- Last Modified Year <= 2017

Do
- Set Status to "Open"
Comment 6 Andriy Gapon freebsd_committer 2018-05-21 06:48:59 UTC
Is this still an issue?