[PATCH] wpa_cli infinite loop
Graham Gower
graham.gower
Tue Oct 28 22:03:07 PDT 2008
Hi,
I've stumbled across a strange problem with wpa_cli sitting in an infinite loop.
I'm using wpa_supplicant 0.5.8 + patches for driver_ralink.c from
www.ralinktech.com/ralink/Home/Support/Linux.html on a heavily patched
celinux 2.4.20 for mipsel.
I also tried wpa_supplicant 0.5.10 before looking at the code. I've
not tried running trunk, but the relevant code looks the same anyway.
I start wpa_supplicant and wpa_cli from a script like so:
wpa_supplicant \
-Bw \
-i $iface \
-D ralink \
-c $wpa_conf \
-P $wpa_pidfile
# wait for wpa_supplicant to open its socket interface
while [ ! -r /var/run/wpa_supplicant/$iface ]; do
sleep 1
echo -n "."
done
wpa_cli \
-B \
-a/etc/init.d/wpa_action.sh \
-P $wpa_cli_pidfile
The wpa_supplicant.conf file contains a network and wpa_supplicant
associates with it. Sometimes, wpa_cli will fail to call my action
script (I am unsure what triggers this - a race?). I attached to the
process with gdb and discovered the call to wpa_ctrl_recv() in
wpa_cli_recv_pending() was returning -1, with errno = 95 (ENOTSOCK).
Setting a breakpoint on wpa_cli_reconnect() showed it was not being
called even after the below change to wpa_ctrl.c.
The patch to wpa_cli.c below seems to fix the issue for me. The
wpa_ctrl.c change should also be made, as wpa_ctrl_pending(ctrl) < 0
cannot occur otherwise.
Hope this is useful,
Graham
Index: wpa_cli.c
===================================================================
--- wpa_cli.c (revision 6992)
+++ wpa_cli.c (working copy)
@@ -1192,11 +1192,12 @@
}
} else {
printf("Could not read pending message.\n");
- break;
+ goto reconnect;
}
}
if (wpa_ctrl_pending(ctrl) < 0) {
+reconnect:
printf("Connection to wpa_supplicant lost - trying to "
"reconnect\n");
wpa_cli_reconnect();
Index: wpa_ctrl.c
===================================================================
--- wpa_ctrl.c (revision 6992)
+++ wpa_ctrl.c (working copy)
@@ -287,13 +287,16 @@
int wpa_ctrl_pending(struct wpa_ctrl *ctrl)
{
+ int res;
struct timeval tv;
fd_set rfds;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&rfds);
FD_SET(ctrl->s, &rfds);
- select(ctrl->s + 1, &rfds, NULL, NULL, &tv);
+ res = select(ctrl->s + 1, &rfds, NULL, NULL, &tv);
+ if (res < 0)
+ return res;
return FD_ISSET(ctrl->s, &rfds);
}
More information about the Hostap
mailing list