diff options
-rw-r--r-- | core/jni/android/graphics/BitmapFactory.cpp | 19 | ||||
-rw-r--r-- | core/jni/android_util_Process.cpp | 3 | ||||
-rw-r--r-- | libs/androidfw/BackupHelpers.cpp | 19 |
3 files changed, 21 insertions, 20 deletions
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp index 8ea28eca476b..e0abc24c42c5 100644 --- a/core/jni/android/graphics/BitmapFactory.cpp +++ b/core/jni/android/graphics/BitmapFactory.cpp @@ -478,7 +478,7 @@ static jobject nativeDecodeFileDescriptor(JNIEnv* env, jobject clazz, jobject fi NPE_CHECK_RETURN_ZERO(env, fileDescriptor); - jint descriptor = jniGetFDFromFileDescriptor(env, fileDescriptor); + int descriptor = jniGetFDFromFileDescriptor(env, fileDescriptor); struct stat fdStat; if (fstat(descriptor, &fdStat) == -1) { @@ -486,16 +486,27 @@ static jobject nativeDecodeFileDescriptor(JNIEnv* env, jobject clazz, jobject fi return nullObjectReturn("fstat return -1"); } - // Restore the descriptor's offset on exiting this function. + // Restore the descriptor's offset on exiting this function. Even though + // we dup the descriptor, both the original and dup refer to the same open + // file description and changes to the file offset in one impact the other. AutoFDSeek autoRestore(descriptor); - FILE* file = fdopen(descriptor, "r"); + // Duplicate the descriptor here to prevent leaking memory. A leak occurs + // if we only close the file descriptor and not the file object it is used to + // create. If we don't explicitly clean up the file (which in turn closes the + // descriptor) the buffers allocated internally by fseek will be leaked. + int dupDescriptor = dup(descriptor); + + FILE* file = fdopen(dupDescriptor, "r"); if (file == NULL) { + // cleanup the duplicated descriptor since it will not be closed when the + // file is cleaned up (fclose). + close(dupDescriptor); return nullObjectReturn("Could not open file"); } SkAutoTUnref<SkFILEStream> fileStream(new SkFILEStream(file, - SkFILEStream::kCallerRetains_Ownership)); + SkFILEStream::kCallerPasses_Ownership)); // Use a buffered stream. Although an SkFILEStream can be rewound, this // ensures that SkImageDecoder::Factory never rewinds beyond the diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp index 65061900ffbb..2b0960fc24d4 100644 --- a/core/jni/android_util_Process.cpp +++ b/core/jni/android_util_Process.cpp @@ -287,7 +287,8 @@ static void android_os_Process_setCanSelfBackground(JNIEnv* env, jobject clazz, void android_os_Process_setThreadScheduler(JNIEnv* env, jclass clazz, jint tid, jint policy, jint pri) { -#ifdef HAVE_SCHED_SETSCHEDULER +// linux has sched_setscheduler(), others don't. +#if defined(__linux__) struct sched_param param; param.sched_priority = pri; int rc = sched_setscheduler(tid, policy, ¶m); diff --git a/libs/androidfw/BackupHelpers.cpp b/libs/androidfw/BackupHelpers.cpp index c78593d23ed6..3f82830c4fa1 100644 --- a/libs/androidfw/BackupHelpers.cpp +++ b/libs/androidfw/BackupHelpers.cpp @@ -1307,23 +1307,12 @@ get_mod_time(const char* filename, struct timeval times[2]) fprintf(stderr, "stat '%s' failed: %s\n", filename, strerror(errno)); return errno; } - times[0].tv_sec = st.st_atime; - times[1].tv_sec = st.st_mtime; - - // If st_atime is a macro then struct stat64 uses struct timespec - // to store the access and modif time values and typically - // st_*time_nsec is not defined. In glibc, this is controlled by - // __USE_MISC. -#ifdef __USE_MISC -#if !defined(st_atime) || defined(st_atime_nsec) -#error "Check if this __USE_MISC conditional is still needed." -#endif + + times[0].tv_sec = st.st_atim.tv_sec; times[0].tv_usec = st.st_atim.tv_nsec / 1000; + + times[1].tv_sec = st.st_mtim.tv_sec; times[1].tv_usec = st.st_mtim.tv_nsec / 1000; -#else - times[0].tv_usec = st.st_atime_nsec / 1000; - times[1].tv_usec = st.st_mtime_nsec / 1000; -#endif return 0; } |