1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// UNSUPPORTED: no-filesystem
10
11// setrlimit(RLIMIT_FSIZE) seems to only work as intended on Apple platforms
12// REQUIRES: target={{.+}}-apple-{{.+}}
13
14// <fstream>
15
16// Make sure that we properly handle the case where we try to write content to a file
17// but we fail to do so because std::fwrite fails.
18
19#include <cassert>
20#include <csignal>
21#include <cstddef>
22#include <fstream>
23#include <string>
24
25#include "platform_support.h"
26#include "test_macros.h"
27
28#if __has_include(<sys/resource.h>)
29# include <sys/resource.h>
30void limit_file_size_to(std::size_t bytes) {
31 rlimit lim = {.rlim_cur: bytes, .rlim_max: bytes};
32 assert(setrlimit(RLIMIT_FSIZE, &lim) == 0);
33
34 std::signal(SIGXFSZ, handler: [](int) {}); // ignore SIGXFSZ to ensure std::fwrite fails
35}
36#else
37# error No known way to limit the amount of filesystem space available
38#endif
39
40template <class CharT>
41void test() {
42 std::string temp = get_temp_file_name();
43 std::basic_filebuf<CharT> fbuf;
44 assert(fbuf.open(temp, std::ios::out | std::ios::trunc));
45
46 std::size_t const limit = 100000;
47 limit_file_size_to(bytes: limit);
48
49 std::basic_string<CharT> large_block(limit / 10, CharT(42));
50
51 std::streamsize ret;
52 std::size_t bytes_written = 0;
53 while ((ret = fbuf.sputn(large_block.data(), large_block.size())) != 0) {
54 bytes_written += ret;
55
56 // In theory, it's possible for an implementation to allow writing arbitrarily more bytes than
57 // set by setrlimit, but in practice if we bust 100x our limit, something else is wrong with the
58 // test and we'd end up looping forever.
59 assert(bytes_written < 100 * limit);
60 }
61
62 fbuf.close();
63}
64
65int main(int, char**) {
66 test<char>();
67#ifndef TEST_HAS_NO_WIDE_CHARACTERS
68 test<wchar_t>();
69#endif
70
71 return 0;
72}
73

source code of libcxx/test/std/input.output/file.streams/fstreams/filebuf.virtuals/overflow.writefail.pass.cpp