Re: [RFC 00/17] Merge event loop implementations

Pedro Alves
2019-09-27T14:53:46Z

On 9/27/19 3:20 PM, Eli Zaretskii wrote:
>> Cc: gdb-patches@sourceware.org
>> From: Pedro Alves <palves@redhat.com>
>> Date: Fri, 27 Sep 2019 15:05:27 +0100
>>
>> But, given that gdb (unlike gdbserver), has been using "int"
>> for sockets on Windows for a long while, and 64-bit Windows
>> has been a thing for a long while too, I wonder whether in
>> practice Windows just makes sure that SOCKET handles
>> fit in 32-bit integers, exactly to avoid porting headaches...
>
> SOCKET is a 64-bit data type on 64-bit Windows. However, according to
> this:
>
> https://stackoverflow.com/questions/1953639/is-it-safe-to-cast-socket-to-int-under-win64
>
> Microsoft is unlikely to ever populate the high 32 bits with anything
> but zero.
>
> So I'd generally recommend using DWORDPTR or uintptr_t for SOCKETs,
> but I'm guessing we are good using unsigned ints instead, if changing
> that is too much trouble.

Using unsigned ints would be as much trouble as any other type, because
it'd be in conflict with the type that we want to use for Unix -- int.

The main complication is that the code in question works with int file
descriptors, and accepts / passes around all kinds of file descriptors,
including PTYs, sockets, the console's file descriptor on
Windows (fileno(stdin)), etc., all using a single type.

So if we go the typedef way, it'd have to be a type that could
fit all the different types of handles/descriptors on Windows (i.e.,
a 64-bit-wide unsigned integer in practice), and then all code that
checks for handle validity would have to be tweaked to not do
"fd < 0" or "fd == -1" but instead maybe call some callback to validate
the handle. That seems a lot of trouble, and unusual. The gnulib
select route seems more attractive compared to that.

Reading that stackoverflow, I'm convinced that we should
just do what everyone does and cast SOCKET to int like gdb is
already doing, and move on.

Alternatively, if someone feels up to it, we could also borrow
what gnulib's socket replacement does, which is to use these
two macros to convert between a socket and a file descriptor:

#define FD_TO_SOCKET(fd) ((SOCKET) _get_osfhandle ((fd)))
#define SOCKET_TO_FD(fh) (_open_osfhandle ((intptr_t) (fh), O_RDWR | O_BINARY))

_open_osfhandle "Associates a C run-time file descriptor with an existing operating
system file handle.", per:
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/open-osfhandle?view=vs-2019

But then again, might as well use gnulib's socket/select/etc.
instead of redoing it ourselves.

In conclusion, I suggest sweeping the issue under the rug for now
and cast SOCKET to int for this series, like GDB already does.

Actually, gdbserver also does that too -- gdb_socket_cloexec
returns int, and gdbserver/remote-utils.c uses that to open sockets.

So removing gdb_fildes_t is not really making things worse.

Thanks,
Pedro Alves