This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Cygwin 64bits gcc produces erroneous constants with the win32 headers.


I originally entered a bug on msys2's bug tracker, but it turns out
they only repackage cygwin packages, and I have verified this is an
issue on cygwin too, so I am now sending that report here.

Original entry:

https://github.com/Alexpux/MSYS2-packages/issues/555



Basically, the 64 bits "gcc-core" and "w32api-headers" cygwin packages
aren't really compatible with each others. As far as I understand,
this isn't an issue already documented here:
https://cygwin.com/faq-nochunks.html#faq.programming.win32-api
.

The 64 bits gcc that gets compiled in has sizeof(long) == 8. This
causes various troubles with the win32 api headers. These troubles
don't exist with the mingw64 compiler which has sizeof(long) == 4.

Here's an example of what I'm talking about. In the winsock API, the
FIONBIO ioctl command constant is computed using sizeof(u_long) (the
relevance of such method isn't discussed here). Using Visual Studio,
or mingw64's gcc, the value of FIONBIO is always 0x8004667e. But using
cygwin's gcc, when producing a 64 bits binary, the value of that
constant becomes 0x8008667e, which is an invalid ioctl command.

Either cygwin's gcc should have sizeof(long) == 4, or the
w32api-headers package should be fixed to replace long references with
something that is 32 bits in the locations that are relevant, such as
the computation of such constants. For that specific problem for
instance, all the lines such as

#define FIONBIO _IOW('f',126,u_long)

should become something like

#define FIONBIO _IOW('f',126,uint32_t)

I have attached a sample code, and its output when compiled using
cygwin 64 bits. The same code compiled with mingw gcc or Visual Studio
will always produces proper results all the time.

Here's the output in cygwin:

nnoble@NNOBLE0-W ~
$ gcc -o test-code test-code.c -lws2_32
nnoble@NNOBLE0-W ~
$ file test-code.exe
test-code.exe: PE32+ executable (console) x86-64, for MS Windows
nnoble@NNOBLE0-W ~
$ ./test-code.exe
Calling WSAIoctl with FIONBIO = 8008667e - sizeof(param1) = 8
WSAIoctl failed with error: -1
Calling WSAIoctl with FIONBIO = 8008667e - sizeof(param2) = 4
WSAIoctl failed with error: -1
Calling WSAIoctl with FIONBIO_PROPER = 8004667e - sizeof(param1) = 8
Success.
Calling WSAIoctl with FIONBIO_PROPER = 8004667e - sizeof(param2) = 4
Success.

Attachment: cygcheck.out
Description: Binary data

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>

#define FIONBIO_PROPER 0x8004667e

int main(int argc, char **argv)  {
    WSADATA wsaData;
    SOCKET ConnectSocket = INVALID_SOCKET;
    int iResult;
    DWORD dResult;
    unsigned long param1 = 1;
    unsigned int param2 = 1;
    int iRet = 0;

    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed with error: %d\n", iResult);
        return 1;
    }

    ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (ConnectSocket == INVALID_SOCKET) {
        printf("socket failed with error: %ld\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    printf("Calling WSAIoctl with FIONBIO = %08x - sizeof(param1) = %d\n", FIONBIO, sizeof(param1));
    iResult = WSAIoctl(ConnectSocket, FIONBIO, &param1, sizeof(param1), NULL, 0, &dResult, NULL, NULL);
    if (iResult != 0) {
        printf("WSAIoctl failed with error: %d\n", iResult);
        iRet = 1;
    } else {
        printf("Success.\n");
    }

    printf("Calling WSAIoctl with FIONBIO = %08x - sizeof(param2) = %d\n", FIONBIO, sizeof(param2));
    iResult = WSAIoctl(ConnectSocket, FIONBIO, &param2, sizeof(param2), NULL, 0, &dResult, NULL, NULL);
    if (iResult != 0) {
        printf("WSAIoctl failed with error: %d\n", iResult);
        iRet = 1;
    } else {
        printf("Success.\n");
    }

    printf("Calling WSAIoctl with FIONBIO_PROPER = %08x - sizeof(param1) = %d\n", FIONBIO_PROPER, sizeof(param1));
    iResult = WSAIoctl(ConnectSocket, FIONBIO_PROPER, &param1, sizeof(param1), NULL, 0, &dResult, NULL, NULL);
    if (iResult != 0) {
        printf("WSAIoctl failed with error: %d\n", iResult);
        iRet = 1;
    } else {
        printf("Success.\n");
    }

    printf("Calling WSAIoctl with FIONBIO_PROPER = %08x - sizeof(param2) = %d\n", FIONBIO_PROPER, sizeof(param2));
    iResult = WSAIoctl(ConnectSocket, FIONBIO_PROPER, &param2, sizeof(param2), NULL, 0, &dResult, NULL, NULL);
    if (iResult != 0) {
        printf("WSAIoctl failed with error: %d\n", iResult);
        iRet = 1;
    } else {
        printf("Success.\n");
    }

    closesocket(ConnectSocket);
    WSACleanup();

    return iRet;
}
--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]