Revert "DO NOT MERGE Control fault injection with config files instead of build flags"

This reverts commit f73abf36bcfd433a3fdd1664a77e8e531346c1b1.

Bug: 27724259
Change-Id: I1301fdad15650837d0b1febd0c3239134e2b94fb
diff --git a/applypatch/applypatch.cpp b/applypatch/applypatch.cpp
index 7985fc0..9d8a217 100644
--- a/applypatch/applypatch.cpp
+++ b/applypatch/applypatch.cpp
@@ -34,8 +34,8 @@
 #include "applypatch.h"
 #include "mtdutils/mtdutils.h"
 #include "edify/expr.h"
-#include "ota_io.h"
 #include "print_sha1.h"
+#include "otafault/ota_io.h"
 
 static int LoadPartitionContents(const char* filename, FileContents* file);
 static ssize_t FileSink(const unsigned char* data, ssize_t len, void* token);
diff --git a/otafault/Android.mk b/otafault/Android.mk
index 7468de6..75617a1 100644
--- a/otafault/Android.mk
+++ b/otafault/Android.mk
@@ -1,10 +1,10 @@
-# Copyright 2015 The Android Open Source Project
+# Copyright 2015 The ANdroid Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-#      http://www.apache.org/licenses/LICENSE-2.0
+# 	   http://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,30 +14,45 @@
 
 LOCAL_PATH := $(call my-dir)
 
+empty :=
+space := $(empty) $(empty)
+comma := ,
+
+ifneq ($(TARGET_INJECT_FAULTS),)
+TARGET_INJECT_FAULTS := $(subst $(comma),$(space),$(strip $(TARGET_INJECT_FAULTS)))
+endif
+
 include $(CLEAR_VARS)
 
-otafault_static_libs := \
-    libminzip \
-    libz \
-    libselinux \
-
-LOCAL_SRC_FILES := config.cpp ota_io.cpp
+LOCAL_SRC_FILES := ota_io.cpp
 LOCAL_MODULE_TAGS := eng
 LOCAL_MODULE := libotafault
 LOCAL_CLANG := true
-LOCAL_C_INCLUDES := bootable/recovery
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
-LOCAL_WHOLE_STATIC_LIBRARIES := $(otafault_static_libs)
+
+ifneq ($(TARGET_INJECT_FAULTS),)
+$(foreach ft,$(TARGET_INJECT_FAULTS),\
+	$(eval LOCAL_CFLAGS += -DTARGET_$(ft)_FAULT=$(TARGET_$(ft)_FAULT_FILE)))
+LOCAL_CFLAGS += -Wno-unused-parameter
+LOCAL_CFLAGS += -DTARGET_INJECT_FAULTS
+endif
+
+LOCAL_STATIC_LIBRARIES := libc
 
 include $(BUILD_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES := config.cpp ota_io.cpp test.cpp
+LOCAL_SRC_FILES := ota_io.cpp test.cpp
 LOCAL_MODULE_TAGS := tests
 LOCAL_MODULE := otafault_test
-LOCAL_STATIC_LIBRARIES := $(otafault_static_libs)
-LOCAL_C_INCLUDES := bootable/recovery
+LOCAL_STATIC_LIBRARIES := libc
 LOCAL_FORCE_STATIC_EXECUTABLE := true
+LOCAL_CFLAGS += -Wno-unused-parameter -Wno-writable-strings
+
+ifneq ($(TARGET_INJECT_FAULTS),)
+$(foreach ft,$(TARGET_INJECT_FAULTS),\
+	$(eval LOCAL_CFLAGS += -DTARGET_$(ft)_FAULT=$(TARGET_$(ft)_FAULT_FILE)))
+LOCAL_CFLAGS += -DTARGET_INJECT_FAULTS
+endif
 
 include $(BUILD_EXECUTABLE)
diff --git a/otafault/config.cpp b/otafault/config.cpp
deleted file mode 100644
index c87f9a6..0000000
--- a/otafault/config.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <map>
-#include <string>
-
-#include <stdio.h>
-#include <unistd.h>
-
-#include "minzip/Zip.h"
-#include "config.h"
-#include "ota_io.h"
-
-#define OTAIO_MAX_FNAME_SIZE 128
-
-static ZipArchive* archive;
-static std::map<const char*, bool> should_inject_cache;
-
-static const char* get_type_path(const char* io_type) {
-    char* path = (char*)calloc(strlen(io_type) + strlen(OTAIO_BASE_DIR) + 2, sizeof(char));
-    sprintf(path, "%s/%s", OTAIO_BASE_DIR, io_type);
-    return path;
-}
-
-void ota_io_init(ZipArchive* za) {
-    archive = za;
-    ota_set_fault_files();
-}
-
-bool should_fault_inject(const char* io_type) {
-    if (should_inject_cache.find(io_type) != should_inject_cache.end()) {
-        return should_inject_cache[io_type];
-    }
-    const char* type_path = get_type_path(io_type);
-    const ZipEntry* entry = mzFindZipEntry(archive, type_path);
-    should_inject_cache[type_path] = entry != nullptr;
-    free((void*)type_path);
-    return entry != NULL;
-}
-
-bool should_hit_cache() {
-    return should_fault_inject(OTAIO_CACHE);
-}
-
-std::string fault_fname(const char* io_type) {
-    const char* type_path = get_type_path(io_type);
-    char* fname = (char*) calloc(OTAIO_MAX_FNAME_SIZE, sizeof(char));
-    const ZipEntry* entry = mzFindZipEntry(archive, type_path);
-    mzReadZipEntry(archive, entry, fname, OTAIO_MAX_FNAME_SIZE);
-    free((void*)type_path);
-    return std::string(fname);
-}
diff --git a/otafault/config.h b/otafault/config.h
deleted file mode 100644
index 4430be3..0000000
--- a/otafault/config.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Read configuration files in the OTA package to determine which files, if any, will trigger errors.
- *
- * OTA packages can be modified to trigger errors by adding a top-level
- * directory called .libotafault, which may optionally contain up to three
- * files called READ, WRITE, and FSYNC. Each one of these optional files
- * contains the name of a single file on the device disk which will cause
- * an IO error on the first call of the appropriate I/O action to that file.
- *
- * Example:
- * ota.zip
- *   <normal package contents>
- *   .libotafault
- *     WRITE
- *
- * If the contents of the file WRITE were /system/build.prop, the first write
- * action to /system/build.prop would fail with EIO. Note that READ and
- * FSYNC files are absent, so these actions will not cause an error.
- */
-
-#ifndef _UPDATER_OTA_IO_CFG_H_
-#define _UPDATER_OTA_IO_CFG_H_
-
-#include <string>
-
-#include <stdbool.h>
-
-#include "minzip/Zip.h"
-
-#define OTAIO_BASE_DIR ".libotafault"
-#define OTAIO_READ "READ"
-#define OTAIO_WRITE "WRITE"
-#define OTAIO_FSYNC "FSYNC"
-#define OTAIO_CACHE "CACHE"
-
-/*
- * Initialize libotafault by providing a reference to the OTA package.
- */
-void ota_io_init(ZipArchive* za);
-
-/*
- * Return true if a config file is present for the given IO type.
- */
-bool should_fault_inject(const char* io_type);
-
-/*
- * Return true if an EIO should occur on the next hit to /cache/saved.file
- * instead of the next hit to the specified file.
- */
-bool should_hit_cache();
-
-/*
- * Return the name of the file that should cause an error for the
- * given IO type.
- */
-std::string fault_fname(const char* io_type);
-
-#endif
diff --git a/otafault/ota_io.cpp b/otafault/ota_io.cpp
index 0445853..9434ebe 100644
--- a/otafault/ota_io.cpp
+++ b/otafault/ota_io.cpp
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 
+#if defined (TARGET_INJECT_FAULTS)
 #include <map>
+#endif
 
 #include <errno.h>
 #include <fcntl.h>
@@ -22,155 +24,185 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
-#include "config.h"
 #include "ota_io.h"
 
-static std::map<intptr_t, const char*> filename_cache;
-static std::string read_fault_file_name = "";
-static std::string write_fault_file_name = "";
-static std::string fsync_fault_file_name = "";
-
-static bool get_hit_file(const char* cached_path, std::string ffn) {
-    return should_hit_cache()
-        ? !strncmp(cached_path, OTAIO_CACHE_FNAME, strlen(cached_path))
-        : !strncmp(cached_path, ffn.c_str(), strlen(cached_path));
-}
-
-void ota_set_fault_files() {
-    if (should_fault_inject(OTAIO_READ)) {
-        read_fault_file_name = fault_fname(OTAIO_READ);
-    }
-    if (should_fault_inject(OTAIO_WRITE)) {
-        write_fault_file_name = fault_fname(OTAIO_WRITE);
-    }
-    if (should_fault_inject(OTAIO_FSYNC)) {
-        fsync_fault_file_name = fault_fname(OTAIO_FSYNC);
-    }
-}
+#if defined (TARGET_INJECT_FAULTS)
+static std::map<int, const char*> FilenameCache;
+static std::string FaultFileName =
+#if defined (TARGET_READ_FAULT)
+        TARGET_READ_FAULT;
+#elif defined (TARGET_WRITE_FAULT)
+        TARGET_WRITE_FAULT;
+#elif defined (TARGET_FSYNC_FAULT)
+        TARGET_FSYNC_FAULT;
+#endif // defined (TARGET_READ_FAULT)
+#endif // defined (TARGET_INJECT_FAULTS)
 
 bool have_eio_error = false;
 
 int ota_open(const char* path, int oflags) {
+#if defined (TARGET_INJECT_FAULTS)
     // Let the caller handle errors; we do not care if open succeeds or fails
     int fd = open(path, oflags);
-    filename_cache[fd] = path;
+    FilenameCache[fd] = path;
     return fd;
+#else
+    return open(path, oflags);
+#endif
 }
 
 int ota_open(const char* path, int oflags, mode_t mode) {
+#if defined (TARGET_INJECT_FAULTS)
     int fd = open(path, oflags, mode);
-    filename_cache[fd] = path;
-    return fd; }
+    FilenameCache[fd] = path;
+    return fd;
+#else
+    return open(path, oflags, mode);
+#endif
+}
 
 FILE* ota_fopen(const char* path, const char* mode) {
+#if defined (TARGET_INJECT_FAULTS)
     FILE* fh = fopen(path, mode);
-    filename_cache[(intptr_t)fh] = path;
+    FilenameCache[(intptr_t)fh] = path;
     return fh;
+#else
+    return fopen(path, mode);
+#endif
 }
 
 int ota_close(int fd) {
-    // descriptors can be reused, so make sure not to leave them in the cache
-    filename_cache.erase(fd);
+#if defined (TARGET_INJECT_FAULTS)
+    // descriptors can be reused, so make sure not to leave them in the cahce
+    FilenameCache.erase(fd);
+#endif
     return close(fd);
 }
 
 int ota_fclose(FILE* fh) {
-    filename_cache.erase((intptr_t)fh);
+#if defined (TARGET_INJECT_FAULTS)
+    FilenameCache.erase((intptr_t)fh);
+#endif
     return fclose(fh);
 }
 
 size_t ota_fread(void* ptr, size_t size, size_t nitems, FILE* stream) {
-    if (should_fault_inject(OTAIO_READ)) {
-        auto cached = filename_cache.find((intptr_t)stream);
-        const char* cached_path = cached->second;
-        if (cached != filename_cache.end() &&
-                get_hit_file(cached_path, read_fault_file_name)) {
-            read_fault_file_name = "";
-            errno = EIO;
+#if defined (TARGET_READ_FAULT)
+    if (FilenameCache.find((intptr_t)stream) != FilenameCache.end()
+            && FilenameCache[(intptr_t)stream] == FaultFileName) {
+        FaultFileName = "";
+        errno = EIO;
+        have_eio_error = true;
+        return 0;
+    } else {
+        size_t status = fread(ptr, size, nitems, stream);
+        // If I/O error occurs, set the retry-update flag.
+        if (status != nitems && errno == EIO) {
             have_eio_error = true;
-            return 0;
         }
+        return status;
     }
+#else
     size_t status = fread(ptr, size, nitems, stream);
     if (status != nitems && errno == EIO) {
         have_eio_error = true;
     }
     return status;
+#endif
 }
 
 ssize_t ota_read(int fd, void* buf, size_t nbyte) {
-    if (should_fault_inject(OTAIO_READ)) {
-        auto cached = filename_cache.find(fd);
-        const char* cached_path = cached->second;
-        if (cached != filename_cache.end()
-                && get_hit_file(cached_path, read_fault_file_name)) {
-            read_fault_file_name = "";
-            errno = EIO;
+#if defined (TARGET_READ_FAULT)
+    if (FilenameCache.find(fd) != FilenameCache.end()
+            && FilenameCache[fd] == FaultFileName) {
+        FaultFileName = "";
+        errno = EIO;
+        have_eio_error = true;
+        return -1;
+    } else {
+        ssize_t status = read(fd, buf, nbyte);
+        if (status == -1 && errno == EIO) {
             have_eio_error = true;
-            return -1;
         }
+        return status;
     }
+#else
     ssize_t status = read(fd, buf, nbyte);
     if (status == -1 && errno == EIO) {
         have_eio_error = true;
     }
     return status;
+#endif
 }
 
 size_t ota_fwrite(const void* ptr, size_t size, size_t count, FILE* stream) {
-    if (should_fault_inject(OTAIO_WRITE)) {
-        auto cached = filename_cache.find((intptr_t)stream);
-        const char* cached_path = cached->second;
-        if (cached != filename_cache.end() &&
-                get_hit_file(cached_path, write_fault_file_name)) {
-            write_fault_file_name = "";
-            errno = EIO;
+#if defined (TARGET_WRITE_FAULT)
+    if (FilenameCache.find((intptr_t)stream) != FilenameCache.end()
+            && FilenameCache[(intptr_t)stream] == FaultFileName) {
+        FaultFileName = "";
+        errno = EIO;
+        have_eio_error = true;
+        return 0;
+    } else {
+        size_t status = fwrite(ptr, size, count, stream);
+        if (status != count && errno == EIO) {
             have_eio_error = true;
-            return 0;
         }
+        return status;
     }
+#else
     size_t status = fwrite(ptr, size, count, stream);
     if (status != count && errno == EIO) {
         have_eio_error = true;
     }
     return status;
+#endif
 }
 
 ssize_t ota_write(int fd, const void* buf, size_t nbyte) {
-    if (should_fault_inject(OTAIO_WRITE)) {
-        auto cached = filename_cache.find(fd);
-        const char* cached_path = cached->second;
-        if (cached != filename_cache.end() &&
-                get_hit_file(cached_path, write_fault_file_name)) {
-            write_fault_file_name = "";
-            errno = EIO;
+#if defined (TARGET_WRITE_FAULT)
+    if (FilenameCache.find(fd) != FilenameCache.end()
+            && FilenameCache[fd] == FaultFileName) {
+        FaultFileName = "";
+        errno = EIO;
+        have_eio_error = true;
+        return -1;
+    } else {
+        ssize_t status = write(fd, buf, nbyte);
+        if (status == -1 && errno == EIO) {
             have_eio_error = true;
-            return -1;
         }
+        return status;
     }
+#else
     ssize_t status = write(fd, buf, nbyte);
     if (status == -1 && errno == EIO) {
         have_eio_error = true;
     }
     return status;
+#endif
 }
 
 int ota_fsync(int fd) {
-    if (should_fault_inject(OTAIO_FSYNC)) {
-        auto cached = filename_cache.find(fd);
-        const char* cached_path = cached->second;
-        if (cached != filename_cache.end() &&
-                get_hit_file(cached_path, fsync_fault_file_name)) {
-            fsync_fault_file_name = "";
-            errno = EIO;
+#if defined (TARGET_FSYNC_FAULT)
+    if (FilenameCache.find(fd) != FilenameCache.end()
+            && FilenameCache[fd] == FaultFileName) {
+        FaultFileName = "";
+        errno = EIO;
+        have_eio_error = true;
+        return -1;
+    } else {
+        int status = fsync(fd);
+        if (status == -1 && errno == EIO) {
             have_eio_error = true;
-            return -1;
         }
+        return status;
     }
+#else
     int status = fsync(fd);
     if (status == -1 && errno == EIO) {
         have_eio_error = true;
     }
     return status;
+#endif
 }
-
diff --git a/otafault/ota_io.h b/otafault/ota_io.h
index 84187a7..641a5ae 100644
--- a/otafault/ota_io.h
+++ b/otafault/ota_io.h
@@ -26,10 +26,6 @@
 #include <stdio.h>
 #include <sys/stat.h>
 
-#define OTAIO_CACHE_FNAME "/cache/saved.file"
-
-void ota_set_fault_files();
-
 int ota_open(const char* path, int oflags);
 
 int ota_open(const char* path, int oflags, mode_t mode);
diff --git a/otafault/test.cpp b/otafault/test.cpp
index 6514782..a0f7315 100644
--- a/otafault/test.cpp
+++ b/otafault/test.cpp
@@ -17,18 +17,16 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
-#include <unistd.h>
 
 #include "ota_io.h"
 
-int main(int /* argc */, char** /* argv */) {
+int main(int argc, char **argv) {
     int fd = open("testdata/test.file", O_RDWR);
     char buf[8];
-    const char* out = "321";
+    char *out = "321";
     int readv = ota_read(fd, buf, 4);
     printf("Read returned %d\n", readv);
     int writev = ota_write(fd, out, 4);
     printf("Write returned %d\n", writev);
-    close(fd);
     return 0;
 }
diff --git a/updater/blockimg.cpp b/updater/blockimg.cpp
index faa7008..e9c8ddb 100644
--- a/updater/blockimg.cpp
+++ b/updater/blockimg.cpp
@@ -45,7 +45,7 @@
 #include "install.h"
 #include "openssl/sha.h"
 #include "minzip/Hash.h"
-#include "ota_io.h"
+#include "otafault/ota_io.h"
 #include "print_sha1.h"
 #include "unique_fd.h"
 #include "updater.h"
diff --git a/updater/install.cpp b/updater/install.cpp
index 6ae1e5f..b7d9e85 100644
--- a/updater/install.cpp
+++ b/updater/install.cpp
@@ -51,7 +51,7 @@
 #include "minzip/DirUtil.h"
 #include "mtdutils/mounts.h"
 #include "mtdutils/mtdutils.h"
-#include "ota_io.h"
+#include "otafault/ota_io.h"
 #include "updater.h"
 #include "install.h"
 #include "tune2fs.h"
diff --git a/updater/updater.cpp b/updater/updater.cpp
index 1693fa1..ddc01e1 100644
--- a/updater/updater.cpp
+++ b/updater/updater.cpp
@@ -25,7 +25,6 @@
 #include "blockimg.h"
 #include "minzip/Zip.h"
 #include "minzip/SysUtil.h"
-#include "config.h"
 
 // Generated by the makefile, this function defines the
 // RegisterDeviceExtensions() function, which calls all the
@@ -85,7 +84,6 @@
                argv[3], strerror(err));
         return 3;
     }
-    ota_io_init(&za);
 
     const ZipEntry* script_entry = mzFindZipEntry(&za, SCRIPT_NAME);
     if (script_entry == NULL) {