|
10 | 10 | #include <cstdlib> // std::exit |
11 | 11 | #include <cstring> |
12 | 12 | #include <memory> |
| 13 | +#include <thread> |
13 | 14 |
|
14 | 15 | #include "gtest-extra.h" |
15 | 16 | #include "util.h" |
@@ -513,4 +514,49 @@ TEST(file_test, fdopen) { |
513 | 514 | int read_fd = pipe.read_end.descriptor(); |
514 | 515 | EXPECT_EQ(read_fd, FMT_POSIX(fileno(pipe.read_end.fdopen("r").get()))); |
515 | 516 | } |
| 517 | + |
| 518 | +// Windows CRT implements _IOLBF incorrectly (full buffering). |
| 519 | +# ifndef _WIN32 |
| 520 | +TEST(file_test, line_buffering) { |
| 521 | + auto pipe = fmt::pipe(); |
| 522 | + |
| 523 | + int write_fd = pipe.write_end.descriptor(); |
| 524 | + auto write_end = pipe.write_end.fdopen("w"); |
| 525 | + setvbuf(write_end.get(), nullptr, _IOLBF, 4096); |
| 526 | + write_end.print("42\n"); |
| 527 | + close(write_fd); |
| 528 | + try { |
| 529 | + write_end.close(); |
| 530 | + } catch (const std::system_error&) { |
| 531 | + } |
| 532 | + |
| 533 | + auto read_end = pipe.read_end.fdopen("r"); |
| 534 | + std::thread reader([&]() { |
| 535 | + int n = 0; |
| 536 | + int result = fscanf(read_end.get(), "%d", &n); |
| 537 | + (void)result; |
| 538 | + EXPECT_EQ(n, 42); |
| 539 | + }); |
| 540 | + |
| 541 | + reader.join(); |
| 542 | +} |
| 543 | +# endif // _WIN32 |
| 544 | + |
| 545 | +TEST(file_test, buffer_boundary) { |
| 546 | + auto pipe = fmt::pipe(); |
| 547 | + |
| 548 | + auto write_end = pipe.write_end.fdopen("w"); |
| 549 | + setvbuf(write_end.get(), nullptr, _IOFBF, 4096); |
| 550 | + for (int i = 3; i < 4094; i++) |
| 551 | + write_end.print("{}", (i % 73) != 0 ? 'x' : '\n'); |
| 552 | + write_end.print("{} {}", 1234, 567); |
| 553 | + write_end.close(); |
| 554 | + |
| 555 | + auto read_end = pipe.read_end.fdopen("r"); |
| 556 | + char buf[4091] = {}; |
| 557 | + size_t n = fread(buf, 1, sizeof(buf), read_end.get()); |
| 558 | + EXPECT_EQ(n, sizeof(buf)); |
| 559 | + EXPECT_STREQ(fgets(buf, sizeof(buf), read_end.get()), "1234 567"); |
| 560 | +} |
| 561 | + |
516 | 562 | #endif // FMT_USE_FCNTL |
0 commit comments