W3C libwww on Windows NT

Modifications to libwww 3.1 for Windows and Windows/NT support.

History

The Initial work involved in porting libWWWW to Windows/NT involved using the Winsock API, as defined in winsock.h.

Most changes were as expected (e.g. file naming conventions had to be smoothed over, setting correct feature macros to include/exclude various Unix APIs).

The biggest problem arose in the handling of the console in the built-in HTEventLoop function. Unix systems assume that all file descriptors are select()-able, including stdin. This is not true under Win32: the C runtime supports the canonical FILE *, file _descriptors_ (aka C runtime handles, or CRTs), and Win32 file handles (what is returned by the Win32 CreateFile() call). Sockets under Win32 are file handles, for example. However, only sockets can be passed to the select() call. We describe the console workaround later in this note.

The Windows/NT port depends on the following variables

_WINDOWS
defined for Windows/3.x
WIN32
defined for Win32
_WINSOCKAPI_
defined if Winsock compliant with Microsoft extensions defined in Microsoft's winsock.h as the gaurd variable

Building for Windows/NT

LibWWW for Windows/NT is built as a static library using Visual C++ 2.1 running under Windows/NT 3.51beta. To build the library, create a new project, add all .c files, and then remove the HTWAIS.c file. Define _WINDOWS,WIN32, and _DEBUG as part of your project settings. I've only compiled a debugging version, so some of the finer details of compiling under Visual C++ elude me. I haven't (yet) thought about the issues involved in building libwww as a DLL.

Building the linemode browser is equally simple. I have built it as a console application; simply add the library directory as one of the include directories, and include the library and wsock32.lib (32 bit Winsock library) as part of your link command.

Workarounds for NT

New methods to iterate over fd_sets

In Unix, file descriptors are small postive numbers, and usually contrained to be <= 64. Under Win32, sockets are file handles (32 bit integers). One cannot safely interate between 1 and the maximum fd value, since that value is potentially very large. We work around this by creating a separate fd_set which represents all sockets ever registered, and simply iterate through this set to enumerate all sockets registered with the library. The fd_set implemention in Winsock is a counted array; note as well that the maxsock parameter in select() is not used in the Winsock implementation.

sockets aren't file descriptors, and vice versa

The library uses NETREAD() and NETWRITE() macros to hide the underlying system call used to read a socket. However, the linemode browser also can read from a file, given certain options. Whilst read() and write() will work on any file descriptor under Unix, the same is _not_ true for Win32. Hence, a vicious hack: if the fd is <=10, we use read(), else we use recv(). A better solution to this is solicited.

The Console hack

Our first effort was to get the linemode browser running. However, the linemode browser calls the library with the file_descriptor of stdin. This doesn't work under NT: only sockets are select()-able. Hence, we implemented a busy wait: if we call HTEvent_register() with descriptor 0, we assume that its the console, and record this fact. Then, in the event loop, we check to see if the console is ready, and then check to see if any sockets are ready. If the console isn't registered, then we just issue the select() call as written, which will block indefinitely. The NT version of the library offers the following interfaces. In order for this to work, however, the application must implement it's own event loop; and, specifically, the application must also trap the library's registration of sockets for it's own use. In order to do so, the developer must re-implement the functionality of the library's event loop, and re-implement the functions that the library calls to register sockets for its own use.

Here are the OSF/RI, we are re-implementing the HTEvent() module, and removing the HTThread module for the next release of the library. It is our intention that the library call the HTEvent modules and not those currently in the HTThread.c module.

The new API for the HTEvent module will be available soon as a separate document.

Some Cautions in developing for NT and Unix

Before checking source into your local revision control system, make sure that one remove carriage-returns from the source documents! Otherwise, they may be seen as differences.

Set tabs stops in your local editor to 8 spaces, and forbid your editor from coverting tabs to space (in other words, we want actual tabs in the source files).

Testing Results

We have only tested the library using the linemode browser, although we have tested the interface in blocking and non-blocking mode. The Windows GUI interface is only partially implemented, and has _not_ been tested. The new PUT and POST methods have likewise not been tested on NT for this pre-release


Charlie Brooks OSF Research Institute, 11 Cambridge Center, 4th Floor, Cambridge, MA 02142,
(617) 621 8758, (617) 621 8696 (FAX) cbrooks@osf.org