Fetch icon indicating copy to clipboard operation
Fetch copied to clipboard

EBADF (Bad file descriptor)

Open andj207 opened this issue 4 years ago • 6 comments

Download video mp4 file throw Bad file description on my Realme C1 and Xperia Z1 with release build, work well with debug build.

Android 9 The video url is: https://v.pinimg.com/videos/mc/720p/29/8b/e4/298be43b0ab83f7608767ae5bc767071.mp4 The file uri to save (permission has been granted): content://com.android.providers.downloads.documents/tree/raw%3A%2Fstorage%2Femulated%2F0%2FDownload%2FMusic/document/raw%3A%2Fstorage%2Femulated%2F0%2FDownload%2FMusic%2F298be43b0ab83f7608767ae5bc767071.mp4

Here is the exception log:

libcore.io.Linux.writeBytes (Linux.java)
libcore.io.Linux.write (Linux.java:288)
libcore.io.BlockGuardOs.write (BlockGuardOs.java:348)
libcore.io.IoBridge.write (IoBridge.java:526)
java.io.FileOutputStream.write (FileOutputStream.java:381)
com.tonyodev.fetch2core.StorageResolverHelper$getOutputResourceWrapper$1.write (StorageResolverHelper.java:37)
com.tonyodev.fetch2.downloader.SequentialFileDownloaderImpl.writeToOutput (SequentialFileDownloaderImpl.java:232)
com.tonyodev.fetch2.downloader.SequentialFileDownloaderImpl.run (SequentialFileDownloaderImpl.java:124)
com.tonyodev.fetch2.downloader.DownloadManagerImpl$start$$inlined$synchronized$lambda$1.run.     (DownloadManagerImpl.java:103)
java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1167)
java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:641)
java.lang.Thread.run (Thread.java:764)

andj207 avatar Jun 24 '21 07:06 andj207

When I set minifyEnabled false and shrinkResources false in release build, it works well. If I turn those things on, I set proguard as following, it still not works, the error Bad file descriptor is still there.

-keep class com.tonyodev.fetch2.** { *; }
-keep class com.squareup.okhttp3.** { *; }

andj207 avatar Jun 25 '21 03:06 andj207

It's all about the contentResolver.openFileDescriptor(fileUri, "w") in the class StorageResolverHelper.kt. When using with Storage Access Framework the file path is a Document uri, if the download is paused and then resumed, the file will be cleared to 0 byte and continued append the new bytes on Android version <= 9 (Realme C1 and Xperia Z1).

The fix is: contentResolver.openFileDescriptor(fileUri, "rw") Everything works well again. It took me a month to find this problem :))

andj207 avatar Jul 28 '21 07:07 andj207

Thanks @andj207, your patch https://github.com/andj207/Fetch/commit/49ca46e10d548f1bd7a94ba2cf4fef7ff5b233f7 fixes file corruption issues some of my users were facing (xperia, asus phones). I couldn't reproduce the bug myself but after testing the patch with affected users, they reported file corruptions have stopped.

/cc @tonyofrancis

alashow avatar Aug 16 '21 09:08 alashow

I have the same issue on a Pocophone F1 with Android 11 and several other device/sdk combinations. I traced the issue down to the minifyEnabled true setting in debug builds.

I think I fixed it by adding following progruard rules:

-keep class com.tonyodev.fetch2.** { *; }
-keep class com.tonyodev.fetch2core.** { *; }

I would like them to be more specific, but at least it is working now.

cemrich avatar Oct 14 '21 12:10 cemrich

Also, this may be a diplicate of #454 where I got the proguard rules from.

cemrich avatar Oct 14 '21 12:10 cemrich

Proguard rules alone didn't fix the problem in my case.

alashow avatar Oct 15 '21 00:10 alashow