diff options
-rw-r--r-- | src/libc-stdio.h | 72 | ||||
-rw-r--r-- | src/libc-verbose.h | 20 | ||||
-rw-r--r-- | src/libc.c | 13 |
3 files changed, 79 insertions, 26 deletions
diff --git a/src/libc-stdio.h b/src/libc-stdio.h new file mode 100644 index 0000000..7f09c74 --- /dev/null +++ b/src/libc-stdio.h @@ -0,0 +1,72 @@ +#pragma once + +struct bionic___sFILE { +#if defined(__LP64__) + char __private[152]; +#else + char __private[84]; +#endif +} __attribute__((aligned(sizeof(void*)))); + +// Bionic standard stream support pre-M Android +// Post-M it's saner and they point to stdin/stdout/stderr symbols instead +const struct bionic___sFILE bionic___sF[3] = { + {{ 's', 't', 'd', 'i', 'n' }}, + {{ 's', 't', 'd', 'o', 'u', 't' }}, + {{ 's', 't', 'd', 'e', 'r', 'r' }} +}; + +static inline FILE* +bionic_file_to_glibc_file(FILE *f) +{ + // Can't compare just memory addresses because GNU libstdc++ copies the FILE struct... + // Maybe there could be a cleaner solution, this may in practice break if standard streams + // are opened with different flags in C++. + if (memcmp(f, "stdin", sizeof("stdin"))) + return stdin; + else if (memcmp(f, "stdout", sizeof("stdout"))) + return stdout; + else if (memcmp(f, "stderr", sizeof("stderr"))) + return stderr; + return f; +} + +FILE* +bionic_freopen(const char *filename, const char *modes, FILE *stream) +{ + return freopen(filename, modes, bionic_file_to_glibc_file(stream)); +} + +int +bionic_fclose(FILE *stream) +{ + return fclose(bionic_file_to_glibc_file(stream)); +} + +size_t +bionic_fread(void *ptr, size_t size, size_t nmemb, FILE *stream) +{ + char buf[256], fname[256] = {0}; + stream = bionic_file_to_glibc_file(stream); + snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fileno(stream)); + readlink(buf, fname, sizeof(fname)); + verbose("%s (%d)\n%p, %zu, %zu, %p", fname, fileno(stream), ptr, size, nmemb, (void*)stream); + return fread(ptr, size, nmemb, stream); +} + +size_t +bionic_fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream) +{ + char buf[256], fname[256] = {0}; + stream = bionic_file_to_glibc_file(stream); + snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fileno(stream)); + readlink(buf, fname, sizeof(fname)); + verbose("%s (%d)\n%p, %zu, %zu, %p", fname, fileno(stream), ptr, size, nmemb, (void*)stream); + return fwrite(ptr, size, nmemb, stream); +} + +int +bionic_fflush(FILE *stream) +{ + return fflush(bionic_file_to_glibc_file(stream)); +} diff --git a/src/libc-verbose.h b/src/libc-verbose.h index 190f0b1..2d46f17 100644 --- a/src/libc-verbose.h +++ b/src/libc-verbose.h @@ -144,26 +144,6 @@ bionic_unlink(const char *path) return unlink(path); } -size_t -bionic_fread(void *ptr, size_t size, size_t nmemb, FILE *stream) -{ - char buf[256], fname[256] = {0}; - snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fileno(stream)); - readlink(buf, fname, sizeof(fname)); - verbose("%s (%d)\n%p, %zu, %zu, %p", fname, fileno(stream), ptr, size, nmemb, (void*)stream); - return fread(ptr, size, nmemb, stream); -} - -size_t -bionic_fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream) -{ - char buf[256], fname[256] = {0}; - snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fileno(stream)); - readlink(buf, fname, sizeof(fname)); - verbose("%s (%d)\n%p, %zu, %zu, %p", fname, fileno(stream), ptr, size, nmemb, (void*)stream); - return fwrite(ptr, size, nmemb, stream); -} - char* bionic_getenv(const char *name) { @@ -14,10 +14,6 @@ #include <netdb.h> // h_errno #include "wrapper/verbose.h" -#ifdef VERBOSE_FUNCTIONS -# include "libc-verbose.h" -#endif - struct bionic_dirent { uint64_t d_ino; int64_t d_off; @@ -74,9 +70,10 @@ tkill(int tid, int sig) // Stuff needed for runtime compatibility, but not neccessary for linking // Also stuff that exists in glibc, but needs to be wrapped for runtime compatibility +#include "libc-stdio.h" + const char *bionic__ctype_, *bionic__tolower_tab_, *bionic__toupper_tab_; -char bionic___sF[0x54] = {0}; -unsigned int bionic___page_size = PAGE_SIZE; +const unsigned int bionic___page_size = PAGE_SIZE; __attribute_const__ int* @@ -378,3 +375,7 @@ bionic___futex_wake(volatile void* ftx, int count) return syscall(SYS_futex, ftx, FUTEX_WAKE, count, NULL, 0); } #endif + +#ifdef VERBOSE_FUNCTIONS +# include "libc-verbose.h" +#endif |