[Bug stdio/34006] libio: inconsistent fmemopen_write behavior on last \0

marocketbd at gmail dot com sourceware-bugzilla@sourceware.org
Wed Mar 25 03:47:32 GMT 2026


https://sourceware.org/bugzilla/show_bug.cgi?id=34006

--- Comment #1 from Rocket Ma <marocketbd at gmail dot com> ---
A note from POSIX.1-2024:

> Note that buf will not be null terminated if max_size bytes are written to the memory stream. Applications wanting to guarantee that the buffer will be null terminated need to call fmemopen() with max_size set to one byte smaller than the actual size of buf and set buf[max_size] to a null byte.

Which means for the case of my first comment, glibc should always fill the last
char with X.

I also rewrite a buffered version of test, source code is attached below. The
result is:

seek=5 mode=r  fflush+3= 0( 0) fflush+5= 0( 0)buf[0..9]=abc.......
seek=6 mode=r  fflush+3= 0( 0) fflush+5= 0( 0)buf[0..9]=abc.......
seek=5 mode=r+ fflush+3= 0( 0) fflush+5=-1( 0)buf[0..9]=abc..XXXXX
seek=6 mode=r+ fflush+3= 0( 0) fflush+5=-1(28)buf[0..9]=abc...XXX.
seek=5 mode=w  fflush+3= 0( 0) fflush+5=-1( 0)buf[0..9]=abc..XXXX.
seek=6 mode=w  fflush+3= 0( 0) fflush+5=-1(28)buf[0..9]=abc...XXX.
seek=5 mode=w+ fflush+3= 0( 0) fflush+5=-1( 0)buf[0..9]=.bc..XXXX.
seek=6 mode=w+ fflush+3= 0( 0) fflush+5=-1(28)buf[0..9]=.bc...XXX.
seek=5 mode=a  fflush+3= 0( 0) fflush+5=-1( 0)buf[0..9]=abcXXXXXXX
seek=6 mode=a  fflush+3= 0( 0) fflush+5=-1( 0)buf[0..9]=abcXXXXXXX
seek=5 mode=a+ fflush+3= 0( 0) fflush+5=-1( 0)buf[0..9]=abcXXXXXXX
seek=6 mode=a+ fflush+3= 0( 0) fflush+5=-1( 0)buf[0..9]=abcXXXXXXX

Indeed, in some cases, fflush returned error, but errno is not set, that should
be fixed, too.

---

#include <errno.h>
#include <stdio.h>

static void hexdump(const unsigned char *p, size_t n) {
    for (size_t i = 0; i < n; ++i)
        if (p[i])
            putchar(p[i]);
        else
            putchar('.');
    putchar('\n');
}

static void run_case(long seek_pos, const char *mode) {
    unsigned char buf[11] = "abc";
    FILE *fp = fmemopen(buf, 10, mode);
    fseek(fp, seek_pos, SEEK_SET);

#define COPYME "XXXXXXXX"

    fwrite(COPYME, 1, 3, fp);
    errno = 0;
    int rc = fflush(fp);
    int errno_after_fflush = errno;

    fwrite(COPYME, 1, 5, fp);
    errno = 0;
    int rc2 = fflush(fp);

    printf("seek=%ld mode=%-2s fflush+3=%2d(%2d) fflush+5=%2d(%2d)", seek_pos,
mode, rc,
           errno_after_fflush, rc2, errno);
    printf("buf[0..9]=");
    hexdump(buf, sizeof(buf) - 1);

    fclose(fp);
}

int main(void) {
    run_case(5, "r");
    run_case(6, "r");
    run_case(5, "r+");
    run_case(6, "r+");

    run_case(5, "w");
    run_case(6, "w");
    run_case(5, "w+");
    run_case(6, "w+");

    run_case(5, "a");
    run_case(6, "a");
    run_case(5, "a+");
    run_case(6, "a+");

    return 0;
}

-- 
You are receiving this mail because:
You are on the CC list for the bug.


More information about the Glibc-bugs mailing list