private static @Nullable List<ProcessInfo> getProcessListOnUnix() {
    File proc = new File("/proc");

    File[] processes = proc.listFiles();
    if (processes == null) {
      LOG.error("Cannot read /proc, not mounted?");
      return null;
    }

    String currentUser = getCurrentUser();
    Map<Long, String> owners = getProcessOwners();
    List<ProcessInfo> result = new ArrayList<>();

    for (File each : processes) {
      int pid = StringUtil.parseInt(each.getName(), -1);
      if (pid == -1) continue;

      List<String> cmdline;
      try (FileInputStream stream = new FileInputStream(new File(each, "cmdline"))) {
        String cmdlineString = new String(FileUtil.loadBytes(stream), StandardCharsets.UTF_8);
        cmdline = StringUtil.split(cmdlineString, "\0");
      }
      catch (IOException e) {
        continue;
      }
      if (cmdline.isEmpty()) continue;

      String executablePath = null;

      try {
        File exe = new File(each, "exe");
        if (!exe.getAbsolutePath().equals(exe.getCanonicalPath())) {
          executablePath = exe.getCanonicalPath();
        }
      }
      catch (IOException e) {
        // couldn't resolve symlink
      }

      int parentPid = -1;
      try (FileInputStream stream = new FileInputStream(new File(each, "status"))) {
        String statusString = new String(FileUtil.loadBytes(stream), StandardCharsets.UTF_8);
        for (String line : StringUtil.splitByLines(statusString)) {
          if (line.startsWith(PARENT_PID_PREFIX)) {
            try {
              parentPid = Integer.parseInt(line.substring(PARENT_PID_PREFIX.length()).trim());
            }
            catch (NumberFormatException numberFormatException) {
              LOG.error("Failed to parse parent pid from line " + line);
            }
            break;
          }
        }
      }
      catch (IOException ignored) {
      }

      String processUser = owners.get((long)pid);
      result.add(new ProcessInfo(pid, StringUtil.join(cmdline, " "),
                                 PathUtil.getFileName(cmdline.get(0)),
                                 StringUtil.join(cmdline.subList(1, cmdline.size()), " "),
                                 executablePath,
                                 parentPid,
                                 processUser,
                                 currentUser != null ? ThreeState.fromBoolean(currentUser.equals(processUser)) : ThreeState.UNSURE
      ));
    }
    return result;
  }
private static @Nullable List<ProcessInfo> getProcessListOnUnix()