# HG changeset patch # User wenzelm # Date 1542225074 -3600 # Node ID 5faf57207a9bbf71b0365619bd87c633bf25662d # Parent f6c17b9e110439f075804351eb4ff297a6b568e5 proper use of stat() vs. lstat() (for symlinks); diff -r f6c17b9e1104 -r 5faf57207a9b src/Pure/General/ssh.scala --- a/src/Pure/General/ssh.scala Wed Nov 14 20:04:39 2018 +0100 +++ b/src/Pure/General/ssh.scala Wed Nov 14 20:51:14 2018 +0100 @@ -201,7 +201,7 @@ type Attrs = SftpATTRS - sealed case class Dir_Entry(name: Path, is_dir: Boolean) + sealed case class Dir_Entry(name: String, is_dir: Boolean) { def is_file: Boolean = !is_dir } @@ -340,29 +340,20 @@ def mkdir(path: Path): Unit = sftp.mkdir(remote_path(path)) def rmdir(path: Path): Unit = sftp.rmdir(remote_path(path)) - private def try_stat(name: String): Option[Attrs] = - try { Some(sftp.stat(name)) } - catch { case _: SftpException => None } - - private def test_dir(name: String, attrs: Attrs): Boolean = - if (attrs.isLink) try_stat(name + "/.").isDefined else attrs.isDir + private def test_entry(path: Path, as_dir: Boolean): Boolean = + try { + val is_dir = sftp.stat(remote_path(path)).isDir + if (as_dir) is_dir else !is_dir + } + catch { case _: SftpException => false } - private def check_entry(path: Path, as_dir: Boolean): Boolean = - { - val name = remote_path(path) - try_stat(name) match { - case None => false - case Some(attrs) => if (as_dir) test_dir(name, attrs) else !test_dir(name, attrs) - } - } + override def is_dir(path: Path): Boolean = test_entry(path, true) + override def is_file(path: Path): Boolean = test_entry(path, false) def is_link(path: Path): Boolean = try { sftp.lstat(remote_path(path)).isLink } catch { case _: SftpException => false } - override def is_dir(path: Path): Boolean = check_entry(path, true) - override def is_file(path: Path): Boolean = check_entry(path, false) - override def mkdirs(path: Path): Unit = if (!is_dir(path)) { execute( @@ -382,7 +373,15 @@ name = Untyped.get[String](a, "filename") attrs = Untyped.get[Attrs](a, "attrs") if name != "." && name != ".." - } yield Dir_Entry(Path.basic(name), test_dir(dir_name + "/" + name, attrs))).toList + } + yield { + Dir_Entry(name, + if (attrs.isLink) { + try { sftp.stat(dir_name + "/" + name).isDir } + catch { case _: SftpException => false } + } + else attrs.isDir) + }).toList } def find_files( @@ -399,9 +398,8 @@ if (follow_links || !is_link(dir)) { if (include_dirs) check(dir) for (entry <- read_dir(dir)) { - val path = dir + entry.name - if (include_dirs || entry.is_file) check(path) - if (entry.is_dir) find(path) + val path = dir + Path.basic(entry.name) + if (entry.is_file) check(path) else find(path) } } }