1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.os; 18 19 import com.android.internal.util.ProcFileReader; 20 21 import libcore.io.IoUtils; 22 23 import java.io.FileInputStream; 24 import java.io.IOException; 25 26 /** 27 * Reads and parses {@code locks} files in the {@code proc} filesystem. 28 * A typical example of /proc/locks 29 * 30 * 1: POSIX ADVISORY READ 18403 fd:09:9070 1073741826 1073742335 31 * 2: POSIX ADVISORY WRITE 18292 fd:09:34062 0 EOF 32 * 2: -> POSIX ADVISORY WRITE 18291 fd:09:34062 0 EOF 33 * 2: -> POSIX ADVISORY WRITE 18293 fd:09:34062 0 EOF 34 * 3: POSIX ADVISORY READ 3888 fd:09:13992 128 128 35 * 4: POSIX ADVISORY READ 3888 fd:09:14230 1073741826 1073742335 36 */ 37 public class ProcLocksReader { 38 private final String mPath; 39 ProcLocksReader()40 public ProcLocksReader() { 41 mPath = "/proc/locks"; 42 } 43 ProcLocksReader(String path)44 public ProcLocksReader(String path) { 45 mPath = path; 46 } 47 48 /** 49 * Checks if a process corresponding to a specific pid owns any file locks. 50 * @param pid The process ID for which we want to know the existence of file locks. 51 * @return true If the process holds any file locks, false otherwise. 52 * @throws IOException if /proc/locks can't be accessed. 53 */ hasFileLocks(int pid)54 public boolean hasFileLocks(int pid) throws Exception { 55 ProcFileReader reader = null; 56 long last = -1; 57 long id; // ordinal position of the lock in the list 58 int owner; // the PID of the process that owns the lock 59 60 try { 61 reader = new ProcFileReader(new FileInputStream(mPath)); 62 63 while (reader.hasMoreData()) { 64 id = reader.nextLong(true); // lock id 65 if (id == last) { 66 reader.finishLine(); // blocked lock 67 continue; 68 } 69 70 reader.nextIgnored(); // lock type: POSIX? 71 reader.nextIgnored(); // lock type: MANDATORY? 72 reader.nextIgnored(); // lock type: RW? 73 74 owner = reader.nextInt(); // pid 75 if (owner == pid) { 76 return true; 77 } 78 reader.finishLine(); 79 last = id; 80 } 81 } catch (IOException e) { 82 // TODO: let ProcFileReader log the failed line 83 throw new Exception("Exception parsing /proc/locks"); 84 } finally { 85 IoUtils.closeQuietly(reader); 86 } 87 return false; 88 } 89 } 90