diff --git a/libraries/base/System/Posix/Internals.hs b/libraries/base/System/Posix/Internals.hs
index 8e603623560abf6a717790da8d33d38e2c441595..e0745b39d6bd6c12ea80d59e7d06439f8e115593 100644
--- a/libraries/base/System/Posix/Internals.hs
+++ b/libraries/base/System/Posix/Internals.hs
@@ -517,7 +517,7 @@ foreign import javascript unsafe "h$base_isatty"
     c_isatty :: CInt -> IO CInt
 foreign import javascript interruptible "h$base_lseek"
    c_lseek :: CInt -> COff -> CInt -> IO COff
-foreign import javascript interruptible "h$base_lstat" -- fixme wrong type
+foreign import javascript interruptible "h$base_lstat"
    lstat :: CFilePath -> Ptr CStat -> IO CInt
 foreign import javascript interruptible "h$base_open"
    c_open :: CFilePath -> CInt -> CMode -> IO CInt
diff --git a/libraries/base/jsbits/base.js b/libraries/base/jsbits/base.js
index 8ea7e51d2b3b71c30502e883b0eb14128eaa63cd..c82443f3f103ad74ad4e794b562723c3137d5a50 100644
--- a/libraries/base/jsbits/base.js
+++ b/libraries/base/jsbits/base.js
@@ -230,6 +230,40 @@ function h$base_lstat(file, file_off, stat, stat_off, c) {
 #endif
         h$unsupported(-1, c);
 }
+
+function h$lstat(file, file_off, stat, stat_off) {
+  TRACE_IO("lstat")
+#ifndef GHCJS_BROWSER
+  if(h$isNode()) {
+    try {
+      var fs = h$fs.lstatSync(h$decodeUtf8z(file, file_off));
+      h$base_fillStat(fs, stat, stat_off);
+      return 0;
+    } catch(e) {
+      h$setErrno(e);
+      return -1;
+    }
+  } else
+#endif
+    h$unsupported(-1);
+}
+
+function h$rmdir(file, file_off) {
+  TRACE_IO("rmdir")
+#ifndef GHCJS_BROWSER
+  if(h$isNode()) {
+    try {
+      var fs = h$fs.rmdirSync(h$decodeUtf8z(file, file_off));
+      return 0;
+    } catch(e) {
+      h$setErrno(e);
+      return -1;
+    }
+  } else
+#endif
+    h$unsupported(-1);
+}
+
 function h$base_open(file, file_off, how, mode, c) {
 #ifndef GHCJS_BROWSER
     if(h$isNode()) {
@@ -435,20 +469,26 @@ function h$base_waitpid(pid, stat, stat_off, options, c) {
 /** @const */ var h$base_o_nonblock = 0x00004;
 /** @const */ var h$base_o_binary   = 0x00000;
 
+function h$base_stat_check_mode(mode,p) {
+  // inspired by Node's checkModeProperty
+  var r = (mode & h$fs.constants.S_IFMT) === p;
+  return r ? 1 : 0;
+}
+
 function h$base_c_s_isreg(mode) {
-    return 1;
+  return h$base_stat_check_mode(mode,h$fs.constants.S_IFREG);
 }
 function h$base_c_s_ischr(mode) {
-    return 0;
+  return h$base_stat_check_mode(mode,h$fs.constants.S_IFCHR);
 }
 function h$base_c_s_isblk(mode) {
-    return 0;
+  return h$base_stat_check_mode(mode,h$fs.constants.S_IFBLK);
 }
 function h$base_c_s_isdir(mode) {
-    return 0; // fixme
+  return h$base_stat_check_mode(mode,h$fs.constants.S_IFDIR);
 }
 function h$base_c_s_isfifo(mode) {
-    return 0;
+  return h$base_stat_check_mode(mode,h$fs.constants.S_IFIFO);
 }
 function h$base_c_fcntl_read(fd,cmd) {
     return -1;
diff --git a/libraries/base/tests/IO/all.T b/libraries/base/tests/IO/all.T
index c86bb3ee393377eb9bcca26a281660489373bf3c..0a51695bdb8ac39f56099ac40981e9a0f8fe2586 100644
--- a/libraries/base/tests/IO/all.T
+++ b/libraries/base/tests/IO/all.T
@@ -12,8 +12,7 @@ test('hClose001', [], compile_and_run, [''])
 test('hClose002', [normalise_win32_io_errors, js_broken(22261)], compile_and_run, [''])
 test('hFileSize001',    normal, compile_and_run, [''])
 test('hFileSize002',
-     [omit_ghci, # different output
-      js_broken(22261)],
+     [omit_ghci], # different output
      compile_and_run, [''])
 test('hFlush001', [], compile_and_run, [''])
 
@@ -71,12 +70,12 @@ test('misc001', [extra_run_opts('misc001.hs misc001.out')], compile_and_run,
 
 test('openFile001',  normal, compile_and_run, [''])
 test('openFile002',  [exit_code(1), normalise_win32_io_errors], compile_and_run, [''])
-test('openFile003', [normalise_win32_io_errors, js_broken(22362)], compile_and_run, [''])
+test('openFile003', normalise_win32_io_errors, compile_and_run, [''])
 test('openFile004', [], compile_and_run, [''])
 test('openFile005', js_broken(22261), compile_and_run, [''])
 test('openFile006', [], compile_and_run, [''])
 test('openFile007', js_broken(22261), compile_and_run, [''])
-test('openFile008', [js_broken(22349), cmd_prefix('ulimit -n 1024; ')], compile_and_run, [''])
+test('openFile008', [cmd_prefix('ulimit -n 1024; ')], compile_and_run, [''])
 test('openFile009', [when(arch('wasm32'), fragile(23284))], compile_and_run, [''])
 
 test('putStr001',    normal, compile_and_run, [''])
diff --git a/libraries/base/tests/IO/openFile003.stdout-javascript-unknown-ghcjs b/libraries/base/tests/IO/openFile003.stdout-javascript-unknown-ghcjs
new file mode 100644
index 0000000000000000000000000000000000000000..5ba81aec75ffe7fd4db677ab1703225b96d439fe
--- /dev/null
+++ b/libraries/base/tests/IO/openFile003.stdout-javascript-unknown-ghcjs
@@ -0,0 +1,4 @@
+Left openFile003Dir: openFile: inappropriate type (is a directory)
+Left openFile003Dir: openFile: inappropriate type (Illegal operation on a directory)
+Left openFile003Dir: openFile: inappropriate type (Illegal operation on a directory)
+Left openFile003Dir: openFile: inappropriate type (Illegal operation on a directory)