Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WSAStartup issue on Windows #136

Closed
Hoernchen opened this issue Jan 4, 2017 · 14 comments
Closed

WSAStartup issue on Windows #136

Hoernchen opened this issue Jan 4, 2017 · 14 comments
Labels

Comments

@Hoernchen
Copy link

Building using the mingw script produces a version that does not work on Windows:

E:\projects\wg2>wget2.exe http://www.google.com
�[31mFailed to resolve www.google.de:80 (Either the application has not called WSAStartup, or WSAStartup failed. )

@rockdaboot
Copy link
Owner

@gvanem Didn't you send us a WSAStartup patch !? Sorry, I was sure we had that applied, but can't find it any more. Could you resend it to me ?

@gvanem
Copy link
Contributor

gvanem commented Jan 5, 2017

Ok, here is what I sent you in an email:

--- a/src/wget.c 2016-11-08 19:54:27
+++ b/src/wget.c 2016-11-08 20:25:53
@@ -135,6 +135,37 @@
 int
        nthreads;

+#if defined(_WIN32)
+static void
+ws_cleanup (void)
+{
+  WSACleanup ();
+}
+
+/* Perform Windows specific initialization.  */
+static void
+ws_startup (void)
+{
+  WSADATA data;
+  WORD requested = MAKEWORD (1, 1);
+  int err = WSAStartup (requested, &data);
+  if (err != 0)
+    {
+      fprintf (stderr, _("wget: Couldn't find usable socket driver.\n"));
+      exit (1);
+    }
+
+  if (data.wVersion < requested)
+    {
+      fprintf (stderr, _("wget: Couldn't find usable socket driver.\n"));
+      WSACleanup ();
+      exit (1);
+    }
+
+  atexit (ws_cleanup);
+}
+#endif
+
 void set_exit_status(int status)
 {
        // use Wget exit status scheme:
@@ -857,11 +888,12 @@
        textdomain("wget");
 #endif

-#if defined(_WIN32) || defined(_WIN64)
+#if defined(_WIN32)
        // not sure if this is needed for Windows
        // signal(SIGPIPE, SIG_IGN);
        signal(SIGTERM, nop);
        signal(SIGINT, nop);
+       ws_startup();
 #else
        // need to set some signals
        struct sigaction sig_action;

This is almost an exact copy & paste from Wget.
Note the removal of #if defined(_WIN32) || defined(_WIN64). For Win64, _WIN32 is also defined.

@rockdaboot
Copy link
Owner

@gvanem Thx, just found a gnulib module doing that. I integrated the socket startup/cleanup function deeper within the library, so that the examples benefit as well.

After reading https://msdn.microsoft.com/en-us/library/windows/desktop/ms742213%28v=vs.85%29.aspx, I decided to use socket version 2.2. Any objections ?

Could you test the latest commit and report back, please !?

@gvanem
Copy link
Contributor

gvanem commented Jan 5, 2017

Doesn't work; WSAStartup() isn't called since wget_global_init() isn't called AFAICS. At least not in a src/*.c file. But in examples/*.c though 😸 .

I just added a wget_global_init(NULL) in main() (is that syntax OK?). This works better, but still some problems somewhere with mixing GNUlib fd-handles with Winsock-handles.

@rockdaboot
Copy link
Owner

Init NULL is OK, i'll fix wget.c when back from lunch. Do you know which network functions need handles and which need fds ?

@gvanem
Copy link
Contributor

gvanem commented Jan 5, 2017

I suspect there is some problem with GnuLib's shimming of poll(). Would be nice if Wget2 had an option (in $WGET2) to use select(). That just works. The speed gain of using poll() is AFAICS negligible (comparing with nmap --nsock-engine=poll vs. nmap --nsock-engine=select).

@rockdaboot
Copy link
Owner

Regarding gnulib docs, mingw poll() should be ok: https://www.gnu.org/software/gnulib/manual/html_node/poll.html
If not, we should investigate and open a bug against gnulib.
AFAIR, there weren't any problems when cross-compiling on Linux (MinGW) and executing wget2 with wine. I'll try again, but without a reproducer, I won't do anything.

@rockdaboot
Copy link
Owner

@gvanem Found a problem in gnulib/poll.c with MinGW - likely the same problem that you have.

Before make, change lib/poll.c. In windows_compute_revents_socket(), before

      if (r > 0 || error == WSAENOTCONN)
        happened |= (POLLIN | POLLRDNORM) & sought;

insert

if (r==-1 && error==0)
  r=1;

Not sure why, but recv() returns -1 (with error==0) when the socket is ready to read.
The above change let wget2 download correctly.
Basically the recv with MSG_PEEK is useless ... but why ? Maybe because the socket/handle is still non-blocking ? Do you have any idea ?

@gvanem
Copy link
Contributor

gvanem commented Jan 5, 2017

The above change let wget2 download correctly.

It works sometimes. Other times I get a crash in rpl_select(). I'm using WSAPoll() until this is fixed.
But there are so many other issues with Wget2 on Windows; like ANSI-sequences for colours, PThreads etc.

@rockdaboot
Copy link
Owner

Well, wget2 is documented to be POSIX + C99. That excludes Windows ATM. But color seqs should be easy... You are invited to provide patches, else there currently is no Win developer who does.

@rockdaboot
Copy link
Owner

BTW, the gnulib poll emulation for Win looks messy. If there is a WSAPoll, that should be used. But again, only a Win dev could make that.

@gvanem
Copy link
Contributor

gvanem commented Jan 5, 2017

Some of my hacks is in libwget/mswindows.* at http://www.watt-32.net/misc/wget2-win-hacks.zip.
This uses WSAPoll(), implements a simple trace-macro and an ANSI decoder. not thread safe.

@rockdaboot
Copy link
Owner

wine doesn't know WSAPoll, again I can't test...

@rockdaboot
Copy link
Owner

Just stumbled upon https://daniel.haxx.se/blog/2012/10/10/wsapoll-is-broken/ (sigh).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants