From a776ffd243bbd02948ebefd43f4ac2690ebb11e6 Mon Sep 17 00:00:00 2001 From: Irfan Sheriff Date: Fri, 12 Apr 2013 15:46:29 -0700 Subject: Rewrite an invalid config file We saw a case of config file being corrupted. Add a mechanism to recover from this when wifi is toggled off and on. Bug: 8569820 Change-Id: If2baceb065838d2adb5cde61772d25a05455fc90 --- wifi/wifi.c | 61 +++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 26 deletions(-) (limited to 'wifi') diff --git a/wifi/wifi.c b/wifi/wifi.c index b0ef345..30933fe 100644 --- a/wifi/wifi.c +++ b/wifi/wifi.c @@ -342,6 +342,7 @@ int update_ctrl_interface(const char *config_file) { char *pbuf; char *sptr; struct stat sb; + int ret; if (stat(config_file, &sb) != 0) return -1; @@ -368,6 +369,8 @@ int update_ctrl_interface(const char *config_file) { } else { strcpy(ifc, CONTROL_IFACE_PATH); } + /* Assume file is invalid to begin with */ + ret = -1; /* * if there is a "ctrl_interface=" entry, re-write it ONLY if it is * NOT a directory. The non-directory value option is an Android add-on @@ -378,33 +381,35 @@ int update_ctrl_interface(const char *config_file) { * The is deemed to be a directory if the "DIR=" form is used or * the value begins with "/". */ - if ((sptr = strstr(pbuf, "ctrl_interface=")) && - (!strstr(pbuf, "ctrl_interface=DIR=")) && - (!strstr(pbuf, "ctrl_interface=/"))) { - char *iptr = sptr + strlen("ctrl_interface="); - int ilen = 0; - int mlen = strlen(ifc); - int nwrite; - if (strncmp(ifc, iptr, mlen) != 0) { - ALOGE("ctrl_interface != %s", ifc); - while (((ilen + (iptr - pbuf)) < nread) && (iptr[ilen] != '\n')) - ilen++; - mlen = ((ilen >= mlen) ? ilen : mlen) + 1; - memmove(iptr + mlen, iptr + ilen + 1, nread - (iptr + ilen + 1 - pbuf)); - memset(iptr, '\n', mlen); - memcpy(iptr, ifc, strlen(ifc)); - destfd = TEMP_FAILURE_RETRY(open(config_file, O_RDWR, 0660)); - if (destfd < 0) { - ALOGE("Cannot update \"%s\": %s", config_file, strerror(errno)); - free(pbuf); - return -1; + if (sptr = strstr(pbuf, "ctrl_interface=")) { + ret = 0; + if ((!strstr(pbuf, "ctrl_interface=DIR=")) && + (!strstr(pbuf, "ctrl_interface=/"))) { + char *iptr = sptr + strlen("ctrl_interface="); + int ilen = 0; + int mlen = strlen(ifc); + int nwrite; + if (strncmp(ifc, iptr, mlen) != 0) { + ALOGE("ctrl_interface != %s", ifc); + while (((ilen + (iptr - pbuf)) < nread) && (iptr[ilen] != '\n')) + ilen++; + mlen = ((ilen >= mlen) ? ilen : mlen) + 1; + memmove(iptr + mlen, iptr + ilen + 1, nread - (iptr + ilen + 1 - pbuf)); + memset(iptr, '\n', mlen); + memcpy(iptr, ifc, strlen(ifc)); + destfd = TEMP_FAILURE_RETRY(open(config_file, O_RDWR, 0660)); + if (destfd < 0) { + ALOGE("Cannot update \"%s\": %s", config_file, strerror(errno)); + free(pbuf); + return -1; + } + TEMP_FAILURE_RETRY(write(destfd, pbuf, nread + mlen - ilen -1)); + close(destfd); } - TEMP_FAILURE_RETRY(write(destfd, pbuf, nread + mlen - ilen -1)); - close(destfd); } } free(pbuf); - return 0; + return ret; } int ensure_config_file_exists(const char *config_file) @@ -422,9 +427,13 @@ int ensure_config_file_exists(const char *config_file) ALOGE("Cannot set RW to \"%s\": %s", config_file, strerror(errno)); return -1; } - /* return if filesize is at least 10 bytes */ - if (stat(config_file, &sb) == 0 && sb.st_size > 10) { - return update_ctrl_interface(config_file); + /* return if we were able to update control interface properly */ + if (update_ctrl_interface(config_file) >=0) { + return 0; + } else { + /* This handles the scenario where the file had bad data + * for some reason. We continue and recreate the file. + */ } } else if (errno != ENOENT) { ALOGE("Cannot access \"%s\": %s", config_file, strerror(errno)); -- cgit v1.1