/* * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ package com.facebook.stetho.common; import javax.annotation.Nullable; import java.io.FileInputStream; import java.io.IOException; public class ProcessUtil { /** * Maximum length allowed in {@code /proc/self/cmdline}. Imposed to avoid a large buffer * allocation during the init path. */ private static final int CMDLINE_BUFFER_SIZE = 64; private static String sProcessName; private static boolean sProcessNameRead; /** * Get process name by reading {@code /proc/self/cmdline}. * * @return Process name or null if there was an error reading from {@code /proc/self/cmdline}. * It is unknown how this error can occur in practice and should be considered extremely * rare. */ @Nullable public static synchronized String getProcessName() { if (!sProcessNameRead) { sProcessNameRead = true; try { sProcessName = readProcessName(); } catch (IOException e) { } } return sProcessName; } private static String readProcessName() throws IOException { byte[] cmdlineBuffer = new byte[CMDLINE_BUFFER_SIZE]; // Avoid using a Reader to not pick up a forced 16K buffer. Silly java.io... FileInputStream stream = new FileInputStream("/proc/self/cmdline"); boolean success = false; try { int n = stream.read(cmdlineBuffer); success = true; int endIndex = indexOf(cmdlineBuffer, 0, n, (byte)0 /* needle */); return new String(cmdlineBuffer, 0, endIndex > 0 ? endIndex : n); } finally { Util.close(stream, !success); } } private static int indexOf(byte[] haystack, int offset, int length, byte needle) { for (int i = 0; i < haystack.length; i++) { if (haystack[i] == needle) { return i; } } return -1; } }