From 7873369338ee0159ca285153fd4592cbcff65d7a Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 6 Aug 2023 21:45:29 +0800 Subject: Update Android port * java/org/gnu/emacs/EmacsNative.java: Declare ftruncate. * java/org/gnu/emacs/EmacsSafThread.java (openDocument1): If initially opening with rwt, verify the file descriptor is really writable; if not, resort to rw and truncating the file descriptor by hand instead. * src/androidvfs.c (NATIVE_NAME (ftruncate)): New function. Truncate file descriptor and return whether that was successful. --- java/org/gnu/emacs/EmacsNative.java | 4 ++++ java/org/gnu/emacs/EmacsSafThread.java | 37 ++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) (limited to 'java') diff --git a/java/org/gnu/emacs/EmacsNative.java b/java/org/gnu/emacs/EmacsNative.java index 7d72a9f192e..fae0ba98f86 100644 --- a/java/org/gnu/emacs/EmacsNative.java +++ b/java/org/gnu/emacs/EmacsNative.java @@ -274,6 +274,10 @@ public final class EmacsNative operations. */ public static native void safPostRequest (); + /* Detect and return FD is writable. FD may be truncated to 0 bytes + in the process. */ + public static native boolean ftruncate (int fd); + static { /* Older versions of Android cannot link correctly with shared diff --git a/java/org/gnu/emacs/EmacsSafThread.java b/java/org/gnu/emacs/EmacsSafThread.java index 29cd3fa6bc7..3ae3c0839ce 100644 --- a/java/org/gnu/emacs/EmacsSafThread.java +++ b/java/org/gnu/emacs/EmacsSafThread.java @@ -24,6 +24,7 @@ import java.util.HashMap; import java.util.Iterator; import java.io.FileNotFoundException; +import java.io.IOException; import android.content.ContentResolver; import android.database.Cursor; @@ -1597,6 +1598,42 @@ public final class EmacsSafThread extends HandlerThread = resolver.openFileDescriptor (documentUri, mode, signal); + /* If a writable file descriptor is requested and TRUNCATE is set, + then probe the file descriptor to detect if it is actually + readable. If not, close this file descriptor and reopen it + with MODE set to rw; some document providers granting access to + Samba shares don't implement rwt, but these document providers + invariably truncate the file opened even when the mode is + merely rw. + + This may be ascribed to a mix-up in Android's documentation + regardin DocumentsProvider: the `openDocument' function is only + documented to accept r or rw, whereas the default + implementation of the `openFile' function (which documents rwt) + delegates to `openDocument'. */ + + if (write && truncate && fileDescriptor != null + && !EmacsNative.ftruncate (fileDescriptor.getFd ())) + { + try + { + fileDescriptor.closeWithError ("File descriptor requested" + + " is not writable"); + } + catch (IOException e) + { + Log.w (TAG, "Leaking unclosed file descriptor " + e); + } + + fileDescriptor + = resolver.openFileDescriptor (documentUri, "rw", signal); + + /* Try to truncate fileDescriptor just to stay on the safe + side. */ + if (fileDescriptor != null) + EmacsNative.ftruncate (fileDescriptor.getFd ()); + } + /* Every time a document is opened, remove it from the file status cache. */ toplevel = getCache (treeUri); -- cgit v1.2.1