Patchwork supplicant: Make unix socket non-blocking.

login
register
mail settings
Submitter Ben Greear
Date Nov. 14, 2011, 7:06 p.m.
Message ID <1321297574-28228-1-git-send-email-greearb@candelatech.com>
Download mbox | patch
Permalink /patch/125590/
State Superseded
Headers show

Comments

Ben Greear - Nov. 14, 2011, 7:06 p.m.
From: Ben Greear <greearb@candelatech.com>

This keeps wpa_cli from hanging forever if the other end of the
socket dies.

Signed-hostap: Ben Greear <greearb@candelatech.com>
---
:100644 100644 3b25f77... 8ed9dee... M	src/common/wpa_ctrl.c
:100644 100644 306a222... 113d361... M	wpa_supplicant/ctrl_iface_unix.c
 src/common/wpa_ctrl.c            |   23 +++++++++++++++++++++++
 wpa_supplicant/ctrl_iface_unix.c |   15 ++++++++++++++-
 2 files changed, 37 insertions(+), 1 deletions(-)

Patch

diff --git a/src/common/wpa_ctrl.c b/src/common/wpa_ctrl.c
index 3b25f77..8ed9dee 100644
--- a/src/common/wpa_ctrl.c
+++ b/src/common/wpa_ctrl.c
@@ -295,6 +295,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;
@@ -321,7 +322,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 306a222..113d361 100644
--- a/wpa_supplicant/ctrl_iface_unix.c
+++ b/wpa_supplicant/ctrl_iface_unix.c
@@ -20,7 +20,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"
@@ -265,6 +266,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)
@@ -411,6 +413,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);