[freetds] Using freetds in Windows

James K. Lowden jklowden at freetds.org
Sat Jan 9 12:07:29 EST 2010

> Andrew H. Wakefield wrote:
> jkl said:
> > The primary problem is that Windows sockets only vaguely resemble the
> > standard sockets they're based on.  They don't set errno; they require
> > a call to WSAGetLastError().  That returns a number, sure enough, but
> > not one you can translate with strerror(3) or perror(3) or in fact any
> > Win32 function. I wrote tds_prwsaerror() just for that purpose.  
> Thanks for the reply. I'm not sure I really followed your explanation --
> but that is a reflection of my newness to freetds, no doubt. :)

Let's try again.  :-)

On a bog-standard Unix system, connect(2) returns an integer: 0 if
successful, else -1.  If the latter, it sets the global variable errno to
some value.  To get a textual desription of that value, you pass it to
strerror(3).  In src/tds/net.c, that looks something like this:

	retval = connect(tds->s, (struct sockaddr *) &sin, sizeof(sin));
	if (retval == 0) {
		tdsdump_log(TDS_DBG_INFO2, "connection established\n");
	} else {
		tds->oserr = sock_errno;
			"tds_open_socket: connect(2) returned\"%s\"\n",

On Windows, if connect(2) returns zero, you're connected and everyone's
happy.  But if not, passing the value returned to strerror(3) results in
"Unknown error", unhelpful to say the least.  Worse, the Win32 API has no
equivalent function, so printing a useful error message is an
every-man-for-himself effort.[1]  

I changed the code such that when compiled for Windows strerror() is
defined to call another function that produces a useful message.  It's not
a complete answer because (among other reasons) the db-lib error handler
won't get the correct error string.  But at least the TDSDUMP log will
accurately describe what happened.  


[1] Until now.  tds_prwsaerror() is LPGL licensed. 

More information about the FreeTDS mailing list