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.
import java.util.Iterator;
import java.io.FileNotFoundException;
+import java.io.IOException;
import android.content.ContentResolver;
import android.database.Cursor;
= 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);
/* 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
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 */