emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/android 7873369338e 1/2: Update Android port


From: Po Lu
Subject: feature/android 7873369338e 1/2: Update Android port
Date: Sun, 6 Aug 2023 09:46:17 -0400 (EDT)

branch: feature/android
commit 7873369338ee0159ca285153fd4592cbcff65d7a
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    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.
---
 ChangeLog.android                      |  9 +++++++++
 java/org/gnu/emacs/EmacsNative.java    |  4 ++++
 java/org/gnu/emacs/EmacsSafThread.java | 37 ++++++++++++++++++++++++++++++++++
 src/androidvfs.c                       |  8 +++++++-
 4 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/ChangeLog.android b/ChangeLog.android
index 689482d2f1a..82ab75b40c1 100644
--- a/ChangeLog.android
+++ b/ChangeLog.android
@@ -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.
 
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);
diff --git a/src/androidvfs.c b/src/androidvfs.c
index dc5097f463e..d6daff481b0 100644
--- a/src/androidvfs.c
+++ b/src/androidvfs.c
@@ -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 */



reply via email to

[Prev in Thread] Current Thread [Next in Thread]