| 1 | diff --git a/std/stdio.d b/std/stdio.d |
| 2 | index 0c315026..8b1860d0 100644 |
| 3 | --- a/std/stdio.d |
| 4 | +++ b/runtime/phobos/std/stdio.d |
| 5 | @@ -310,6 +310,45 @@ else version (GENERIC_IO) |
| 6 | void funlockfile(FILE*); |
| 7 | } |
| 8 | |
| 9 | + version(CRuntime_Bionic) |
| 10 | + { |
| 11 | + import core.stdc.wchar_ : mbstate_t; |
| 12 | + import core.sys.posix.sys.types : pthread_mutex_t; |
| 13 | + |
| 14 | + extern(C) struct wchar_io_data |
| 15 | + { |
| 16 | + mbstate_t wcio_mbstate_in; |
| 17 | + mbstate_t wcio_mbstate_out; |
| 18 | + wchar_t[1] wcio_ungetwc_buf; |
| 19 | + size_t wcio_ungetwc_inbuf; |
| 20 | + int wcio_mode; |
| 21 | + } |
| 22 | + |
| 23 | + extern(C) struct __sfileext |
| 24 | + { |
| 25 | + __sbuf _ub; |
| 26 | + wchar_io_data _wcio; |
| 27 | + pthread_mutex_t _lock; |
| 28 | + } |
| 29 | + |
| 30 | + void bionic_lock(FILE* foo) |
| 31 | + { |
| 32 | + if( foo == stdout._p.handle || foo == stdin._p.handle || foo == stderr._p.handle) |
| 33 | + { |
| 34 | + auto ext = cast(__sfileext*) foo._ext._base; |
| 35 | + if (ext._lock.value == 0) |
| 36 | + { |
| 37 | + // A bionic regression in Android 5.0 leaves |
| 38 | + // the mutex for stdout/err/in uninitialized, |
| 39 | + // so check for that and initialize it. |
| 40 | + printf("lock is zero, initializing...\n"); |
| 41 | + ext._lock.value = 0x4000; |
| 42 | + } |
| 43 | + } |
| 44 | + flockfile(foo); |
| 45 | + } |
| 46 | + } |
| 47 | + |
| 48 | int fputc_unlocked(int c, _iobuf* fp) { return fputc(c, cast(shared) fp); } |
| 49 | int fputwc_unlocked(wchar_t c, _iobuf* fp) |
| 50 | { |
| 51 | @@ -328,7 +367,10 @@ else version (GENERIC_IO) |
| 52 | alias FGETC = fgetc_unlocked; |
| 53 | alias FGETWC = fgetwc_unlocked; |
| 54 | |
| 55 | - alias FLOCK = flockfile; |
| 56 | + version(CRuntime_Bionic) |
| 57 | + alias FLOCK = bionic_lock; |
| 58 | + else |
| 59 | + alias FLOCK = flockfile; |
| 60 | alias FUNLOCK = funlockfile; |
| 61 | } |
| 62 | else |