From nobody@FreeBSD.org  Mon Nov 22 16:06:41 2010
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 1FA75106567A
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 22 Nov 2010 16:06:41 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from red.freebsd.org (unknown [IPv6:2001:4f8:fff6::22])
	by mx1.freebsd.org (Postfix) with ESMTP id 0ECB98FC15
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 22 Nov 2010 16:06:41 +0000 (UTC)
Received: from red.freebsd.org (localhost [127.0.0.1])
	by red.freebsd.org (8.14.4/8.14.4) with ESMTP id oAMG6e2Z073533
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 22 Nov 2010 16:06:40 GMT
	(envelope-from nobody@red.freebsd.org)
Received: (from nobody@localhost)
	by red.freebsd.org (8.14.4/8.14.4/Submit) id oAMG6ejA073532;
	Mon, 22 Nov 2010 16:06:40 GMT
	(envelope-from nobody)
Message-Id: <201011221606.oAMG6ejA073532@red.freebsd.org>
Date: Mon, 22 Nov 2010 16:06:40 GMT
From: Salvatore Sanfilippo <antirez@gmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: /dev/null seek offset is not reported correctly
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         152485
>Category:       kern
>Synopsis:       [patch] seek offset for /dev/null(4) and /dev/zero(4) not reported correctly
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    arundel
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Nov 22 16:10:13 UTC 2010
>Closed-Date:    
>Last-Modified:  Mon Nov 21 21:51:34 UTC 2011
>Originator:     Salvatore Sanfilippo
>Release:        FreeBSD 8
>Organization:
VMware
>Environment:
unfortunately I don't have access to the system where the bug was reported / verified
>Description:
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.
>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;
}

>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.

>Release-Note:
>Audit-Trail:

From: Alexander Best <arundel@freebsd.org>
To: bug-followup@freebsd.org
Cc:  
Subject: Re: misc/152485: /dev/null seek offset is not reported correctly
Date: Wed, 15 Dec 2010 16:17:41 +0000

 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

From: Alexander Best <arundel@freebsd.org>
To: bug-followup@freebsd.org
Cc:  
Subject: Re: misc/152485: null(4)/zero(4): /dev/null seek offset is not reported correctly
Date: Thu, 24 Feb 2011 00:37:54 +0000

 --tThc/1wpZn/ma/RB
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 does this patch solve the issue for you?
 
 cheers.
 alex
 
 -- 
 a13x
 
 --tThc/1wpZn/ma/RB
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: attachment; filename="null.c.diff"
 
 diff --git a/sys/dev/null/null.c b/sys/dev/null/null.c
 index 3005c19..a83be6f 100644
 --- a/sys/dev/null/null.c
 +++ b/sys/dev/null/null.c
 @@ -47,11 +47,12 @@ static struct cdev *zero_dev;
  
  static d_write_t null_write;
  static d_ioctl_t null_ioctl;
 +static d_read_t null_read;
  static d_read_t zero_read;
  
  static struct cdevsw null_cdevsw = {
  	.d_version =	D_VERSION,
 -	.d_read =	(d_read_t *)nullop,
 +	.d_read =	null_read,
  	.d_write =	null_write,
  	.d_ioctl =	null_ioctl,
  	.d_name =	"null",
 @@ -71,6 +72,19 @@ static void *zbuf;
  static int
  null_write(struct cdev *dev __unused, struct uio *uio, int flags __unused)
  {
 +
 +	uio->uio_offset += uio->uio_resid;
 +	uio->uio_resid = 0;
 +
 +	return (0);
 +}
 +
 +/* ARGSUSED */
 +static int
 +null_read(struct cdev *dev __unused, struct uio *uio, int flags __unused)
 +{
 +
 +	uio->uio_offset += uio->uio_resid;
  	uio->uio_resid = 0;
  
  	return (0);
 
 --tThc/1wpZn/ma/RB--
Responsible-Changed-From-To: freebsd-bugs->arundel 
Responsible-Changed-By: arundel 
Responsible-Changed-When: Wed Nov 16 16:24:40 UTC 2011 
Responsible-Changed-Why:  
Assign to me. Although i don't have commit rights for "src", i'm working on this 
issue atm. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=152485 
>Unformatted:
