简体   繁体   English

检查 open_memstream 的 FILE 操作上的 memory 错误

[英]Check for out of memory error on open_memstream's FILE operation

  1. Does POSIX guarantees the ferror is set on open_memstream's FILE write operations? POSIX 是否保证在 open_memstream 的 FILE 写入操作上设置了 ferror?
  2. How do I check for out of memory condition on FILE operation if the FILE is created with open_memstream?如果 FILE 是使用 open_memstream 创建的,如何检查 FILE 操作上的 memory 条件?

I used to assume that error should be set on the stream if the internal realloc fails and the error condition could be obtained with ferror, but the following test with glibc 2.31 shows it doesn't do so (Linux overcommit_memory is disabled):我曾经假设如果内部重新分配失败并且可以使用 ferror 获得错误条件,则应该在 stream 上设置错误,但是使用 glibc 2.31 进行的以下测试表明它没有这样做(Linux overcommit_memory 已禁用):

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

static char chunk[1024] = {1};

int main(void) {
    size_t sz = 0;
    char *s = NULL;
    FILE *sf = open_memstream(&s, &sz);
    if (!sf) {
        fprintf(stderr, "%d: ERROR open_memstream failed: %s", (int)__LINE__, strerror(errno));
        return -1;
    }

    for (;;) {
        size_t new_n = fwrite(chunk, sizeof chunk, 1, sf);
        if (ferror(sf))
            fprintf(stderr, "%d: ERROR ferror(sf): %s\n", (int)__LINE__, strerror(errno));
        if (new_n == 0)
            break;
    }

    if (fflush(sf))
        fprintf(stderr, "%d: ERROR fflush(sf)\n", (int)__LINE__);
    if (ferror(sf))
        fprintf(stderr, "%d: ERROR ferror(sf)\n", (int)__LINE__);
        
    fprintf(stderr, "%d: writing done %zu\n", (int)__LINE__, sz);
    fclose(sf);
    free(s);
    return 0;
}

user@ws:~$ ./a.out 
30: writing done 4347395995

glibc ticket for the issue: https://sourceware.org/bugzilla/show_bug.cgi?id=26573问题的 glibc 票证: https://sourceware.org/bugzilla/show_bug.cgi?id=26573

Does POSIX guarantees the ferror is set on open_memstream's FILE write operations? POSIX 是否保证在 open_memstream 的 FILE 写入操作上设置了 ferror?

To my suprise, no, I see nothing in open_memstream nor in ferror .令我惊讶的是,不,我在open_memstreamferror中什么都看不到。

Browsing glibc, in glibc/memstream.c it does not set _IO_ERR_SEEN in flags, so ferror will not output.浏览 glibc,在glibc/memstream.c中它没有在标志中设置_IO_ERR_SEEN ,所以ferror不会 output。

How do I check for out of memory condition on FILE operation if the FILE is created with open_memstream?如果 FILE 是使用 open_memstream 创建的,如何检查 FILE 操作上的 memory 条件?

Check if sz got incremented.检查sz是否增加。 Check errno .检查errno

The buffer is only observable after fflush , and缓冲区只能在fflush之后观察到,并且

Upon successful completion, fflush() shall return 0;成功完成后, fflush()将返回 0; otherwise, it shall set the error indicator for the stream, return EOF , and set errno to indicate the error.否则,它应该为 stream 设置错误指示器,返回EOF并设置errno以指示错误。

This imposes a requirement to set the error indicator.这就要求设置错误指示器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM