From 470bdaa27a771467fcd44dfa9c9c951501642ac6 Mon Sep 17 00:00:00 2001 From: Yongjun Zhang Date: Thu, 10 Nov 2016 22:38:38 -0800 Subject: [PATCH] HADOOP-12718. Incorrect error message by fs -put local dir without permission. (John Zhuge via Yongjun Zhang) --- .../apache/hadoop/fs/FSExceptionMessages.java | 2 + .../java/org/apache/hadoop/fs/FileUtil.java | 8 ++- .../org/apache/hadoop/fs/TestFsShellCopy.java | 51 +++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FSExceptionMessages.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FSExceptionMessages.java index 95724ffc877..1511bb0a480 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FSExceptionMessages.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FSExceptionMessages.java @@ -46,4 +46,6 @@ public class FSExceptionMessages { public static final String TOO_MANY_BYTES_FOR_DEST_BUFFER = "Requested more bytes than destination buffer size"; + + public static final String PERMISSION_DENIED = "Permission denied"; } diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileUtil.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileUtil.java index 84a8abb0eb5..ea6249e47fd 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileUtil.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileUtil.java @@ -29,6 +29,7 @@ import java.net.InetAddress; import java.net.URI; import java.net.UnknownHostException; +import java.nio.file.AccessDeniedException; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; @@ -1139,9 +1140,14 @@ public static File[] listFiles(File dir) throws IOException { * an IOException to be thrown. * @param dir directory for which listing should be performed * @return list of file names or empty string list - * @exception IOException for invalid directory or for a bad disk. + * @exception AccessDeniedException for unreadable directory + * @exception IOException for invalid directory or for bad disk */ public static String[] list(File dir) throws IOException { + if (!canRead(dir)) { + throw new AccessDeniedException(dir.toString(), null, + FSExceptionMessages.PERMISSION_DENIED); + } String[] fileNames = dir.list(); if(fileNames == null) { throw new IOException("Invalid directory or I/O error occurred for dir: " diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestFsShellCopy.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestFsShellCopy.java index 6ca390508ac..1db72d20199 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestFsShellCopy.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestFsShellCopy.java @@ -26,12 +26,15 @@ import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; +import java.io.PrintStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.permission.FsPermission; import org.apache.hadoop.test.GenericTestUtils; import org.apache.hadoop.util.StringUtils; import org.junit.Before; @@ -607,4 +610,52 @@ public void testCopyNoParent() throws Exception { shellRun("-copyFromLocal", srcPath.toString(), noDirName + "/"), is(not(0))); } + + @Test + public void testPutSrcDirNoPerm() + throws Exception { + final Path src = new Path(testRootDir, "srcNoPerm"); + final Path dst = new Path(testRootDir, "dst"); + lfs.delete(src, true); + lfs.mkdirs(src, new FsPermission((short)0)); + lfs.delete(dst, true); + + try { + final ByteArrayOutputStream err = new ByteArrayOutputStream(); + PrintStream oldErr = System.err; + System.setErr(new PrintStream(err)); + shellRun(1, "-put", src.toString(), dst.toString()); + System.setErr(oldErr); + System.err.print(err.toString()); + assertTrue(err.toString().contains( + FSExceptionMessages.PERMISSION_DENIED)); + } finally { + // Make sure the test directory can be deleted + lfs.setPermission(src, new FsPermission((short)0755)); + } + } + + @Test + public void testPutSrcFileNoPerm() + throws Exception { + final Path src = new Path(testRootDir, "srcNoPerm"); + final Path dst = new Path(testRootDir, "dst"); + lfs.delete(src, true); + lfs.create(src); + lfs.setPermission(src, new FsPermission((short)0)); + lfs.delete(dst, true); + + try { + final ByteArrayOutputStream err = new ByteArrayOutputStream(); + PrintStream oldErr = System.err; + System.setErr(new PrintStream(err)); + shellRun(1, "-put", src.toString(), dst.toString()); + System.setErr(oldErr); + System.err.print(err.toString()); + assertTrue(err.toString().contains("(Permission denied)")); + } finally { + // make sure the test file can be deleted + lfs.setPermission(src, new FsPermission((short)0755)); + } + } }