Simon Josefsson wrote:
This may have been discussed before, but I don't recall a solution, so
maybe a new report will help.
Yes, in the meantime we all had time to think about it.
i586-mingw32msvc-gcc -g -O2 -o test-getdelim.exe test-getdelim.o
../gllib/libgnu.a
../gllib/libgnu.a(close.o): In function `_gl_close_fd_maybe_socket':
/home/jas/src/gnulib/m/gllib/close.c:39: undefined reference to
`_wsaenumnetworkeve...@12'
/home/jas/src/gnulib/m/gllib/close.c:46: undefined reference to
`_closesoc...@4'
../gllib/libgnu.a(close.o): In function `set_winsock_errno':
/home/jas/src/gnulib/m/gllib/w32sock.h:34: undefined reference to
`_wsagetlaster...@0'
/home/jas/src/gnulib/m/gllib/w32sock.h:35: undefined reference to
`_wsasetlaster...@4'
The logic behind it is correct: some functions in the package open sockets,
and test-getdelim calls fclose(), which calls close(), which - given the unknown
origin of the file descriptor - needs to call WSAEnumNetworkEvents(), which
requires -lws2_32.
Some ideas:
1) Should the sockets.m4 module unconditionally add LIBSOCKET to LDADD?
2) Should the gnulib-tool generated Makefile.am add LIBSOCKET to LDADD?
No, LDADD has an effect on all executables. I don't want to link all my
programs against -lws2_32 just because one of them uses sockets.
No, I don't want to add LIBSOCKET to the link dependencies of the 'close'
and 'fclose' either. It would also have the effect that all or nearly my
programs would link against -lws2_32.
Dynamic loading of ws2_32,dll is not the solution either; it would still
have the effect of loading an extra library in programs that don't need it.
Is there any other options?
I propose to move the sockets related part of close() into the 'sockets'
module, and connect the close() code with the sockets related code at runtime
rather than at compile time. Like this (tested on mingw).
This uses the hook design pattern. It would be possible to optimize it,
knowing that at most one hook will be installed, but there's not much
point in doing so.
2009-03-20 Bruno Haible br...@clisp.org
Remove dependency from 'close' module to -lws2_32 on native Windows.
* lib/close-hook.h: New file.
* lib/close-hook.c: New file.
* lib/close.c: Include close-hook.h. Don't include sys/socket.h,
w32sock.h.
(_gl_close_fd_maybe_socket): Remove function.
(rpl_close): Invoke execute_all_close_hooks instead of
_gl_close_fd_maybe_socket.
* lib/sockets.c: Include close-hook.h, w32sock.h.
(close_fd_maybe_socket): New function, essentially from lib/close.c.
(close_sockets_hook): New variable.
(gl_sockets_startup): Register close_fd_maybe_socket as a hook.
(gl_sockets_cleanup): Unregister it.
* lib/unistd.in.h (HAVE__GL_CLOSE_FD_MAYBE_SOCKET): Remove macro.
* m4/close.m4 (gl_REPLACE_CLOSE): Undo 2009-02-05 change.
* modules/close-hook: New file.
* modules/close (Files): Remove lib/w32sock.h.
(Depends-on): Add close-hook.
(Link): Remove section.
* modules/sockets (Files): Add lib/w32sock.h.
(Depends-on): Add close-hook.
* modules/sys_socket (configure.ac): Remove gl_MODULE_INDICATOR
invocation.
* NEWS: Mention that LIB_CLOSE is gone.
== lib/close-hook.h ==
/* Hook for making the close() function extensible.
Copyright (C) 2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see http://www.gnu.org/licenses/. */
#ifndef CLOSE_HOOK_H
#define CLOSE_HOOK_H
#ifdef __cplusplus
extern C {
#endif
/* Currently, this entire code is only needed for the handling of sockets
on native Windows platforms. */
#if WINDOWS_SOCKETS
/* An element of the list of close hooks.
The fields of this structure are considered private. */
struct close_hook
{
/* Doubly linked list. */
struct close_hook *private_next;
struct close_hook *private_prev;
/* Function that treats the types of FD that it knows about and calls
execute_close_hooks (FD, REMAINING_LIST) as a fallback. */
int (*private_fn) (int fd, const struct close_hook *remaining_list);
};
/* This type of function closes FD, applying special knowledge for the FD
types it knows about, and calls execute_close_hooks (FD, REMAINING_LIST)
for the other