fclose works differently on android and linux

android, android-ndk, fclose, freopen, linux

Solution

It doesn’t make any sense to try to use stderr after closing it, on any platform.

Problem

Following program: ``` #include <stdlib.h> #include <stdio.h> #include <sys/stat.h> #include <sys/types.h> int main() { fclose( stderr ); printf( "%d\n", fileno( stderr ) ); return 0; } ``` shows `-1` on ubuntu 11.04 and `2` on ICS 4.0.3 emulator. Can't find any info about this issue - can i make this code work similar on both platforms? `freopen` on `stderr` has same problem. Update: Previous small program demonstrates the cause of actual problem i faced with: if i try to `freopen` `stderr` to file in inexistent directory, on linux `stderr` is closed but on android it stays opened! And even more - if i write smth in this opened `stderr` file and then do `fopen` on some other file, text i printed to `stderr` is written to this opened file. So, this program: ``` #include <stdlib.h> #include <stdio.h> #include <sys/stat.h> #include <sys/types.h> # define LOGD( ... ) printf( __VA_ARGS__ ); printf( "\n" ) # ifdef ANDROID # define HOMEDIR "/data/data/com.myapp/" // for android # else # define HOMEDIR "/home/darkmist/" // for linux # endif # define _T( x ) x void TestFreopen_mkdir() { int mkdirres = mkdir( HOMEDIR "1.d", 0777 ); LOGD(_T("TestFreopen mkdirres=0x%08x"),mkdirres); } void TestFreopen() { LOGD(_T("TestFreopen begin")); LOGD(_T("TestFreopen stderr=0x%08x"),fileno(stderr)); fprintf(stderr,"fprintf_1 to stderr\n"); // TestFreopen_mkdir(); // case 1 if ( NULL == freopen( HOMEDIR "1.d/1", "w", stderr ) ) { LOGD( "freopen failed" ); if ( -1 != fileno( stderr ) ) { fclose( stderr ); LOGD( "freopen closed" ); } } LOGD(_T("TestFreopen stderr=0x%08x"),fileno(stderr)); fprintf(stderr,"fprintf_2 to stderr\n"); TestFreopen_mkdir(); // case 2 FILE* fopen_file = fopen( HOMEDIR "1.d/2", _T( "wb" ) ); LOGD(_T("TestFreopen fopen_file=0x%08x"),fileno(fopen_file)); // same as for reopened stderr!! fprintf(stderr,"fprintf_3 to stderr\n"); fprintf(fopen_file,"fprintf_1 to fopen_file\n"); fflush(fopen_file); LOGD(_T("TestFreopen end")); } int main() { TestFreopen(); return 0; } ``` shows this on linux: ``` $ ./a.out TestFreopen begin TestFreopen stderr=0x00000002 fprintf_1 to stderr freopen failed TestFreopen stderr=0xffffffff TestFreopen mkdirres=0x00000000 TestFreopen fopen_file=0x00000002 TestFreopen end $ cat ~/1.d/2 fprintf_1 to fopen_file ``` and this on android: ``` $ adb push ./a.out /data/data/com.myapp 573 KB/s (34635 bytes in 0.058s) $ adb shell run-as com.myapp /data/data/com.myapp/a.out TestFreopen begin TestFreopen stderr=0x00000002 fprintf_1 to stderr freopen failed freopen closed TestFreopen stderr=0x00000002 TestFreopen mkdirres=0x00000000 TestFreopen fopen_file=0x00000002 TestFreopen end $ adb shell run-as com.myapp cat /data/data/com.myapp/1.d/2 fprintf_3 to stderr fprintf_1 to fopen_file ```

Original source