Handle throwing fs.currentDirectory (#44)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index af5827a..1559454 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+#### 3.0.13
+
+* Handle `currentDirectory` throwing an exception in `getExecutablePath()`.
+
 #### 3.0.12
 
 * Updated version constraint on intl.
diff --git a/lib/src/interface/common.dart b/lib/src/interface/common.dart
index 2e711c1..02a5cde 100644
--- a/lib/src/interface/common.dart
+++ b/lib/src/interface/common.dart
@@ -56,7 +56,14 @@
 }) {
   assert(_osToPathStyle[platform.operatingSystem] == fs.path.style.name);
 
-  workingDirectory ??= fs.currentDirectory.path;
+  try {
+    workingDirectory ??= fs.currentDirectory.path;
+  } on FileSystemException {
+    // The `currentDirectory` getter can throw a FileSystemException for example
+    // when the process doesn't have read/list permissions in each component of
+    // the cwd path. In this case, fall back on '.'.
+    workingDirectory ??= '.';
+  }
   Context context =
       new Context(style: fs.path.style, current: workingDirectory);
 
diff --git a/pubspec.yaml b/pubspec.yaml
index 29f77c4..718b0a6 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: process
-version: 3.0.12
+version: 3.0.13
 authors:
 - Todd Volkert <tvolkert@google.com>
 - Michael Goderbauer <goderbauer@google.com>
diff --git a/test/src/interface/common_test.dart b/test/src/interface/common_test.dart
index 6d465a6..7a4f790 100644
--- a/test/src/interface/common_test.dart
+++ b/test/src/interface/common_test.dart
@@ -213,6 +213,34 @@
                 platform: platform),
             'C:\\\"Program Files\"\\bla.exe');
       });
+
+      test('with absolute path when currentDirectory getter throws', () {
+        FileSystem fsNoCwd = MemoryFileSystemNoCwd(fs);
+        String command = fs.path.join(dir3.path, 'bla.exe');
+        String expectedPath = command;
+        fs.file(command).createSync();
+
+        String executablePath = getExecutablePath(
+          command,
+          null,
+          platform: platform,
+          fs: fsNoCwd,
+        );
+        _expectSamePath(executablePath, expectedPath);
+      });
+
+      test('with relative path when currentDirectory getter throws', () {
+        FileSystem fsNoCwd = MemoryFileSystemNoCwd(fs);
+        String command = fs.path.join('.', 'bla.exe');
+
+        String executablePath = getExecutablePath(
+          command,
+          null,
+          platform: platform,
+          fs: fsNoCwd,
+        );
+        expect(executablePath, isNull);
+      });
     });
 
     group('on Linux', () {
@@ -284,3 +312,12 @@
   expect(actual, isNotNull);
   expect(actual.toLowerCase(), expected.toLowerCase());
 }
+
+class MemoryFileSystemNoCwd extends ForwardingFileSystem {
+  MemoryFileSystemNoCwd(FileSystem delegate) : super(delegate);
+
+  @override
+  Directory get currentDirectory {
+    throw FileSystemException('Access denied');
+  }
+}