Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fclose works differently on android and linux

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
like image 801
Andrey Starodubtsev Avatar asked May 30 '12 13:05

Andrey Starodubtsev


People also ask

What is the difference between open and fopen in Linux?

The key difference between the fopen() and the open() function in the Linux operating system is that the open() function is a low-level call, where the fopen() when called simply calls the open() function in the background and it returns a Filepointer directly.

What happens if don't Fclose?

fclose() closes the associated file. If function fclose() is not called explicitly, the operating system normally will close the file when program execution terminates. However, if the file is being used for output, some data may still be buffered and not physically written to the output file.

Does Fclose free the pointer?

A pointer to a closed file cannot be used as an input value to the freopen() function. Notes: The storage pointed to by the FILE pointer is freed by the fclose() function.

What does fopen do in Linux?

The fopen() function opens the file whose name is the string pointed to by pathname and associates a stream with it. The argument mode points to a string beginning with one of the following sequences (possibly followed by additional characters, as described below): r Open text file for reading.


1 Answers

It seems to me that you are expecting what is formally declared to be undefined behavior of a file pointer subsequent to its closing to be the same on devices which have very different C libraries.

Once you call freopen() in a way that is designed to fail, future attempts to use that file pointer are not something you can depend on having a consistent outcome.

You have found some interesting results whereby left over pieces can still be used with unexpected outcome, but the problem is not that they don't cause some sort of exception, the problem is that you are attempting to use an invalid file pointer in a language that does not advertise itself as having safeguards.

The problem is not with the system, but rather with your program's misuse of the system.

like image 143
Chris Stratton Avatar answered Oct 03 '22 07:10

Chris Stratton