Visual C++ 14 no longer export __pioinfo - by ConnectAnonymousUser

Status : 

  By Design<br /><br />
		The product team believes this item works according to its intended design.<br /><br />
		A more detailed explanation for the resolution of this particular item may have been provided in the comments section.

Sign in
to vote
ID 1279133 Comments
Status Closed Workarounds
Type Bug Repros 0
Opened 4/25/2015 10:31:58 PM
Access Restriction Public


msvcrXXX.dll exported __pioinfo but ucrtbase.dll doesn't.
I understand why __pioinfo is no longer exported; it is clearly internal implementation.

However CRuby (a.k.a. MRI; Ruby C implementation) uses __pioinfo.

CRuby needs __pioinfo
* to associate socket and fd: CRuby creates fd with dummy file handle and set socket 
* to implement overlapped I/O for Windows 2000/XP
* to emulate fcntl(2)

If Visual C++ 14 really no longer export __pioinfo, CRuby want crtbase.dll to add and export functions to achieve above usage.

Following are detail of above usage.

= to associate socket and fd

CRuby needs unified handling files, pipes, sockets and so on through file descriptors because of its specification derived from Unix culture.
A socket must be associated with a fd, and a Ruby script handle a socket through such fds.

Therefore CRuby associate fd and socket with __pioinfo. After CRuby accept a socket, it creates dummy file handle with NUL device, associate a new fd with the file handle by _open_osfhandle, and set the socket as operating-system file handle into __pioinfo[fd]->osfhnd.

= to implement overlapped I/O for Windows 2000/XP

CRuby needs a Cancelable I/O because it want to implement an asyncronous I/O. Usually on Windows it uses CancelIoEx function. However it is only supported Windows Vista or later. At that time Microsoft still supported Windows XP and CRuby also want to support Windows XP. Therefore CRuby implements overlapped I/O itself, and it requires __pioinfo[fd]->osfile and ->lock.

= to emulate fcntl(2)

To emulate fcntl(fd, F_DUPFD) CRuby need to get flags of given fd. So CRuby sees __pioinfo[fd]->osfile.
Sign in to post a comment.
Posted by naruse on 1/22/2016 at 3:33 AM
As a note, related ticket of Ruby's bug tracker is
It also has a link to dirty hack of getting the address of __pioinfo.
Posted by Microsoft on 5/12/2015 at 5:37 AM

Yes, this change is by design: In previous versions of the runtime library, many internal implementation details of the stdio and low-level I/O libraries were exposed in public headers. In the Universal CRT (for Visual Studio 2015), we encapsulated most of these implementation details to give us greater freedom to alter them in the future. These implementation details were not documented and user code should not have taken a dependency on them.

We would recommend altering the code in Ruby such that it does not depend on these internal implementation details. Here are some ideas based on your description of the reliance on these internal implementation details and a cursory inspection of the code to which you linked.

For the “associate socket and fd” usage: It is not clear to me why Ruby goes through this complex dance to produce a suitable file descriptor. Why does it not just call _open_osfhandle with the socket, e.g.,

fd = _open_osfhandle((intptr_t)r, O_RDWR | O_BINARY | O_NOINHERIT);

Per the Windows Sockets documentation, it appears that SOCKETs may be used as file handles in this way (, and this does appear to work.

For the “implement overlapped I/O for Windows 2000/XP” usage: In your explanation, it sounds like this was only done because “at that time Microsoft still supported Windows XP.” While we do still support development for Windows XP using Visual Studio 2015, Windows XP is itself out of support. Do you still support Windows XP? If not, we would recommend switching to the Windows overlapped I/O implementation that was introduced in Windows Vista. If you do still need to support Windows XP, is it sufficient to test the properties of the underlying Windows file handle? I’m not sure what part of the code in that file is relevant to this usage. If you could provide a reduced example of what you’re trying to do, we might be able to provide further advice.

For the “emulate fcntl(2)” usage: Looking at the implementation of dupfd in the source file to which you linked, it appears like one alternative would be to duplicate the file handle each time that _open_osfhandle is called, so that when close is called at the end of the function for all but one of the file descriptors, the file itself remains open?

Please feel free to contact me directly via e-mail if you have any further questions.


James McNellis
Visual C++ Libraries
Posted by Microsoft on 4/25/2015 at 11:06 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If you require immediate assistance with this issue, please contact product support at