Skip to content

Commit 79919c0

Browse files
authored
fix(io): correct write_all_nullptr_case and prevent FD leak in POSIX pipe setup (#1201)
- freestanding/io_buffer/output.h: fix write_all_nullptr_case to dispatch to scatter_write_all(_bytes)_decay on the output stream (optstm), and keep buffer_curr consistent. - hosted/platforms/posix.h: avoid FD leaks in the POSIX pipe constructor by wrapping FDs with posix_file_factory and setting FD_CLOEXEC; transfer ownership explicitly and keep a single assignment point. No API changes. Success paths unchanged. Rebase-only history preserved.
1 parent 77a05a2 commit 79919c0

File tree

2 files changed

+35
-8
lines changed
  • include

2 files changed

+35
-8
lines changed

include/fast_io_freestanding_impl/io_buffer/output.h

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,30 @@ inline constexpr char_type const *write_some_overflow_impl(optstmtype optstm,
122122
}
123123

124124
template <::std::integral char_type, typename optstmtype>
125-
inline constexpr void write_all_nullptr_case(basic_io_buffer_pointers<char_type> &__restrict pointers,
125+
inline constexpr void write_all_nullptr_case(optstmtype optstm, basic_io_buffer_pointers<char_type> &__restrict pointers,
126126
char_type const *first, char_type const *last)
127127
{
128-
basic_io_scatter_t<char_type> const scatters[2]{
129-
{(pointers.buffer_begin ? pointers.buffer_begin : first),
130-
static_cast<::std::size_t>(pointers.buffer_curr - pointers.buffer_begin)},
131-
{first, static_cast<::std::size_t>(last - first)}};
132-
::fast_io::operations::decay::scatter_write_all_decay(pointers, scatters, 2);
128+
if constexpr (::fast_io::operations::decay::defines::has_any_of_write_bytes_operations<optstmtype>)
129+
{
130+
io_scatter_t const scatters[2]{
131+
{reinterpret_cast<::std::byte const *>(pointers.buffer_begin ? pointers.buffer_begin : first),
132+
static_cast<::std::size_t>(pointers.buffer_begin
133+
? (reinterpret_cast<::std::byte const *>(pointers.buffer_curr) -
134+
reinterpret_cast<::std::byte const *>(pointers.buffer_begin))
135+
: 0u)},
136+
{reinterpret_cast<::std::byte const *>(first),
137+
static_cast<::std::size_t>(reinterpret_cast<::std::byte const *>(last) -
138+
reinterpret_cast<::std::byte const *>(first))}};
139+
::fast_io::operations::decay::scatter_write_all_bytes_decay(optstm, scatters, 2);
140+
}
141+
else
142+
{
143+
basic_io_scatter_t<char_type> const scatters[2]{
144+
{(pointers.buffer_begin ? pointers.buffer_begin : first),
145+
static_cast<::std::size_t>(pointers.buffer_begin ? (pointers.buffer_curr - pointers.buffer_begin) : 0u)},
146+
{first, static_cast<::std::size_t>(last - first)}};
147+
::fast_io::operations::decay::scatter_write_all_decay(optstm, scatters, 2);
148+
}
133149
pointers.buffer_curr = pointers.buffer_begin;
134150
}
135151

include/fast_io_hosted/platforms/posix.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1415,14 +1415,25 @@ class basic_posix_family_pipe
14151415
int a2[2]{-1, -1};
14161416
#if (defined(_WIN32) && !defined(__WINE__) && !defined(__BIONIC__)) && !defined(__CYGWIN__)
14171417
if (noexcept_call(::_pipe, a2, 131072u, _O_BINARY) == -1)
1418+
throw_posix_error();
14181419
#elif defined(__linux__)
14191420
if (noexcept_call(::pipe2, a2, O_CLOEXEC) == -1)
1421+
throw_posix_error();
14201422
#elif (defined(__MSDOS__) || defined(__DJGPP__)) || defined(__NEWLIB__)
14211423
if (noexcept_call(::pipe, a2) == -1)
1424+
throw_posix_error();
14221425
#else
1423-
if (noexcept_call(::pipe, a2) == -1 || ::fast_io::details::sys_fcntl(a2[0], F_SETFD, FD_CLOEXEC) == -1 || ::fast_io::details::sys_fcntl(a2[1], F_SETFD, FD_CLOEXEC) == -1)
1426+
{
1427+
if (noexcept_call(::pipe, a2) == -1)
1428+
throw_posix_error();
1429+
::fast_io::posix_file_factory fd0(a2[0]);
1430+
::fast_io::posix_file_factory fd1(a2[1]);
1431+
::fast_io::details::sys_fcntl(fd0.fd, F_SETFD, FD_CLOEXEC);
1432+
::fast_io::details::sys_fcntl(fd1.fd, F_SETFD, FD_CLOEXEC);
1433+
fd0.fd = -1;
1434+
fd1.fd = -1;
1435+
}
14241436
#endif
1425-
throw_posix_error();
14261437
pipes->fd = *a2;
14271438
pipes[1].fd = a2[1];
14281439
#endif

0 commit comments

Comments
 (0)