[PATCH] hostapd_cli: Fix memory leak on interactive mode

Masashi Honma honma at ictec.co.jp
Wed Jan 26 19:44:17 EST 2011


Hello.

The hostapd_cli shows following meassages when I stop it with SIGINT.

-------
Interactive mode

> ^CMEMLEAK[0x9f0f008]: len 6
WPA_TRACE: memleak - START
[0]: ./hostapd_cli(os_malloc+0x55) [0x804be25]
     os_malloc() ../src/utils/os_unix.c:359
[1]: ./hostapd_cli(os_strdup+0x27) [0x804be67]
     os_strdup() ../src/utils/os_unix.c:430
[2]: ./hostapd_cli(main+0x122) [0x804b312]
     main() hostapd_cli.c:953
WPA_TRACE: memleak - END
MEMLEAK: total 6 bytes
-------

This patch solves this issue with select() instead of alert().


diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
index 7cc84bb..cb4a6e5 100644
--- a/hostapd/hostapd_cli.c
+++ b/hostapd/hostapd_cli.c
@@ -797,46 +797,103 @@ static void hostapd_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
 static void hostapd_cli_interactive(void)
 {
 	const int max_args = 10;
-	char cmd[256], *res, *argv[max_args], *pos;
+	char buf[256], *res, *argv[max_args], *pos;
 	int argc;
+	fd_set rfds;
+	int ret;
+	size_t len = sizeof(buf) - 1;
+	struct timeval tv;
 
 	printf("\nInteractive mode\n\n");
+	printf("> ");
+	fflush(stdout);
 
-	do {
-		hostapd_cli_recv_pending(ctrl_conn, 0, 0);
-		printf("> ");
-		alarm(ping_interval);
-		res = fgets(cmd, sizeof(cmd), stdin);
-		alarm(0);
-		if (res == NULL)
+	while (!hostapd_cli_quit) {
+		FD_ZERO(&rfds);
+		tv.tv_sec = 2;
+		tv.tv_usec = 0;
+		if (ctrl_conn == NULL)
+			ret = select(0, &rfds, NULL, NULL, &tv);
+		else {
+			FD_SET(0, &rfds);
+			FD_SET(wpa_ctrl_get_fd(ctrl_conn), &rfds);
+			ret = select(wpa_ctrl_get_fd(ctrl_conn) + 1, &rfds,
+				     NULL, NULL, &tv);
+		}
+		if (ret < 0) {
+			if (errno == EINTR)
+				continue;
+			perror("select() failed");
 			break;
-		pos = cmd;
-		while (*pos != '\0') {
-			if (*pos == '\n') {
-				*pos = '\0';
-				break;
+		}
+		if (ret == 0) { /* Timeout */
+			if (ctrl_conn != NULL &&
+			    _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
+				printf("Connection to hostapd lost - "
+				       "trying to reconnect\n");
+				hostapd_cli_close_connection();
 			}
-			pos++;
+			if (ctrl_conn == NULL) {
+				ctrl_conn = hostapd_cli_open_connection(
+					ctrl_ifname);
+				if (ctrl_conn != NULL) {
+					if (wpa_ctrl_attach(ctrl_conn) == 0) {
+						printf("Connection to hostapd "
+						       "re-established\n");
+						hostapd_cli_attached = 1;
+					} else {
+						printf("Warning: Failed to "
+						       "attach to hostapd.\n");
+						hostapd_cli_close_connection();
+					}
+				}
+			}
+			continue;
 		}
-		argc = 0;
-		pos = cmd;
-		for (;;) {
-			while (*pos == ' ')
-				pos++;
-			if (*pos == '\0')
+		if (FD_ISSET(0, &rfds)) {
+			res = fgets(buf, sizeof(buf), stdin);
+			if (res == NULL)
 				break;
-			argv[argc] = pos;
-			argc++;
-			if (argc == max_args)
-				break;
-			while (*pos != '\0' && *pos != ' ')
+			pos = buf;
+			while (*pos != '\0') {
+				if (*pos == '\n') {
+					*pos = '\0';
+					break;
+				}
 				pos++;
-			if (*pos == ' ')
-				*pos++ = '\0';
+			}
+			argc = 0;
+			pos = buf;
+			for (;;) {
+				while (*pos == ' ')
+					pos++;
+				if (*pos == '\0')
+					break;
+				argv[argc] = pos;
+				argc++;
+				if (argc == max_args)
+					break;
+				while (*pos != '\0' && *pos != ' ')
+					pos++;
+				if (*pos == ' ')
+					*pos++ = '\0';
+			}
+			if (argc)
+				wpa_request(ctrl_conn, argc, argv);
+			if (memcmp(buf, "quit", 4) != 0)
+				printf("> ");
+			fflush(stdout);
+		}
+		if (FD_ISSET(wpa_ctrl_get_fd(ctrl_conn), &rfds)) {
+			if (wpa_ctrl_recv(ctrl_conn, buf, &len) == 0) {
+				buf[len] = '\0';
+				printf("%s\n", buf);
+			} else {
+				printf("Could not read pending message.\n");
+				break;
+			}
 		}
-		if (argc)
-			wpa_request(ctrl_conn, argc, argv);
-	} while (!hostapd_cli_quit);
+	}
 }
 
 
@@ -852,32 +909,7 @@ static void hostapd_cli_cleanup(void)
 
 static void hostapd_cli_terminate(int sig)
 {
-	hostapd_cli_cleanup();
-	exit(0);
-}
-
-
-static void hostapd_cli_alarm(int sig)
-{
-	if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
-		printf("Connection to hostapd lost - trying to reconnect\n");
-		hostapd_cli_close_connection();
-	}
-	if (!ctrl_conn) {
-		ctrl_conn = hostapd_cli_open_connection(ctrl_ifname);
-		if (ctrl_conn) {
-			printf("Connection to hostapd re-established\n");
-			if (wpa_ctrl_attach(ctrl_conn) == 0) {
-				hostapd_cli_attached = 1;
-			} else {
-				printf("Warning: Failed to attach to "
-				       "hostapd.\n");
-			}
-		}
-	}
-	if (ctrl_conn)
-		hostapd_cli_recv_pending(ctrl_conn, 1, 0);
-	alarm(ping_interval);
+	hostapd_cli_cmd_quit(NULL, 0, NULL);
 }
 
 
@@ -1009,7 +1041,6 @@ int main(int argc, char *argv[])
 
 	signal(SIGINT, hostapd_cli_terminate);
 	signal(SIGTERM, hostapd_cli_terminate);
-	signal(SIGALRM, hostapd_cli_alarm);
 
 	if (interactive || action_file) {
 		if (wpa_ctrl_attach(ctrl_conn) == 0) {


Regards,
Masashi Honma.


More information about the HostAP mailing list