Re: Using freetds in Windows
Frediano Ziglio <[email protected]>
| Newsgroups | gmane.comp.db.tds.freetds |
|---|---|
| Message-ID | <[email protected]> |
2010/1/12 James K. Lowden <[email protected]>: > Frediano Ziglio wrote: >> Perhaps would be better to translate C >> errors into Windows system errors and use FormatMessage for windows and >> strerror for Unix? > > Winsock errors cannot be formatted with FormatMessage. That's why we have > tds_prwsaerror(). > ?? I execute attached format_message.c and give: NO_ERROR -> The operation completed successfully. WSAEINTR -> A blocking operation was interrupted by a call to WSACancelBlockingCall. WSAEBADF -> The file handle supplied is not valid. WSAEACCES -> An attempt was made to access a socket in a way forbidden by its access permissions. WSAEFAULT -> The system detected an invalid pointer address in attempting to use a pointer argument in a call. ... without any errors in both Windows Xp and Windows 2000. I don't have a NT4 machine and I don't care about too old windows versions. This should work on all Win32/Win64 platforms so at least somebody have windows 16 the code is ok. >> we always use strerror, windows or not. > > It matters more to you than to me. :-) > > In the db-lib code we don't need to support multithreading. I don't know > how to use errno portably in multithreaded code. I would like to believe > that in any environment in which errno is in thread-local storage, > strerror(3) would be thread-safe. > errno is currently quite portable and thread-safe, strerror not, there is a strerror_r to solve the problem. > I encountered a bug today in replacements/strtok_r(). It doesn't treat > consecutive tokens as one, so at the end of the port 1434 response (two > semicolons), it returns a zero-length string instead of NULL. It made me > wish we'd single-threaded the code instead of replacing it with something > that almost works. > I'll fix it. >> I think that a developer >> have to use perl even on windows or manually copy file from distribution >> while users will use distribution which came with proper file. > > Agreed. > >> Why not adding .sln/.vcproj and Nmakefile to distribution ?? > > Laziness. Good idea, though. > >> It's that macro is defined in replacements.h and tds_sysdep_private.h so >> I got a warning about redefinition. I build defncopy as cross compile >> using FreeTDS library (not MS one). > > Understood. It's good you use Mingw and I use VS 2005. If we get it to > compile both ways, we're doing something right. > This raise a coherency question: what should we put into tds_sysdep_private.h and in replacements.h?? The difference between tds_sysdep_private and tds_sysdep_public is clear, tds_sysdep_public have to be distributed in order to compile cklient programs while tds_sysdep_private is used to make internal code portable so it's ok to use in unittests or internal application (like defncopy). replacements.h was added to provide definitions for functions replaced or not available so it define functions/macro to allow the use of undefined functions, even system dependent one. Perhaps tds_sysdep_private should include replacements? No, I think not, replacements it's also used for our small replacements functions definitions so I would suggest this rule: if we have some function defined in replacement library define in replacements.h else define in tds_sysdep includes (mostly tds_sysdep_private). So strcasecmp (which doesn't have function defined in replacement library) should go to tds_sysdep_private. Do you agree? bye freddy77 _______________________________________________ FreeTDS mailing list [email protected] http://lists.ibiblio.org/mailman/listinfo/freetds
format_message.c
(application/octet-stream, 2.4 KB)
#include <windows.h>
#include <stdio.h>
void test(DWORD err, const char *errstr)
{
LPSTR out = NULL;
DWORD res = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, (LPSTR) &out, 0, NULL);
if (!res) {
fprintf(stderr, "Error getting message for %s\n", errstr);
} else {
printf("%s -> %s\n", errstr, out);
LocalFree(out);
}
}
#define T(e) test(e, #e)
int main()
{
T(NO_ERROR);
T(WSAEINTR);
T(WSAEBADF);
T(WSAEACCES);
T(WSAEFAULT);
T(WSAEINVAL);
T(WSAEMFILE);
T(WSAEWOULDBLOCK);
T(WSAEINPROGRESS);
T(WSAEALREADY);
T(WSAENOTSOCK);
T(WSAEDESTADDRREQ);
T(WSAEMSGSIZE);
T(WSAEPROTOTYPE);
T(WSAENOPROTOOPT);
T(WSAEPROTONOSUPPORT);
T(WSAESOCKTNOSUPPORT);
T(WSAEOPNOTSUPP);
T(WSAEPFNOSUPPORT);
T(WSAEAFNOSUPPORT);
T(WSAEADDRINUSE);
T(WSAEADDRNOTAVAIL);
T(WSAENETDOWN);
T(WSAENETUNREACH);
T(WSAENETRESET);
T(WSAECONNABORTED);
T(WSAECONNRESET);
T(WSAENOBUFS);
T(WSAEISCONN);
T(WSAENOTCONN);
T(WSAESHUTDOWN);
T(WSAETOOMANYREFS);
T(WSAETIMEDOUT);
T(WSAECONNREFUSED);
T(WSAELOOP);
T(WSAENAMETOOLONG);
T(WSAEHOSTDOWN);
T(WSAEHOSTUNREACH);
T(WSAENOTEMPTY);
T(WSAEPROCLIM);
T(WSAEUSERS);
T(WSAEDQUOT);
T(WSAESTALE);
T(WSAEREMOTE);
T(WSASYSNOTREADY);
T(WSAVERNOTSUPPORTED);
T(WSANOTINITIALISED);
T(WSAEDISCON);
T(WSAENOMORE);
T(WSAECANCELLED);
T(WSAEINVALIDPROCTABLE);
T(WSAEINVALIDPROVIDER);
T(WSAEPROVIDERFAILEDINIT);
T(WSASYSCALLFAILURE);
T(WSASERVICE_NOT_FOUND);
T(WSATYPE_NOT_FOUND);
T(WSA_E_NO_MORE);
T(WSA_E_CANCELLED);
T(WSAEREFUSED);
T(WSAHOST_NOT_FOUND);
T(WSATRY_AGAIN);
T(WSANO_RECOVERY);
T(WSANO_DATA);
T(WSA_QOS_RECEIVERS);
T(WSA_QOS_SENDERS);
T(WSA_QOS_NO_SENDERS);
T(WSA_QOS_NO_RECEIVERS);
T(WSA_QOS_REQUEST_CONFIRMED);
T(WSA_QOS_ADMISSION_FAILURE);
T(WSA_QOS_POLICY_FAILURE);
T(WSA_QOS_BAD_STYLE);
T(WSA_QOS_BAD_OBJECT);
T(WSA_QOS_TRAFFIC_CTRL_ERROR);
T(WSA_QOS_GENERIC_ERROR);
T(WSA_QOS_ESERVICETYPE);
T(WSA_QOS_EFLOWSPEC);
T(WSA_QOS_EPROVSPECBUF);
T(WSA_QOS_EFILTERSTYLE);
T(WSA_QOS_EFILTERTYPE);
T(WSA_QOS_EFILTERCOUNT);
T(WSA_QOS_EOBJLENGTH);
T(WSA_QOS_EFLOWCOUNT);
T(WSA_QOS_EUNKNOWNPSOBJ);
T(WSA_QOS_EPOLICYOBJ);
T(WSA_QOS_EFLOWDESC);
T(WSA_QOS_EPSFLOWSPEC);
T(WSA_QOS_EPSFILTERSPEC);
T(WSA_QOS_ESDMODEOBJ);
T(WSA_QOS_ESHAPERATEOBJ);
T(WSA_QOS_RESERVED_PETYPE);
return 0;
}