{"record":{"id":"cca3466312d820c8","repo":"MuntashirAkon/AppManager","slug":"enosys","errorCode":"ENOSYS","errorMessage":"splice","messagePattern":"splice","errorType":"error_code","errorClass":"ErrnoException","httpStatus":null,"severity":"error","filePath":"libcore/io/src/main/java/io/github/muntashirakon/io/FileUtils.java","lineNumber":154,"sourceCode":"    }\n\n    @RequiresApi(api = 28)\n    static long splice(\n            FileDescriptor fdIn, Int64Ref offIn,\n            FileDescriptor fdOut, Int64Ref offOut,\n            long len, int flags) throws ErrnoException {\n        try {\n            if (splice == null) {\n                splice = Os.class.getMethod(\"splice\",\n                        FileDescriptor.class, Int64Ref.class,\n                        FileDescriptor.class, Int64Ref.class,\n                        long.class, int.class);\n            }\n            return (long) splice.invoke(null, fdIn, offIn, fdOut, offOut, len, flags);\n        } catch (InvocationTargetException e) {\n            throw (ErrnoException) e.getTargetException();\n        } catch (ReflectiveOperationException e) {\n            throw new ErrnoException(\"splice\", ENOSYS);\n        }\n    }\n\n    @SuppressWarnings(\"deprecation\")\n    @SuppressLint(\"NewApi\")\n    static long sendfile(\n            FileDescriptor outFd, FileDescriptor inFd,\n            MutableLong inOffset, long byteCount) throws ErrnoException {\n        if (Build.VERSION.SDK_INT >= 28) {\n            Int64Ref off = inOffset == null ? null : new Int64Ref(inOffset.value);\n            long result = Os.sendfile(outFd, inFd, off, byteCount);\n            if (off != null)\n                inOffset.value = off.value;\n            return result;\n        } else {\n            try {\n                if (os == null) {\n                    os = Class.forName(\"libcore.io.Libcore\").getField(\"os\").get(null);","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/libcore/io/src/main/java/io/github/muntashirakon/io/FileUtils.java#L136-L172","documentation":"FileUtils.splice() invokes Os.splice() reflectively (required for API 28+). If the reflective lookup of the method or its invocation fails with ReflectiveOperationException, the method throws ErrnoException(\"splice\", ENOSYS) — 'function not implemented'. This translates a reflection/environment problem into an errno so callers can fall back to a non-splice path.","triggerScenarios":"Calling splice-based I/O (e.g. OpenFile.pread/read on API >= 28 paths that use FileUtils.splice) on a device/VM where Os.splice cannot be resolved reflectively or the invocation fails reflectively; custom ROMs or stripped frameworks missing the method; InvocationTargetException thrown from splice itself is rethrown as-is, so ENOSYS only comes from reflection failures.","commonSituations":"Running on emulators or modified Android builds lacking Os.splice; proguard/R8 renaming interfering with reflection when subclassing; testing splice paths on API < 28 without guards.","solutions":["Update the OS/ROM or test on a device with API >= 28 and an unmodified framework","Catch ErrnoException with errno == ENOSYS and fall back to the read/write loop path (the library's FORCE_NO_SPLICE fallback pattern)","Set the library's no-splice option (e.g. FORCE_NO_SPLICE) to bypass splice entirely"],"exampleFix":"// before\nlong n = FileUtils.splice(fdIn, offIn, fdOut, offOut, len, 0);\n// after\ntry {\n    n = FileUtils.splice(fdIn, offIn, fdOut, offOut, len, 0);\n} catch (ErrnoException e) {\n    if (e.errno == OsConstants.ENOSYS) {\n        n = fallbackCopy(fdIn, offIn, fdOut, offOut, len); // manual read/write loop\n    } else throw e;\n}","handlingStrategy":"fallback","validationCode":"if (Build.VERSION.SDK_INT < 28) { /* skip splice path */ }","typeGuard":null,"tryCatchPattern":"try { long n = FileUtils.splice(fdIn, offIn, fdOut, offOut, len, 0); } catch (ErrnoException e) { if (e.errno == OsConstants.ENOSYS) { /* manual copy fallback */ } else throw e; }","preventionTips":["Prefer the library's high-level APIs that already implement the FORCE_NO_SPLICE fallback","Test on real production devices/ROMs, not only stock emulators","Keep the library updated for hidden-API restriction workarounds"],"tags":["android","io","splice","enosys","reflection"],"backgroundTag":"unsupported-platform","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}