View Bug Activity | Format For Printing
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; }
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.
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
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).
I checked in a patch.