summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/jni/android/graphics/BitmapFactory.cpp19
-rw-r--r--core/jni/android_util_Process.cpp3
-rw-r--r--libs/androidfw/BackupHelpers.cpp19
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, &param);
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;
}