Loading applypatch/applypatch.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -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); Loading otafault/Android.mk +14 −29 Original line number Diff line number Diff line # 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. Loading @@ -14,45 +14,30 @@ 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) LOCAL_SRC_FILES := ota_io.cpp otafault_static_libs := \ libminzip \ libz \ libselinux \ LOCAL_SRC_FILES := config.cpp ota_io.cpp LOCAL_MODULE_TAGS := eng LOCAL_MODULE := libotafault LOCAL_CLANG := true 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 LOCAL_C_INCLUDES := bootable/recovery LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) LOCAL_WHOLE_STATIC_LIBRARIES := $(otafault_static_libs) include $(BUILD_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_SRC_FILES := ota_io.cpp test.cpp LOCAL_SRC_FILES := config.cpp ota_io.cpp test.cpp LOCAL_MODULE_TAGS := tests LOCAL_MODULE := otafault_test LOCAL_STATIC_LIBRARIES := libc LOCAL_STATIC_LIBRARIES := $(otafault_static_libs) LOCAL_C_INCLUDES := bootable/recovery 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) otafault/config.cpp 0 → 100644 +65 −0 Original line number Diff line number Diff line /* * 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); } otafault/config.h 0 → 100644 +74 −0 Original line number Diff line number Diff line /* * 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 otafault/ota_io.cpp +76 −87 Original line number Diff line number Diff line Loading @@ -14,9 +14,7 @@ * limitations under the License. */ #if defined (TARGET_INJECT_FAULTS) #include <map> #endif #include <errno.h> #include <fcntl.h> Loading @@ -24,137 +22,128 @@ #include <sys/stat.h> #include <unistd.h> #include "config.h" #include "ota_io.h" #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) 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); } } 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); FilenameCache[fd] = path; filename_cache[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); FilenameCache[fd] = path; return fd; #else return open(path, oflags, mode); #endif } filename_cache[fd] = path; return fd; } FILE* ota_fopen(const char* path, const char* mode) { #if defined (TARGET_INJECT_FAULTS) FILE* fh = fopen(path, mode); FilenameCache[(intptr_t)fh] = path; filename_cache[(intptr_t)fh] = path; return fh; #else return fopen(path, mode); #endif } int ota_close(int fd) { #if defined (TARGET_INJECT_FAULTS) // descriptors can be reused, so make sure not to leave them in the cahce FilenameCache.erase(fd); #endif // descriptors can be reused, so make sure not to leave them in the cache filename_cache.erase(fd); return close(fd); } int ota_fclose(FILE* fh) { #if defined (TARGET_INJECT_FAULTS) FilenameCache.erase((intptr_t)fh); #endif filename_cache.erase((intptr_t)fh); return fclose(fh); } size_t ota_fread(void* ptr, size_t size, size_t nitems, FILE* stream) { #if defined (TARGET_READ_FAULT) if (FilenameCache.find((intptr_t)stream) != FilenameCache.end() && FilenameCache[(intptr_t)stream] == FaultFileName) { FaultFileName = ""; 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; return 0; } else { return fread(ptr, size, nitems, stream); } #else } return fread(ptr, size, nitems, stream); #endif } ssize_t ota_read(int fd, void* buf, size_t nbyte) { #if defined (TARGET_READ_FAULT) if (FilenameCache.find(fd) != FilenameCache.end() && FilenameCache[fd] == FaultFileName) { FaultFileName = ""; 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; return -1; } else { return read(fd, buf, nbyte); } #else } return read(fd, buf, nbyte); #endif } size_t ota_fwrite(const void* ptr, size_t size, size_t count, FILE* stream) { #if defined (TARGET_WRITE_FAULT) if (FilenameCache.find((intptr_t)stream) != FilenameCache.end() && FilenameCache[(intptr_t)stream] == FaultFileName) { FaultFileName = ""; 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; return 0; } else { return fwrite(ptr, size, count, stream); } #else } return fwrite(ptr, size, count, stream); #endif } ssize_t ota_write(int fd, const void* buf, size_t nbyte) { #if defined (TARGET_WRITE_FAULT) if (FilenameCache.find(fd) != FilenameCache.end() && FilenameCache[fd] == FaultFileName) { FaultFileName = ""; 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; return -1; } else { return write(fd, buf, nbyte); } #else } return write(fd, buf, nbyte); #endif } int ota_fsync(int fd) { #if defined (TARGET_FSYNC_FAULT) if (FilenameCache.find(fd) != FilenameCache.end() && FilenameCache[fd] == FaultFileName) { FaultFileName = ""; 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; return -1; } else { return fsync(fd); } #else } return fsync(fd); #endif } Loading
applypatch/applypatch.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -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); Loading
otafault/Android.mk +14 −29 Original line number Diff line number Diff line # 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. Loading @@ -14,45 +14,30 @@ 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) LOCAL_SRC_FILES := ota_io.cpp otafault_static_libs := \ libminzip \ libz \ libselinux \ LOCAL_SRC_FILES := config.cpp ota_io.cpp LOCAL_MODULE_TAGS := eng LOCAL_MODULE := libotafault LOCAL_CLANG := true 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 LOCAL_C_INCLUDES := bootable/recovery LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) LOCAL_WHOLE_STATIC_LIBRARIES := $(otafault_static_libs) include $(BUILD_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_SRC_FILES := ota_io.cpp test.cpp LOCAL_SRC_FILES := config.cpp ota_io.cpp test.cpp LOCAL_MODULE_TAGS := tests LOCAL_MODULE := otafault_test LOCAL_STATIC_LIBRARIES := libc LOCAL_STATIC_LIBRARIES := $(otafault_static_libs) LOCAL_C_INCLUDES := bootable/recovery 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)
otafault/config.cpp 0 → 100644 +65 −0 Original line number Diff line number Diff line /* * 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); }
otafault/config.h 0 → 100644 +74 −0 Original line number Diff line number Diff line /* * 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
otafault/ota_io.cpp +76 −87 Original line number Diff line number Diff line Loading @@ -14,9 +14,7 @@ * limitations under the License. */ #if defined (TARGET_INJECT_FAULTS) #include <map> #endif #include <errno.h> #include <fcntl.h> Loading @@ -24,137 +22,128 @@ #include <sys/stat.h> #include <unistd.h> #include "config.h" #include "ota_io.h" #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) 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); } } 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); FilenameCache[fd] = path; filename_cache[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); FilenameCache[fd] = path; return fd; #else return open(path, oflags, mode); #endif } filename_cache[fd] = path; return fd; } FILE* ota_fopen(const char* path, const char* mode) { #if defined (TARGET_INJECT_FAULTS) FILE* fh = fopen(path, mode); FilenameCache[(intptr_t)fh] = path; filename_cache[(intptr_t)fh] = path; return fh; #else return fopen(path, mode); #endif } int ota_close(int fd) { #if defined (TARGET_INJECT_FAULTS) // descriptors can be reused, so make sure not to leave them in the cahce FilenameCache.erase(fd); #endif // descriptors can be reused, so make sure not to leave them in the cache filename_cache.erase(fd); return close(fd); } int ota_fclose(FILE* fh) { #if defined (TARGET_INJECT_FAULTS) FilenameCache.erase((intptr_t)fh); #endif filename_cache.erase((intptr_t)fh); return fclose(fh); } size_t ota_fread(void* ptr, size_t size, size_t nitems, FILE* stream) { #if defined (TARGET_READ_FAULT) if (FilenameCache.find((intptr_t)stream) != FilenameCache.end() && FilenameCache[(intptr_t)stream] == FaultFileName) { FaultFileName = ""; 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; return 0; } else { return fread(ptr, size, nitems, stream); } #else } return fread(ptr, size, nitems, stream); #endif } ssize_t ota_read(int fd, void* buf, size_t nbyte) { #if defined (TARGET_READ_FAULT) if (FilenameCache.find(fd) != FilenameCache.end() && FilenameCache[fd] == FaultFileName) { FaultFileName = ""; 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; return -1; } else { return read(fd, buf, nbyte); } #else } return read(fd, buf, nbyte); #endif } size_t ota_fwrite(const void* ptr, size_t size, size_t count, FILE* stream) { #if defined (TARGET_WRITE_FAULT) if (FilenameCache.find((intptr_t)stream) != FilenameCache.end() && FilenameCache[(intptr_t)stream] == FaultFileName) { FaultFileName = ""; 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; return 0; } else { return fwrite(ptr, size, count, stream); } #else } return fwrite(ptr, size, count, stream); #endif } ssize_t ota_write(int fd, const void* buf, size_t nbyte) { #if defined (TARGET_WRITE_FAULT) if (FilenameCache.find(fd) != FilenameCache.end() && FilenameCache[fd] == FaultFileName) { FaultFileName = ""; 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; return -1; } else { return write(fd, buf, nbyte); } #else } return write(fd, buf, nbyte); #endif } int ota_fsync(int fd) { #if defined (TARGET_FSYNC_FAULT) if (FilenameCache.find(fd) != FilenameCache.end() && FilenameCache[fd] == FaultFileName) { FaultFileName = ""; 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; return -1; } else { return fsync(fd); } #else } return fsync(fd); #endif }