unzOpen's fopen returns NULL and gives errno 24, EMFILE too many open files

Using Cocos2d-X 2.1.0 on an Android device with API 8, I’m getting errno 24 “too many open files” from fopen. The call path to get to fopen goes:

ZipFile::ZipFile
unzOpen
unzOpenInternal (with is64bitOpenFunction == 0)
ZOPEN64 / call_zopen64
fopen64_file_func (ioapi.cpp)
fopen64 (aka fopen)

I tried making sure that USE_FILE32API was defined, but it already was. It definitely seems to be calling the 32 bit version of fopen.

The device I am running on is a Samsung Galaxy S. It has always ran Cocos2dx apps fine in the past. The last version I tried was 2.0.3 and it never gave me this error.

I know that the zip file functionality was updated in Cocos2dx 2.1.0. Is it possible that something is broken?

Does anyone know how to fix this or a possible workaround?

I found version 2.1 is not stable!

I got it to work on a different machine with an older Android SDK install, but it still doesn’t work on the machine with the latest Android SDK.

Working:
Mac OS X 10.6.8 (Snow Leopard)
Android SDK APIs: 4.2, 2.2
Android SDK Tools: rev 20
Android SDK Platform tools: rev 12
NDK: Crystax r7

NOT working:
Max OS X 10.7.5 (Lion)
Android SDK APIs: 4.2, 2.2
Android SDK Tools: rev 21.0.1
Android SDK Platform tools: rev 16.0.1
NDK: Crystax r7

Here’s an easy way to confirm the problem. Create a new android project with create-android-project.sh using API 8. Then edit it’s jni/hellocpp/main.cpp to test fopen.

Add these includes:

#include
#include

And add this to JNI_OnLoad:

FILE* file = fopen(“/data/app/com.yourcompany.yourapp-1.apk”, “rb”);
LOGD (“cocos2d: fopen == %d, errno %d (%s)”, file, errno, strerror(errno));

This gives me the following error when I run it on the device:

cocos2d: fopen == 0, errno 24 (Too many open files)

BTW, I’m using this command to build the APK:

ant Dsdk.dir=/Users/nat/code/android/sdk debug
And this to run it:
adb
d install bin/HelloCpp-debug.apk && adb -d logcat | grep cocos2d

I think maybe it’s caused by crystax mod….

颖玉 邓 wrote:

I think maybe it’s caused by crystax mod….

confirmed:
when i compile a project with ndk-r7-crystax-5-beta3, it saied that : Get data from file(*) failed!
but before that, it’s complied by ndk-r8c-orign. no any error popuped.

and more:
my another project use some feature from C++11. I can’t complie it without crystax mod.
first, i solved assets reading problem by using AssetManager api coming after API LEVEL 9.
But I can’t solve another problem, that is network with socket system call.
When I called socket( …… ), returned a –1 and errno is EMFILE, just like unzOpen does.

I’ve spent a long time for this, but i can’t solve it by now.

ok i solved this.
You can use NDK r8 from google instead of NDK from CrystaX.

And for CPP0X, just add ‘~~fexceptions’ and ’~~std=c++11’ after ‘-frtti’ in Application.mk.

And there is some functions that r8 doesn’t provide, such as wcsncmp, wcsnicmp and wcstoll/ull, you can add them manually.

After these, NDK r8 worked.

And no more EMFILE or unzOpen return NULL.