Search code examples
cwindowslibpq

Closing fd returned from _open_osfhandle without closing underlying handle


I have a program using libpq on windows, and I use _open_osfhandle(PQsocket(cnxn), 0) so that I can call select() on it.

My problem is, libpq is closing the underlying socket in PQfinish() so I get assert failures when calling _close() on the value returned by _open_osfhandle()

Is there a way to close a CRT file descriptor, without also closing the underlying handle?

EDIT

The reason I need this, is because after about 512 connections, _open_osfhandle() fails saying too many open files. Also, I tried _free_osfhnd (I found it in close.cpp when visual studio showed me the source of the assert) and it still failed.


Solution

  • So, Raymond Chen's comment told me to try DuplicateHandle, and this worked.

    Here is where I dupe it:

    HANDLE h_dup_handle = 0;
    SERROR_CHECK(DuplicateHandle(GetCurrentProcess(), PQsocket(A->cnxn),
                 GetCurrentProcess(), &h_dup_handle, 0, TRUE,
                 DUPLICATE_SAME_ACCESS), "DuplicateHandle failed!");
    A->int_windows_pq_handle = _open_osfhandle(h_dup_handle, 0);
    SERROR_CHECK(client->int_windows_pq_handle != -1, "_open_osfhandle failed!")
    

    (SERROR_CHECK is a macro that goes to the error label if the condition is not met)

    Here is where I close it:

    PQfinish(client->cnxn);
    _close(client->int_windows_pq_handle);