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.
This commit is contained in:
Po Lu 2023-08-06 21:45:29 +08:00
parent 669a4b96c3
commit 7873369338
4 changed files with 57 additions and 1 deletions

View 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.

View file

@ -274,6 +274,10 @@ public static native void blitRect (Bitmap src, Bitmap dest, int x1,
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

View file

@ -24,6 +24,7 @@
import java.util.Iterator;
import java.io.FileNotFoundException;
import java.io.IOException;
import android.content.ContentResolver;
import android.database.Cursor;
@ -1597,6 +1598,42 @@ In addition, arbitrary runtime exceptions (such as
= 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);

View 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 */