[PATCH 1/7] supplicant: Make unix socket non-blocking.
greearb at candelatech.com
greearb
Fri Jul 6 09:52:35 PDT 2012
From: Ben Greear <greearb at candelatech.com>
This keeps wpa_cli from hanging forever if the other end of the
socket dies.
Signed-hostap: Ben Greear <greearb at candelatech.com>
---
src/common/wpa_ctrl.c | 37 ++++++++++++++++++++++++++++++++++++-
wpa_supplicant/ctrl_iface_unix.c | 15 ++++++++++++++-
2 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/src/common/wpa_ctrl.c b/src/common/wpa_ctrl.c
index b2b0683..e671f79 100644
--- a/src/common/wpa_ctrl.c
+++ b/src/common/wpa_ctrl.c
@@ -12,6 +12,8 @@
#ifdef CONFIG_CTRL_IFACE_UNIX
#include <sys/un.h>
+#include <unistd.h>
+#include <fcntl.h>
#endif /* CONFIG_CTRL_IFACE_UNIX */
#ifdef ANDROID
@@ -23,7 +25,6 @@
#include "wpa_ctrl.h"
#include "common.h"
-
#if defined(CONFIG_CTRL_IFACE_UNIX) || defined(CONFIG_CTRL_IFACE_UDP)
#define CTRL_IFACE_SOCKET
#endif /* CONFIG_CTRL_IFACE_UNIX || CONFIG_CTRL_IFACE_UDP */
@@ -73,6 +74,7 @@ struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
int ret;
size_t res;
int tries = 0;
+ int flags;
ctrl = os_malloc(sizeof(*ctrl));
if (ctrl == NULL)
@@ -156,6 +158,16 @@ try_again:
return NULL;
}
+ /* Make socket non-blocking so that we don't hang forever if
+ * target dies unexpectedly.
+ */
+ flags = fcntl(ctrl->s, F_GETFL);
+ flags |= (O_NONBLOCK);
+ if (fcntl(ctrl->s, F_SETFL, flags) < 0) {
+ perror("fcntl(ctrl->s, O_NONBLOCK)");
+ /* Not fatal, continue on.*/
+ }
+
return ctrl;
}
@@ -289,6 +301,7 @@ int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
void (*msg_cb)(char *msg, size_t len))
{
struct timeval tv;
+ struct os_time started_at;
int res;
fd_set rfds;
const char *_cmd;
@@ -315,7 +328,29 @@ int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
_cmd_len = cmd_len;
}
+ errno = 0;
+ started_at.sec = 0;
+ started_at.usec = 0;
+retry_send:
if (send(ctrl->s, _cmd, _cmd_len, 0) < 0) {
+ if ((errno == EAGAIN) || (errno = EBUSY)
+ || (errno == EWOULDBLOCK)) {
+ /* Must be non-blocking socket...try for a bit longer
+ * before giving up.
+ */
+ if (started_at.sec == 0)
+ os_get_time(&started_at);
+ else {
+ struct os_time n;
+ os_get_time(&n);
+ /* Try for a few seconds. */
+ if (n.sec > (started_at.sec + 5))
+ goto send_err;
+ }
+ os_sleep(1, 0);
+ goto retry_send;
+ }
+ send_err:
os_free(cmd_buf);
return -1;
}
diff --git a/wpa_supplicant/ctrl_iface_unix.c b/wpa_supplicant/ctrl_iface_unix.c
index 7bebcb8..e4fc6bb 100644
--- a/wpa_supplicant/ctrl_iface_unix.c
+++ b/wpa_supplicant/ctrl_iface_unix.c
@@ -14,7 +14,8 @@
#ifdef ANDROID
#include <cutils/sockets.h>
#endif /* ANDROID */
-
+#include <unistd.h>
+#include <fcntl.h>
#include "utils/common.h"
#include "utils/eloop.h"
#include "utils/list.h"
@@ -259,6 +260,7 @@ wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
char *buf, *dir = NULL, *gid_str = NULL;
struct group *grp;
char *endp;
+ int flags;
priv = os_zalloc(sizeof(*priv));
if (priv == NULL)
@@ -405,6 +407,17 @@ wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
#ifdef ANDROID
havesock:
#endif /* ANDROID */
+
+ /* Make socket non-blocking so that we don't hang forever if
+ * target dies unexpectedly.
+ */
+ flags = fcntl(priv->sock, F_GETFL);
+ flags |= (O_NONBLOCK);
+ if (fcntl(priv->sock, F_SETFL, flags) < 0) {
+ perror("fcntl(ctrl, O_NONBLOCK)");
+ /* Not fatal, continue on.*/
+ }
+
eloop_register_read_sock(priv->sock, wpa_supplicant_ctrl_iface_receive,
wpa_s, priv);
wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);
--
1.7.3.4
More information about the Hostap
mailing list