-
Notifications
You must be signed in to change notification settings - Fork 553
MinGW: port POSIX socket compatibility layer #2046
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
base: master
Are you sure you want to change the base?
Conversation
note: more socket-related functions will need to have this treatment. I wonder whether it's best |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree we should probably be planning for libcompat
to present the socket.h
API as compat/socket.h
instead of a separate include file for each syscall.
We should group A more difficult question is whether introduction of xfoo() warrants conversion from legacy POSIX foo() to modern C++ API: If every foo() caller is a C++ caller and that caller has to be updated anyway, then it could be the right time to start doing proper memory management and error handling (instead of writing or preserving awkward and duplicated code). That requires a lot more/serious work though. It may also require to get rid of the remaining legacy C callers. |
okay, pending @rousskov review issues and final call on whether to use compat/xsocket.*
filenames.
Windows' accept(2) has the same signature as POSIX', but returns a SOCKET (under the hood, a int *). This confuses error handling code in squid, which uses POSIX return values to detect error values. Implement xaccept() to wrap around it, taking the implementation from mswindows.h and using it on MinGW as well. Error highlighting the issue: ``` TcpAcceptor.cc: In member function 'bool Comm::TcpAcceptor::acceptInto(Comm::ConnectionPointer&)': TcpAcceptor.cc:352:17: error: comparison of unsigned expression in '< 0' is always false [-Werror=type-limits] 352 | if (rawSock < 0) { ```
Co-authored-by: Amos Jeffries <[email protected]>
We are almost done here. There are more methods (WSADuplicateSocket for instance) but I'd look into them separately. The only point of questio for me is ioctl/ioctlsocket . Windows has separate versions for files and sockets, and doesn't support fcntl. But then, in practice, we only use ioctl for sockets. My plan here would be to name the x-function xioctlsocket, to highlight that it's not meant to be used on filedescriptors, and not to have an xioctl at all. @yadij , @rousskov , I'd like advice before committing to a path and then having to change it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What a fundamental effort!
Francesco: The only point of questio for me is ioctl/ioctlsocket . Windows has separate versions for files and sockets, and doesn't support fcntl. But then, in practice, we only use ioctl for sockets. My plan here would be to name the x-function xioctlsocket, to highlight that it's not meant to be used on filedescriptors, and not to have an xioctl at all.
watch_child() may call ioctl() for an open("/dev/tty") descriptor. Does that contradict the above "we only use ioctl for sockets" assertion? Similar concerns may apply to ModDevPoll.cc that uses "/dev/poll".
Win32 API: This ioctlsocket function performs only a subset of functions on a socket when compared to the ioctl function found in Berkeley sockets. The ioctlsocket function has no command parameter equivalent to the FIOASYNC of ioctl, and SIOCATMARK is the only socket-level command that is supported by ioctlsocket.
Can we use xioctl() (instead of xioctlsocket()) everywhere in high-level code? If some callers/use cases can only be supported on Windows via something other than ioctlsocket(), then perhaps our Windows-specific xioctl() implementation can detect those use cases by testing xioctl() parameters and activating special non-ioctlsocket() handling code as needed?
compat/netdb.cc
Outdated
|
||
#include "squid.h" | ||
|
||
#if (_SQUID_WINDOWS_ || _SQUID_MINGW_) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please address the usual condition consistency and "empty line at the end of the file" concerns.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in c21a151
compat/netdb.cc
Outdated
struct hostent * | ||
xgethostbyname(const char *name) | ||
{ | ||
auto result = ::gethostbyname(name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add const
to new variable declarations whenever possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done in c21a151
compat/netdb.h
Outdated
#include <netdb.h> | ||
#endif | ||
|
||
/// Provide POSIX gethostbyname(2) API on MinGW and Visual Studio build environments |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please focus on describing the function (in all environments it is present). The reasons this function was added will be clear from the commit message. For example:
/// Provide POSIX gethostbyname(2) API on MinGW and Visual Studio build environments | |
/// POSIX gethostbyname(3) equivalent |
or simply
/// Provide POSIX gethostbyname(2) API on MinGW and Visual Studio build environments | |
/// gethostbyname(3) equivalent |
Please add or fix other descriptions in a similar way, paying attention to the correct man page section.
compat/netdb.h
Outdated
#if !(_SQUID_WINDOWS_ || _SQUID_MINGW_) | ||
// Windows and MinGW implementations are in compat/netdb.cc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please do not place a comment inside the if
statement that is false for that comment context:
#if !(_SQUID_WINDOWS_ || _SQUID_MINGW_) | |
// Windows and MinGW implementations are in compat/netdb.cc | |
// Windows and MinGW implementations are in compat/netdb.cc | |
#if !(_SQUID_WINDOWS_ || _SQUID_MINGW_) |
or
#if !(_SQUID_WINDOWS_ || _SQUID_MINGW_) | |
// Windows and MinGW implementations are in compat/netdb.cc | |
#if _SQUID_WINDOWS_ || _SQUID_MINGW_ | |
// Windows and MinGW implementations are in compat/netdb.cc | |
#else |
or simply remove this comment -- it is trivial to find those implementations, and we do not have to document the default "implementations are in foo.cc" case anyway!
#if !(_SQUID_WINDOWS_ || _SQUID_MINGW_) | |
// Windows and MinGW implementations are in compat/netdb.cc | |
#if !(_SQUID_WINDOWS_ || _SQUID_MINGW_) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removing the comment
compat/netdb.h
Outdated
return gethostbyname(name); | ||
} | ||
|
||
inline struct servent * | ||
xgetservbyname(const char *name, const char *proto) | ||
{ | ||
return ::getservbyname(name, proto); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please keep these trivial/forwarding implementations consistent. For example, either all of them should use ::
prefix when calling the primary function or none (by default). The "none" option feels better to me because that is how most similar functions are normally called in Squid code and because these are C (rather than C++) functions, but I may be missing some good reasons to use the global namespace prefix.
winsock's socket-related functions are very similar
but not identical to the POSIX standard.
Make the mswindows compatibility layer
available to MinGW, and modernize it.
Implement portable wrappers around
socket-related calls, named x, and
use them in all callsites.
Error highlighting the issue: