Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add wil::println() - C++23's std::println() but for HANDLEs #492

Open
fredemmott opened this issue Dec 21, 2024 · 4 comments
Open

Add wil::println() - C++23's std::println() but for HANDLEs #492

fredemmott opened this issue Dec 21, 2024 · 4 comments

Comments

@fredemmott
Copy link

e.g (needs C++20):

void println(
  HANDLE handle,
  std::format_string<Args...> format,
  Args&&... args) {
  const auto buffer = std::format(format, std::forward<Args>(args)...) + '\n';
  DWORD bytesWritten = {};
  while (bytesWritten < buffer.size()) {
    const auto remaining = buffer.size() - bytesWritten;
    DWORD bytesWrittenThisBatch {};
    const auto result = WriteFile(
      handle,
      buffer.data() + bytesWritten,
      remaining,
      &bytesWrittenThisBatch,
      nullptr);
    if (!SUCCEEDED(result)) {
      throw std::system_error(result, std::system_category());
    }
    bytesWritten += bytesWrittenThisBatch;
  }
}

Would also probably want a wchar version taking an std::wformat_string

@sylveon
Copy link
Contributor

sylveon commented Dec 21, 2024

Is this required considering you can get a FILE* from a HANDLE and then use it with the normal std::print?

@fredemmott
Copy link
Author

If you're talking about _open_osfhandle():

The _open_osfhandle call transfers ownership of the Win32 file handle to the file descriptor. To close a file opened by using _open_osfhandle, call _close. The underlying OS file handle is also closed by a call to _close. Don't call the Win32 function CloseHandle on the original handle.

This is a pretty significant limitation; is there another way?

@fredemmott
Copy link
Author

I guess that can be used with DuplicateHandle(), but there's unintuitive semantics there - for example, are the write cursors kept in sync?

@sylveon
Copy link
Contributor

sylveon commented Dec 21, 2024

Ah good point wrt ownership.

Another concern was every write allocating a string. The + '\n' in particular concerns me because we might do a full copy of the string just to add that newline. Perhaps we could use format_to with an iterator that did buffering using a stack array? But then it would negate some performance fast paths in std::format. Might be worth benchmarking different solutions before setting on one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants