This is sources Bugzilla
Bugzilla Version 2.17.5
Bugzilla Bug 1996
  open_memstream() and seek past end of buffer Last modified: 2006-08-14 22:15
     Query page      Enter new bug
Bug#: 1996   Hardware:   Reporter: Michael Kerrisk <michael.kerrisk@gmail.com>
Host: Target: Build:
Product:     Add CC:
Component:   Version:   CC:
Remove selected CCs
Status: RESOLVED   Priority:  
Resolution: FIXED   Severity:  
Assigned To: Ulrich Drepper <drepper@redhat.com>   Target Milestone:  
Flags: Requestee:
  backport ()
  examined ()
  testsuite ()
Summary:
Keywords:

Attachment Description Type Created Actions
Create a New Attachment (proposed patch, testcase, etc.) View All

Bug 1996 depends on: Show dependency tree
Show dependency graph
Bug 1996 blocks:

Additional Comments:


Leave as RESOLVED FIXED
Reopen bug
Mark bug as VERIFIED

View Bug Activity   |   Format For Printing


Description:   Last confirmed: 0000-00-00 00:00 Opened: 2005-12-08 15:33
The info page for open_memstream() says:

     You can move the stream's file position with `fseek' or `fseeko'
     (*note File Positioning::).  Moving the file position past the end
     of the data already written fills the intervening space with
     zeroes.

However, this is not so.  When the program below is run, the
following output is produced:

    $ ./a.out
    ftell() before = 0
    fseek error: Success
    ftell() after = 0
    ptr=0x804a180  size=3

Either the implementation or the documentation appears to be broken.


#define _GNU_SOURCE
#include <assert.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    FILE *output;
    size_t size;
    char *ptr;
    long l;

    output = open_memstream(&ptr, &size);
    assert(output != NULL);

    printf("ftell() before = %ld\n", ftell(output));
    l = fseek(output, 50, SEEK_END);
    if (l != 0) perror("fseek error");
    printf("ftell() after = %ld\n", ftell(output));
    fprintf(output, "xxx");
    fflush(output);
    printf("ptr=%p  size=%ld\n", ptr, (long) size);
    return 0;
}

------- Additional Comment #1 From Ryan S. Arnold 2006-04-24 22:05 -------
Michael,

Your call:

l = fseek(output, 50, SEEK_END);

is failing with l == -1, but there is no errno being set.  I'm taking a look at
the fseek() function.  I think it is returning from CHECK_FILE() with -1 and no
errno.  This is probably because you're trying to seek to the end of an empty
stream at this point.  I'll investigate more.

------- Additional Comment #2 From Michael Kerrisk 2006-04-24 23:06 -------
Subject: Re:  open_memstream() and seek past end of buffer

Hi Ryan,

> Your call:
> 
> l = fseek(output, 50, SEEK_END);
> 
> is failing with l == -1, but there is no errno being set.  I'm taking a
> look at the fseek() function.  I think it is returning from CHECK_FILE()
> with -1 and no errno.  This is probably because you're trying to seek to
> the end of an empty stream at this point.  I'll investigate more.

I'm not quite sure what you mean by its "my call".  Yes, fseek() is 
failing with errno not set, but the point is that *according to the 
documentation* I should be able to successfully perform move to some point 
past the endd of stream:

     You can move the stream's file position with `fseek' or `fseeko'
     (*note File Positioning::).  Moving the file position past the end
     of the data already written fills the intervening space with
     zeroes.

Cheers,

Michael


------- Additional Comment #3 From Ryan S. Arnold 2006-04-25 21:22 -------
Alright, found the problem.

open_memstream defines _IO_str_seekoff as the function to call when fseek() is
invoked against a stream opened with open_memstream.  In:

libio/strops.c (_IO_str_seekoff)

line 275:

          if (offset < 0 || (_IO_ssize_t) offset > cur_size)
            return EOF;

In your case offset == 50, and cur_size == 0.  Since the open_memstream()
function uses _IO_str_seekoff() and that function doesn't allow seeking beyond
the end of the data already written to the stream then this would indicate that
the documentation is wrong with regard to the current behavior.

A fix for this would be to have open_memstream() provide an overridden fseek
function which allows seeking beyond the end of the stream up to the end of the
buffer.  I'm not sure this is desireable but I don't see why it isn't possible
since the beginning buffer size created by open_memstream is _G_BUFSIZE (8192).

------- Additional Comment #4 From Ulrich Drepper 2006-08-14 22:15 -------
I checked in a patch.

     Query page      Enter new bug
Actions: New | Query | bug # | Reports | Requests   New Account | Log In