Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cc065fb9 authored by Misha Wagner's avatar Misha Wagner
Browse files

Modify Process::readProcFile to read in variable size file

The original Process::readProcFile could only read files smaller than 256 bytes.
This change allows the function to read in larger files. For files smaller than
256 bytes, the added cost is only an extra read call, which returns zero.

Documentation has also been added to Process::readProcFile.

Test: Used in change 5168194

Change-Id: I82f27355276e08f96bdb5fe7da49514a87afb429
parent 1332beac
Loading
Loading
Loading
Loading
+30 −3
Original line number Diff line number Diff line
@@ -1004,7 +1004,34 @@ public class Process {
    /** @hide */
    public static final int PROC_OUT_FLOAT = 0x4000;

    /** @hide */
    /**
     * Read and parse a {@code proc} file in the given format.
     *
     * <p>The format is a list of integers, where every integer describes a variable in the file. It
     * specifies how the variable is syntactically terminated (e.g. {@link Process#PROC_SPACE_TERM},
     * {@link Process#PROC_TAB_TERM}, {@link Process#PROC_ZERO_TERM}).
     *
     * <p>If the variable should be parsed and returned to the caller, the termination type should
     * be binary OR'd with the type of output (e.g. {@link Process#PROC_OUT_STRING}, {@link
     * Process#PROC_OUT_LONG}, {@link Process#PROC_OUT_FLOAT}.
     *
     * <p>If the variable is wrapped in quotation marks it should be binary OR'd with {@link
     * Process#PROC_QUOTES}. If the variable is wrapped in parentheses it should be binary OR'd with
     * {@link Process#PROC_PARENS}.
     *
     * <p>If the variable is not formatted as a string and should be cast directly from characters
     * to a long, the {@link Process#PROC_CHAR} integer should be binary OR'd.
     *
     * <p>If the terminating character can be repeated, the {@link Process#PROC_COMBINE} integer
     * should be binary OR'd.
     *
     * @param file the path of the {@code proc} file to read
     * @param format the format of the file
     * @param outStrings the parsed {@code String}s from the file
     * @param outLongs the parsed {@code long}s from the file
     * @param outFloats the parsed {@code float}s from the file
     * @hide
     */
    public static final native boolean readProcFile(String file, int[] format,
            String[] outStrings, long[] outLongs, float[] outFloats);

+27 −11
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@ using namespace android;

static const bool kDebugPolicy = false;
static const bool kDebugProc = false;
// When reading `proc` files, how many bytes to read at a time
static const int kReadSize = 4096;

#if GUARD_THREAD_PRIORITY
Mutex gKeyCreateMutex;
@@ -1034,21 +1036,35 @@ jboolean android_os_Process_readProcFile(JNIEnv* env, jobject clazz,
    }
    env->ReleaseStringUTFChars(file, file8);

    char buffer[256];
    const int len = read(fd, buffer, sizeof(buffer)-1);
    close(fd);

    std::vector<char> fileBuffer(kReadSize);
    int numBytesRead = 0;
    while (true) {
        // Resize buffer to make space for contents. This might be more than we need, but once we've
        // read we resize back down
        fileBuffer.resize(numBytesRead + kReadSize, 0);
        // Read in contents
        int len = TEMP_FAILURE_RETRY(read(fd, fileBuffer.data() + numBytesRead, kReadSize));
        numBytesRead += len;
        if (len < 0) {
            // If `len` is negative, an error occurred on read
            if (kDebugProc) {
                ALOGW("Unable to open process file: %s fd=%d\n", file8, fd);
            }
            close(fd);
            return JNI_FALSE;
        } else if (len == 0) {
            // If nothing read, we're done
            break;
        }
    buffer[len] = 0;
    }
    // Resize back down to the amount we read
    fileBuffer.resize(numBytesRead);
    // Terminate buffer with null byte
    fileBuffer.push_back('\0');
    close(fd);

    return android_os_Process_parseProcLineArray(env, clazz, buffer, 0, len,
    return android_os_Process_parseProcLineArray(env, clazz, fileBuffer.data(), 0, numBytesRead,
            format, outStrings, outLongs, outFloats);

}

void android_os_Process_setApplicationObject(JNIEnv* env, jobject clazz,