February 21st, 2018

How can I call freopen but open the file with shared access instead of exclusive access?

A customer wants to redirect their program’s stdout to a file. They followed the sample code which basically boils down to the line

    FILE* stream = freopen("output.txt", "w", stdout);

or its security-enhanced alternate version:

    errno_t err = freopen_s(&stream, "output.txt", "w", stdout);

The customer reported that this worked exactly as exepcted, but the output file is opened for exclusive access. They want another process to be able to read from the output file while the original process is writing to it, but the exclusive access prevents that.

The Microsoft-specific function _fsopen lets you specify a custom sharing mode, but there is no corresponding _fsreopen function that augments the freopen function with a sharing mode.

Is there anything the customer can do?

The C/C++ runtime library folks suggested using _dup2 to remap the file descriptor. Something like this:

#include <fcntl.h>
#include <io.h>
#include <stdio.h>
#include <windows.h>

// All error checking omitted for clarity
int main()
{
  // Open with desired sharing mode
  HANDLE h = CreateFileW(L"output.txt", GENERIC_WRITE, FILE_SHARE_READ,
                         nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
                         nullptr);

  // Convert to a file descriptor
  int fd = _open_osfhandle(reinterpret_cast<intptr_t>(h), _O_WRONLY);


  // Remap stdout's file descriptor to be a copy of the one we just created
  _dup2(fd, _fileno(stdout));

  // Don't need our file descriptor any more
  _close(fd);


  printf("Hello, world!\n");

  return 0;
}

The customer confirmed that this does exactly what they needed.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

0 comments

Discussion are closed.