Make UNIX socket non-blocking for ctrl_iface
This keeps wpa_cli from hanging forever if the other end of the socket dies. Signed-hostap: Ben Greear <greearb@candelatech.com>
This commit is contained in:
parent
c8b245b6a4
commit
4fdc8def88
2 changed files with 57 additions and 0 deletions
|
@ -12,6 +12,8 @@
|
||||||
|
|
||||||
#ifdef CONFIG_CTRL_IFACE_UNIX
|
#ifdef CONFIG_CTRL_IFACE_UNIX
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#endif /* CONFIG_CTRL_IFACE_UNIX */
|
#endif /* CONFIG_CTRL_IFACE_UNIX */
|
||||||
|
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
|
@ -73,6 +75,7 @@ struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
|
||||||
int ret;
|
int ret;
|
||||||
size_t res;
|
size_t res;
|
||||||
int tries = 0;
|
int tries = 0;
|
||||||
|
int flags;
|
||||||
|
|
||||||
ctrl = os_malloc(sizeof(*ctrl));
|
ctrl = os_malloc(sizeof(*ctrl));
|
||||||
if (ctrl == NULL)
|
if (ctrl == NULL)
|
||||||
|
@ -156,6 +159,19 @@ try_again:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make socket non-blocking so that we don't hang forever if
|
||||||
|
* target dies unexpectedly.
|
||||||
|
*/
|
||||||
|
flags = fcntl(ctrl->s, F_GETFL);
|
||||||
|
if (flags >= 0) {
|
||||||
|
flags |= O_NONBLOCK;
|
||||||
|
if (fcntl(ctrl->s, F_SETFL, flags) < 0) {
|
||||||
|
perror("fcntl(ctrl->s, O_NONBLOCK)");
|
||||||
|
/* Not fatal, continue on.*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ctrl;
|
return ctrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,6 +305,7 @@ int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
|
||||||
void (*msg_cb)(char *msg, size_t len))
|
void (*msg_cb)(char *msg, size_t len))
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
struct os_time started_at;
|
||||||
int res;
|
int res;
|
||||||
fd_set rfds;
|
fd_set rfds;
|
||||||
const char *_cmd;
|
const char *_cmd;
|
||||||
|
@ -315,7 +332,30 @@ int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
|
||||||
_cmd_len = 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 (send(ctrl->s, _cmd, _cmd_len, 0) < 0) {
|
||||||
|
if (errno == EAGAIN || errno == EBUSY || errno == EWOULDBLOCK)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Must be a 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);
|
os_free(cmd_buf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
#include <cutils/sockets.h>
|
#include <cutils/sockets.h>
|
||||||
#endif /* ANDROID */
|
#endif /* ANDROID */
|
||||||
|
@ -259,6 +261,7 @@ wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
|
||||||
char *buf, *dir = NULL, *gid_str = NULL;
|
char *buf, *dir = NULL, *gid_str = NULL;
|
||||||
struct group *grp;
|
struct group *grp;
|
||||||
char *endp;
|
char *endp;
|
||||||
|
int flags;
|
||||||
|
|
||||||
priv = os_zalloc(sizeof(*priv));
|
priv = os_zalloc(sizeof(*priv));
|
||||||
if (priv == NULL)
|
if (priv == NULL)
|
||||||
|
@ -405,6 +408,20 @@ wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
havesock:
|
havesock:
|
||||||
#endif /* ANDROID */
|
#endif /* ANDROID */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make socket non-blocking so that we don't hang forever if
|
||||||
|
* target dies unexpectedly.
|
||||||
|
*/
|
||||||
|
flags = fcntl(priv->sock, F_GETFL);
|
||||||
|
if (flags >= 0) {
|
||||||
|
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,
|
eloop_register_read_sock(priv->sock, wpa_supplicant_ctrl_iface_receive,
|
||||||
wpa_s, priv);
|
wpa_s, priv);
|
||||||
wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);
|
wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);
|
||||||
|
|
Loading…
Reference in a new issue