DevelWin32 » History » Revision 11
Revision 10 (gstrauss, 2023-02-24 07:56) → Revision 11/12 (gstrauss, 2023-02-27 08:44)
h1. Building lighttpd Compiling Lighty on Windows win32 h2. lighttpd cygwin lighttpd cygwin is maintained as a set of packages available from cygwin @setup.exe@ and supports nearly all the same features of lighttpd available on unix-like systems. However, extra precautions may need to be taken to protect a _WIN32 system (see below), so you are strongly advised against using lighttpd cygwin in production. h2. lighttpd native _WIN32 lighttpd development prototype for native _WIN32 may be built static or shared (dll) using autotools or CMake with compiler toolchain mingw (cygwin or msys) mingw or using MS Visual Studio. https://github.com/gstrauss/lighttpd1.4/tree/win32-exp This is a prototype and you are strongly advised against using _WIN32 lighttpd native _WIN32 in production. h4. lighttpd --- h2. native _WIN32 limitations win32 (ancient documentation) * not implemented - server.c: no daemonize - server.c: no multiple workers - server.c: no lighttpd -1 one-shot mode - log.c: no syslog option (no Windows Event Log) * _WIN32 accepts both @/@ and <code>\</code> as path separators lighttpd code *has not* been reviewed to normalize _WIN32 <code>\</code> to @/@. (possible security exposure) * _WIN32 environment paths may begin *(WARNING: out-dated documentation)* Starting with volume @C:/@ instead of with @/@. (possible security exposure) lighttpd code *has not* been reviewed to normalize _WIN32 paths. lighttpd code assumes lighty 1.4.11-svn the source compiles on windows. Not all parts are ported, but it works in many places that full path begins with @/@. lighttpd might not work across multiple volumes. general. h3. Requirements * _WIN32 NTFS alternate data streams not rejected (possible security exposure) https://redmine.lighttpd.net/issues/1335 Visual C++ (e.g. "Visual C++ Toolkit":http://msdn.microsoft.com/visualc/vctoolkit2003/ or "Visual C++ 2005 Express":http://msdn.microsoft.com/vstudio/express/visualc/download/) * _WIN32 filesystem functions do not properly handle UTF-8 (ASCII works when UNICODE is not defined; wide-char works with UNICODE) Some UTF-8 to wide-char compat translation funcs provided in fs_win32.[ch], but not comprehensive. unlink(), rmdir(), chdir() not provided, or others ... (move, replace, etc and other use of _WIN32 ...A() funcs might the win32-SDK from the "Platform SDK":http://msdn.microsoft.com/vstudio/express/visualc/usingpsdk (tip: you don't need to be replaced with funcs which convert from UTF-8 to wide-char and use ...W()) the full package) * NTFS fails attempt to rename files atomically if either file is open. lighttpd uses this idiom in file caches (deflate.cache-dir disabled on _WIN32) lighttpd mod_webdav will fail if a PUT "SCons":http://www.scons.org/ (scons 0.96.91 or MOVE is attepted on open an file. Many file operations other than read may fail due to this NTFS limitation. * lighttpd mod_webdav *has not* been ported and *will have* multiple issues, including but not limited to atomic file renames, non-ASCII UTF-8 file support * lighttpd does not attempt to detect setCaseSensitiveInfo dir attribute * ... h4. MS fuglies higher) which requires "Python":http://www.python.org/ * SOCKET is (long long unsigned), not (int) as SCons needs a configfile in POSIX file descriptors. In practice (sample size n=1), SOCKET appears to be < INT_MAX, except for INVALID_SOCKET ((long long unsigned)-1), which casts back to (int)-1. While it does not appear necessary to rewrite all code to use SOCKET instead of int, it would be nice that IFF true, that it be documented by Microsoft. Both the size of the type (64-bit) and the sign (unsigned) is unfriendly to porting code. It is suggested that historically SOCKET was a pointer value cast to (uintptr_t) (good job with type-safety $MS!). In 32-bit, int and pointers are the same size, but not in 64-bit. Perhaps this was changed at some point in $MS evolution, but is not well documented, folder as at least initial assignments are smallish integers in 200's and 300's. $MS is able to distinguish between the SConstruct file. My config.py file descriptors (int) and (SOCKET) since both are supported by SetHandleInformation(), ReadFile(), WriteFile(), so we can conclude that $MS did not propagate that logic elsewhere, but probably could. ((HANDLE)(uint64_t)sockfd); ((HANDLE)_get_osfhandle(fd)) (e.g. file and pipes) looks like this: <pre> prefix='c:/lighttpd-scons/' * SOCKET and file descriptors are not allowed as lowest available integer, so using an array indexed by file descriptors is not a good pattern to apply. VC_TOOLKIT_HOME='c:/Programme/Microsoft Visual C++ Toolkit 2003/' * select() and WSAPoll() work only with SOCKET, not with files or pipes. (see WaitForSingleObject() WaitForMultipleObjects() and related functions) (also WSAEventSelect()+WSAWaitForMultipleEvents()) PSDK_HOME='c:/Programme/Microsoft Platform SDK/' * select() is not a bitmap; client code around select() often needs to be reworked. [1] The macros such as FD_ISSET must be applied to SOCKET, and not to arbitrary integer in range from [0,FD_SETSIZE) https://devblogs.microsoft.com/oldnewthing/20221102-00/?p=107343 https://devblogs.microsoft.com/oldnewthing/20161221-00/?p=94985 # with_mysql='/usr/local/mysql/bin/mysql_config' * filesystem redirection (stdin/stdout/stderr) to sockets is possible, but: - filehandles must be inheritable (default) - sockets must be non-overlapped (not default) - socket() creates sockets with WSA_FLAG_OVERLAPPED - WSASocket() has flag option to omit WSA_FLAG_OVERLAPPED with_pcre='no' * programs generally need SYSTEMROOT defined in the environment to run properly with_openssl='no' * #define WIN32_LEAN_AND_MEAN must be defined before #include <windows.h> or else you may get (undesirable) winsock 1.1 header visibility https://learn.microsoft.com/en-us/windows/win32/winsock/creating-a-basic-winsock-application For some apps, #include <winsock2.h> is sufficient instead of #include <windows.h> Must link with -lws2_32 #ifdef _MSC_VER #pragma comment(lib, "ws2_32.lib") #endif with_gzip='no' * connect() on non-blocking socket errors with WSAGetLastError() WSAWOULDBLOCK, not EINPROGRESS with_bzip2='no' * dup() and dup2() can not be used on SOCKET (see WSADuplicateSocket()) with_memcached='no' * dup2() does not return the newfd; incompatible interface with_sqlite3='no' * stat() on a directory fails if string has trailing @/@ or <code>\</code> with_xml='no' * stat() returns ENOENT instead of ENOTDIR for CGI PATH_INFO, e.g. /real/file.cgi/path/info # default 'no' * stat() fails on //?/c:/... paths build_static='yes' * error codes: WSAGetLastError() for sockets; do not check errno # default 'no' * error codes: GetLastError() (except for sockets), and sometimes errno build_fullstatic='no' * Microsoft NTFS does not allow move/rename file operations on open files. (Attempts # default 'yes' build_dynamic='no' </pre> All the with_* options have to do so result in Permission denied; file already in use.) A typical POSIX idiom of atomic rename fails on NTFS if either old or new file 'no' for now, build_static is open. This breaks in lighttpd in numerous places where a cache is updated and the new file is kept open during the rename, only way that works and then served VC_TOOLKIT_HOME and PSDK_HOME have to be set to the client. Forcing locations of the file to be closed Visual C++ Toolkit and then reopened around the rename introduces a race condition Platform SDK. <pre> $ scons </pre> will build the lighty (lighttpd-semi-static.exe) in what is ultimately sent to the client. (While this race is introduced in mod_deflate cache, mod_webdav and other modules might still suffer/fail from this NTFS limitation.) * UCRT <sys/types.h> unconditionally defines off_t 'build' directory. h3. Problems With a get of /trunk/ as long (4 bytes on _WIN32) if _CRT_DECLARE_NONSTDC_NAMES is defined. Any application or library which supports large files of 11/28/2006, and expects 64-bit off_t needs to take steps to workaround this (e.g. define off_t, _off_t, _OFF_T_DEFINED in advance). using VS2005, I get: <pre> scons: *** An executable should have exactly one target with the suffix: .exe * ... </pre> [1] https://learn.microsoft.com/en-us/windows/win32/winsock/select-and-fd---2 > Select, FD_SET, and FD_XXX Macros > Since sockets are not represented by the UNIX-style, small, non-negative integer, the implementation Deleting that section out of the select function was changed SConscript (it seems to be for building test apps?) gets me a bit farther until: <pre> src\server.c(3) : fatal error C1083: Cannot open include file: 'sys/time.h': No such file or directory </pre> Anyone have any suggestions? As with r1504 /trunk/ it seems that Win32 build is broken: sys/time.h only exists in Windows Sockets. Each set POSIX environment, possibly should be using sys/utime.h under Win32. Local implementation of sockets getopt.h is still represented by the FD_SET structure, but instead of being stored as a bitmask, the set is implemented as an array of sockets. To avoid potential problems, applications must adhere to the use of the FD_XXX macros to set, initialize, clear, and check the FD_SET structures. missing.