]> git.eshelyaron.com Git - emacs.git/commitdiff
Update Android port
authorPo Lu <luangruo@yahoo.com>
Sun, 6 Aug 2023 13:45:29 +0000 (21:45 +0800)
committerPo Lu <luangruo@yahoo.com>
Sun, 6 Aug 2023 13:45:29 +0000 (21:45 +0800)
* 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.

ChangeLog.android
java/org/gnu/emacs/EmacsNative.java
java/org/gnu/emacs/EmacsSafThread.java
src/androidvfs.c

index 689482d2f1ada0dd1b8fe9c1ed784d0cd713d45c..82ab75b40c1b60be54714c60712eb7e9bbdd19e2 100644 (file)
@@ -1,11 +1,20 @@
 2023-08-06  Po Lu  <luangruo@yahoo.com>
 
+       * 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.
+
        * src/androidvfs.c (android_saf_tree_chmod): Repair file access
        permissions allowed within FLAGS.
 
 2023-08-05  Po Lu  <luangruo@yahoo.com>
 
        * doc/lispref/commands.texi (Touchscreen Events): Fix typo.
+
        * lisp/subr.el (y-or-n-p): Don't call set-text-conversion-style
        when not present.
 
index 7d72a9f192edbe6da22f431e4abbb778653ac422..fae0ba98f86bf0022384939aa4501f3771e4942b 100644 (file)
@@ -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
index 29cd3fa6bc72284f16423b9771ff174cdcc445e4..3ae3c0839ce79b66ae02737bf3c42b0c07eb8045 100644 (file)
@@ -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);
index dc5097f463e5741569201ccd53796b36e47750c4..d6daff481b032178ba184d4dabcc6ca7e014a3a1 100644 (file)
@@ -5605,7 +5605,7 @@ android_saf_file_open (struct android_vnode *vnode, int flags,
   /* Open a parcel file descriptor according to flags.  */
 
   method = service_class.open_document;
-  trunc  = flags & O_TRUNC;
+  trunc  = (flags & O_TRUNC);
   write  = ((flags & O_RDWR) == O_RDWR || (flags & O_WRONLY));
   inside_saf_critical_section = true;
   descriptor
@@ -6121,6 +6121,12 @@ NATIVE_NAME (safPostRequest) (JNIEnv *env, jobject object)
   sem_post (&saf_completion_sem);
 }
 
+JNIEXPORT jboolean JNICALL
+NATIVE_NAME (ftruncate) (JNIEnv *env, jobject object, jint fd)
+{
+  return ftruncate (fd, 0) != -1;
+}
+
 #ifdef __clang__
 #pragma clang diagnostic pop
 #else /* GNUC */