Fix earlier change to content URI resolution on Android
* java/org/gnu/emacs/EmacsService.java (openContentUri): Return -1 if fd be NULL. * src/androidvfs.c (android_authority_open): Detect SecurityException and suchlike. (android_vfs_init): Initialize exception classes on Android 4.4.
This commit is contained in:
parent
d335f28aa9
commit
c900c707e8
2 changed files with 116 additions and 110 deletions
|
@ -968,7 +968,7 @@ invocation of app_process (through android-emacs) can
|
|||
string; make it writable if WRITABLE, and readable if READABLE.
|
||||
Truncate the file if TRUNCATE.
|
||||
|
||||
Value is the resulting file descriptor or an exception will be
|
||||
Value is the resulting file descriptor, -1, or an exception will be
|
||||
raised. */
|
||||
|
||||
public int
|
||||
|
@ -999,6 +999,9 @@ invocation of app_process (through android-emacs) can
|
|||
minimum requirement for access to /content/by-authority. */
|
||||
|
||||
fd = resolver.openFileDescriptor (Uri.parse (uri), mode);
|
||||
if (fd == null)
|
||||
return -1;
|
||||
|
||||
i = fd.detachFd ();
|
||||
fd.close ();
|
||||
|
||||
|
|
221
src/androidvfs.c
221
src/androidvfs.c
|
@ -3023,6 +3023,104 @@ android_check_content_access (const char *uri, int mode)
|
|||
|
||||
|
||||
|
||||
/* Functions shared by authority and SAF nodes. */
|
||||
|
||||
/* Check for JNI exceptions, clear them, and set errno accordingly.
|
||||
Also, free each of the N local references given as arguments if an
|
||||
exception takes place.
|
||||
|
||||
Value is 1 if an exception has taken place, 0 otherwise.
|
||||
|
||||
If the exception thrown derives from FileNotFoundException, set
|
||||
errno to ENOENT.
|
||||
|
||||
If the exception thrown derives from SecurityException, set errno
|
||||
to EACCES.
|
||||
|
||||
If the exception thrown derives from OperationCanceledException,
|
||||
set errno to EINTR.
|
||||
|
||||
If the exception thrown derives from UnsupportedOperationException,
|
||||
set errno to ENOSYS.
|
||||
|
||||
If the exception thrown derives from OutOfMemoryException, call
|
||||
`memory_full'.
|
||||
|
||||
If the exception thrown is anything else, set errno to EIO. */
|
||||
|
||||
static int
|
||||
android_saf_exception_check (int n, ...)
|
||||
{
|
||||
jthrowable exception;
|
||||
JNIEnv *env;
|
||||
va_list ap;
|
||||
int new_errno;
|
||||
|
||||
env = android_java_env;
|
||||
va_start (ap, n);
|
||||
|
||||
/* First, check for an exception. */
|
||||
|
||||
if (!(*env)->ExceptionCheck (env))
|
||||
{
|
||||
/* No exception has taken place. Return 0. */
|
||||
va_end (ap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Print the exception. */
|
||||
(*env)->ExceptionDescribe (env);
|
||||
|
||||
exception = (*env)->ExceptionOccurred (env);
|
||||
|
||||
if (!exception)
|
||||
/* JNI couldn't return a local reference to the exception. */
|
||||
memory_full (0);
|
||||
|
||||
/* Clear the exception, making it safe to subsequently call other
|
||||
JNI functions. */
|
||||
(*env)->ExceptionClear (env);
|
||||
|
||||
/* Delete each of the N arguments. */
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
ANDROID_DELETE_LOCAL_REF (va_arg (ap, jobject));
|
||||
n--;
|
||||
}
|
||||
|
||||
/* Now set errno or signal memory_full as required. */
|
||||
|
||||
if ((*env)->IsInstanceOf (env, (jobject) exception,
|
||||
file_not_found_exception))
|
||||
new_errno = ENOENT;
|
||||
else if ((*env)->IsInstanceOf (env, (jobject) exception,
|
||||
security_exception))
|
||||
new_errno = EACCES;
|
||||
else if ((*env)->IsInstanceOf (env, (jobject) exception,
|
||||
operation_canceled_exception))
|
||||
new_errno = EINTR;
|
||||
else if ((*env)->IsInstanceOf (env, (jobject) exception,
|
||||
unsupported_operation_exception))
|
||||
new_errno = ENOSYS;
|
||||
else if ((*env)->IsInstanceOf (env, (jobject) exception,
|
||||
out_of_memory_error))
|
||||
{
|
||||
ANDROID_DELETE_LOCAL_REF ((jobject) exception);
|
||||
memory_full (0);
|
||||
}
|
||||
else
|
||||
new_errno = EIO;
|
||||
|
||||
/* expression is still a local reference! */
|
||||
ANDROID_DELETE_LOCAL_REF ((jobject) exception);
|
||||
errno = new_errno;
|
||||
va_end (ap);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Content authority-based vnode implementation.
|
||||
|
||||
/content/by-authority is a simple vnode implementation that converts
|
||||
|
@ -3201,7 +3299,9 @@ android_authority_open (struct android_vnode *vnode, int flags,
|
|||
(jboolean) !(mode & O_WRONLY),
|
||||
(jboolean) ((mode & O_TRUNC)
|
||||
!= 0));
|
||||
android_exception_check_1 (string);
|
||||
if (android_saf_exception_check (1, string))
|
||||
return -1;
|
||||
ANDROID_DELETE_LOCAL_REF (string);
|
||||
|
||||
/* If fd is -1, just assume that the file does not exist,
|
||||
and return -1 with errno set to ENOENT. */
|
||||
|
@ -3209,18 +3309,12 @@ android_authority_open (struct android_vnode *vnode, int flags,
|
|||
if (fd == -1)
|
||||
{
|
||||
errno = ENOENT;
|
||||
goto skip;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mode & O_CLOEXEC)
|
||||
android_close_on_exec (fd);
|
||||
|
||||
skip:
|
||||
ANDROID_DELETE_LOCAL_REF (string);
|
||||
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
|
||||
*fd_return = fd;
|
||||
return 0;
|
||||
}
|
||||
|
@ -4089,100 +4183,6 @@ android_saf_root_get_directory (int dirfd)
|
|||
thread. */
|
||||
static bool inside_saf_critical_section;
|
||||
|
||||
/* Check for JNI exceptions, clear them, and set errno accordingly.
|
||||
Also, free each of the N local references given as arguments if an
|
||||
exception takes place.
|
||||
|
||||
Value is 1 if an exception has taken place, 0 otherwise.
|
||||
|
||||
If the exception thrown derives from FileNotFoundException, set
|
||||
errno to ENOENT.
|
||||
|
||||
If the exception thrown derives from SecurityException, set errno
|
||||
to EACCES.
|
||||
|
||||
If the exception thrown derives from OperationCanceledException,
|
||||
set errno to EINTR.
|
||||
|
||||
If the exception thrown derives from UnsupportedOperationException,
|
||||
set errno to ENOSYS.
|
||||
|
||||
If the exception thrown derives from OutOfMemoryException, call
|
||||
`memory_full'.
|
||||
|
||||
If the exception thrown is anything else, set errno to EIO. */
|
||||
|
||||
static int
|
||||
android_saf_exception_check (int n, ...)
|
||||
{
|
||||
jthrowable exception;
|
||||
JNIEnv *env;
|
||||
va_list ap;
|
||||
int new_errno;
|
||||
|
||||
env = android_java_env;
|
||||
va_start (ap, n);
|
||||
|
||||
/* First, check for an exception. */
|
||||
|
||||
if (!(*env)->ExceptionCheck (env))
|
||||
{
|
||||
/* No exception has taken place. Return 0. */
|
||||
va_end (ap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Print the exception. */
|
||||
(*env)->ExceptionDescribe (env);
|
||||
|
||||
exception = (*env)->ExceptionOccurred (env);
|
||||
|
||||
if (!exception)
|
||||
/* JNI couldn't return a local reference to the exception. */
|
||||
memory_full (0);
|
||||
|
||||
/* Clear the exception, making it safe to subsequently call other
|
||||
JNI functions. */
|
||||
(*env)->ExceptionClear (env);
|
||||
|
||||
/* Delete each of the N arguments. */
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
ANDROID_DELETE_LOCAL_REF (va_arg (ap, jobject));
|
||||
n--;
|
||||
}
|
||||
|
||||
/* Now set errno or signal memory_full as required. */
|
||||
|
||||
if ((*env)->IsInstanceOf (env, (jobject) exception,
|
||||
file_not_found_exception))
|
||||
new_errno = ENOENT;
|
||||
else if ((*env)->IsInstanceOf (env, (jobject) exception,
|
||||
security_exception))
|
||||
new_errno = EACCES;
|
||||
else if ((*env)->IsInstanceOf (env, (jobject) exception,
|
||||
operation_canceled_exception))
|
||||
new_errno = EINTR;
|
||||
else if ((*env)->IsInstanceOf (env, (jobject) exception,
|
||||
unsupported_operation_exception))
|
||||
new_errno = ENOSYS;
|
||||
else if ((*env)->IsInstanceOf (env, (jobject) exception,
|
||||
out_of_memory_error))
|
||||
{
|
||||
ANDROID_DELETE_LOCAL_REF ((jobject) exception);
|
||||
memory_full (0);
|
||||
}
|
||||
else
|
||||
new_errno = EIO;
|
||||
|
||||
/* expression is still a local reference! */
|
||||
ANDROID_DELETE_LOCAL_REF ((jobject) exception);
|
||||
errno = new_errno;
|
||||
va_end (ap);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Return file status for the document designated by ID_NAME within
|
||||
the document tree identified by URI_NAME.
|
||||
|
||||
|
@ -6883,15 +6883,9 @@ android_vfs_init (JNIEnv *env, jobject manager)
|
|||
eassert (java_string_class);
|
||||
(*env)->DeleteLocalRef (env, old);
|
||||
|
||||
/* And initialize those used on Android 5.0 and later. */
|
||||
|
||||
if (android_get_current_api_level () < 21)
|
||||
if (android_get_current_api_level () < 19)
|
||||
return;
|
||||
|
||||
android_init_cursor_class (env);
|
||||
android_init_entry_class (env);
|
||||
android_init_fd_class (env);
|
||||
|
||||
/* Initialize each of the exception classes used by
|
||||
`android_saf_exception_check'. */
|
||||
|
||||
|
@ -6920,6 +6914,15 @@ android_vfs_init (JNIEnv *env, jobject manager)
|
|||
(*env)->DeleteLocalRef (env, old);
|
||||
eassert (out_of_memory_error);
|
||||
|
||||
/* And initialize those used on Android 5.0 and later. */
|
||||
|
||||
if (android_get_current_api_level () < 21)
|
||||
return;
|
||||
|
||||
android_init_cursor_class (env);
|
||||
android_init_entry_class (env);
|
||||
android_init_fd_class (env);
|
||||
|
||||
/* Initialize the semaphore used to wait for SAF operations to
|
||||
complete. */
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue