/* * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ /* @test * @bug 4429043 4493595 6332756 * @summary The FileChannel file locking */ import java.io.*; import java.nio.channels.*; import java.nio.*; /** * Testing FileChannel's lock method. */ public class Lock { public static void main(String[] args) throws Exception { if (args.length > 0) { if(args[0].equals("1")) { MadWriter mw = new MadWriter(args[1], false); } else { MadWriter mw = new MadWriter(args[1], true); } return; } File blah = File.createTempFile("blah", null); blah.deleteOnExit(); RandomAccessFile raf = new RandomAccessFile(blah, "rw"); raf.write(1); raf.close(); test1(blah, "1"); test1(blah, "2"); test2(blah, true); test2(blah, false); test3(blah); } private static void test2(File blah, boolean b) throws Exception { RandomAccessFile raf = new RandomAccessFile(blah, "rw"); FileChannel channel = raf.getChannel(); FileLock lock; if (b) lock = channel.lock(); else lock = channel.tryLock(); lock.release(); channel.close(); } static void test1(File blah, String str) throws Exception { // Grab the lock RandomAccessFile fis = new RandomAccessFile(blah, "rw"); FileChannel fc = fis.getChannel(); FileLock lock = null; if (str.equals("1")) { lock = fc.lock(0, 10, false); if (lock == null) throw new RuntimeException("Lock should not return null"); try { FileLock lock2 = fc.lock(5, 10, false); throw new RuntimeException("Overlapping locks allowed"); } catch (OverlappingFileLockException e) { // Correct result } } // Exec the tamperer String command = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java Lock " + str + " " + blah; Process p = Runtime.getRuntime().exec(command); BufferedReader in = new BufferedReader (new InputStreamReader(p.getInputStream())); String s; int count = 0; while ((s = in.readLine()) != null) { if (!s.equals("good")) { if (File.separatorChar == '/') { // Fails on windows over NFS... throw new RuntimeException("Failed: "+s); } } count++; } if (count == 0) { in = new BufferedReader(new InputStreamReader(p.getErrorStream())); while ((s = in.readLine()) != null) { System.err.println("Error output: " + s); } throw new RuntimeException("Failed, no output"); } // Clean up if (lock != null) { /* Check multiple releases */ lock.release(); lock.release(); } fc.close(); fis.close(); } // The overlap check for file locks should be JVM-wide private static void test3(File blah) throws Exception { FileChannel fc1 = new RandomAccessFile(blah, "rw").getChannel(); FileChannel fc2 = new RandomAccessFile(blah, "rw").getChannel(); // lock via one channel, and then attempt to lock the same file // using a second channel FileLock fl1 = fc1.lock(); try { fc2.tryLock(); throw new RuntimeException("Overlapping locks allowed"); } catch (OverlappingFileLockException x) { } try { fc2.lock(); throw new RuntimeException("Overlapping locks allowed"); } catch (OverlappingFileLockException x) { } // release lock and the attempt to lock with the second channel // should succeed. fl1.release(); FileLock fl2 = fc2.lock(); try { fc1.lock(); throw new RuntimeException("Overlapping locks allowed"); } catch (OverlappingFileLockException x) { } fc1.close(); fc2.close(); } } class MadWriter { public MadWriter(String s, boolean b) throws Exception { File f = new File(s); RandomAccessFile fos = new RandomAccessFile(f, "rw"); FileChannel fc = fos.getChannel(); if (fc.tryLock(10, 10, false) == null) { System.out.println("bad: Failed to grab adjacent lock"); } FileLock lock = fc.tryLock(0, 10, false); if (lock == null) { if (b) System.out.println("bad"); else System.out.println("good"); } else { if (b) System.out.println("good"); else System.out.println("bad"); } fc.close(); fos.close(); } }