summaryrefslogtreecommitdiff
path: root/src/libc-stdio.h
blob: 9dacd217284d17efdcf085db1103d0ff591d42a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#pragma once

#include <wchar.h>

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)
{
   if (f == (void*)&bionic___sF[0])
      return stdin;
   else if (f == (void*)&bionic___sF[1])
      return stdout;
   else if (f == (void*)&bionic___sF[2])
      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));
}

int
bionic_fputc(int c, FILE *stream)
{
   return fputc(c, bionic_file_to_glibc_file(stream));
}

int
bionic_putc(int c, FILE *stream)
{
   return putc(c, bionic_file_to_glibc_file(stream));
}


int
bionic_fputs(const char *c, FILE *stream)
{
   return fputs(c, bionic_file_to_glibc_file(stream));
}

wint_t
bionic_fputwc(wchar_t wc, FILE *stream)
{
   return fputwc(wc, bionic_file_to_glibc_file(stream));
}

wint_t
bionic_putwc(wchar_t wc, FILE *stream)
{
   return putwc(wc, 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));
}