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
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 @@
char *pbuf;
char *sptr;
struct stat sb;
+ int ret;
if (stat(config_file, &sb) != 0)
return -1;
@@ -368,6 +369,8 @@
} else {
strcpy(ifc, CONTROL_IFACE_PATH);
}
+ /* Assume file is invalid to begin with */
+ ret = -1;
/*
* if there is a "ctrl_interface=<value>" 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 @@
* The <value> 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 @@
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));