[Git][ghc/ghc][master] 2 commits: JS: add basic support for POSIX *at functions (#25190)

Marge Bot (@marge-bot) gitlab at gitlab.haskell.org
Mon Aug 26 15:05:55 UTC 2024



Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC


Commits:
27dceb42 by Sylvain Henry at 2024-08-26T11:05:11-04:00
JS: add basic support for POSIX *at functions (#25190)

openat/fstatat/unlinkat/dup are now used in the recent release of the
`directory` and `file-io` packages.

As such, these functions are (indirectly) used in the following tests
one we'll bump the `directory` submodule (see !13122):
- openFile008
- jsOptimizer
- T20509
- bkpcabal02
- bkpcabal03
- bkpcabal04

- - - - -
c68be356 by Matthew Pickering at 2024-08-26T11:05:11-04:00
Update directory submodule to latest master

The primary reason for this bump is to fix the warning from `ghc-pkg
check`:

```
Warning: include-dirs: /data/home/ubuntu/.ghcup/ghc/9.6.2/lib/ghc-9.6.2/lib/../lib/aarch64-linux-ghc-9.6.2/directory-1.3.8.1/include doesn't exist or isn't a directory
```

This also requires adding the `file-io` package as a boot library (which
is discussed in #25145)

Fixes #23594 #25145

- - - - -


9 changed files:

- .gitmodules
- docs/users_guide/9.12.1-notes.rst
- hadrian/src/Packages.hs
- hadrian/src/Rules/ToolArgs.hs
- hadrian/src/Settings/Default.hs
- libraries/directory
- + libraries/file-io
- libraries/ghc-internal/jsbits/base.js
- libraries/ghc-internal/src/GHC/Internal/System/Posix/Internals.hs


Changes:

=====================================
.gitmodules
=====================================
@@ -118,3 +118,6 @@
 [submodule "hadrian/vendored/Cabal"]
 	path = hadrian/vendored/Cabal
 	url = https://gitlab.haskell.org/ghc/packages/Cabal.git
+[submodule "libraries/file-io"]
+	path = libraries/file-io
+	url = https://gitlab.haskell.org/ghc/packages/file-io.git


=====================================
docs/users_guide/9.12.1-notes.rst
=====================================
@@ -223,3 +223,4 @@ for further change information.
     libraries/Win32/Win32.cabal:                         Dependency of ``ghc`` library
     libraries/xhtml/xhtml.cabal:                         Dependency of ``haddock`` executable
     libraries/os-string/os-string.cabal:                 Dependency of ``filepath`` library
+    libraries/file-io/file-io.cabal:                     Dependency of ``directory`` library


=====================================
hadrian/src/Packages.hs
=====================================
@@ -4,7 +4,7 @@ module Packages (
     array, base, binary, bytestring, cabal, cabalSyntax, checkPpr,
     checkExact, countDeps,
     compareSizes, compiler, containers, deepseq, deriveConstants, directory, dumpDecls,
-    exceptions, filepath, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform,
+    exceptions, filepath, fileio, genapply, genprimopcode, ghc, ghcBignum, ghcBoot, ghcBootTh, ghcBootThNext, ghcPlatform,
     ghcCompact, ghcConfig, ghcExperimental, ghcHeap, ghcInternal, ghci, ghciWrapper, ghcPkg, ghcPrim,
     ghcToolchain, ghcToolchainBin, haddockApi, haddockLibrary, haddock, haskeline,
     hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, iservProxy,
@@ -40,7 +40,7 @@ ghcPackages =
     , ghcToolchain, ghcToolchainBin, haddockApi, haddockLibrary, haddock, haskeline, hsc2hs
     , hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, libffi, mtl, osString
     , parsec, pretty, process, rts, runGhc, stm, semaphoreCompat, templateHaskell
-    , terminfo, text, time, transformers, unlit, unix, win32, xhtml
+    , terminfo, text, time, transformers, unlit, unix, win32, xhtml, fileio
     , timeout
     , lintersCommon
     , lintNotes, lintCodes, lintCommitMsg, lintSubmoduleRefs, lintWhitespace ]
@@ -79,6 +79,7 @@ directory           = lib  "directory"
 dumpDecls           = util "dump-decls"
 exceptions          = lib  "exceptions"
 filepath            = lib  "filepath"
+fileio              = lib  "file-io"
 genapply            = util "genapply"
 genprimopcode       = util "genprimopcode"
 ghc                 = prg  "ghc-bin"         `setPath` "ghc"


=====================================
hadrian/src/Rules/ToolArgs.hs
=====================================
@@ -138,6 +138,7 @@ toolTargets = [ cabalSyntax
               , directory
               , process
               , filepath
+              , fileio
               , osString
               -- , ghc     -- # depends on ghc library
               -- , runGhc  -- # depends on ghc library


=====================================
hadrian/src/Settings/Default.hs
=====================================
@@ -83,8 +83,9 @@ stage0Packages = do
     return $ [ cabalSyntax
              , cabal
              , compiler
-             , directory -- depends on filepath
+             , directory -- depends on filepath, fileIo
              , filepath -- depends on os-string
+             , fileio
              , ghc
              , ghcBoot
              , ghcBootThNext


=====================================
libraries/directory
=====================================
@@ -1 +1 @@
-Subproject commit a97a8a8f30d652f972192122fd5f459a147c13e5
+Subproject commit 6045b93c4ef7a713c8f3d6837ca69f8e96b12bf1


=====================================
libraries/file-io
=====================================
@@ -0,0 +1 @@
+Subproject commit a4a0464ccd38e8380c202949a90b21d9e592aeef


=====================================
libraries/ghc-internal/jsbits/base.js
=====================================
@@ -138,6 +138,126 @@ function h$base_fstat(fd, stat, stat_off, c) {
         h$unsupported(-1, c);
 }
 
+function h$stat(path, path_off, stat, stat_off) {
+#ifndef GHCJS_BROWSER
+  if(h$isNode()) {
+    try {
+      var stats = h$fs.statSync(h$decodeUtf8z(path, path_off));
+      h$base_fillStat(stats, stat, stat_off);
+      return 0;
+    } catch(e) {
+      h$setErrno(e);
+      return -1;
+    }
+  }
+  else
+#endif
+    h$unsupported(-1);
+}
+
+function h$lstat(path, path_off, stat, stat_off) {
+#ifndef GHCJS_BROWSER
+  if(h$isNode()) {
+    try {
+      var stats = h$fs.lstatSync(h$decodeUtf8z(path, path_off));
+      h$base_fillStat(stats, stat, stat_off);
+      return 0;
+    } catch(e) {
+      h$setErrno(e);
+      return -1;
+    }
+  }
+  else
+#endif
+    h$unsupported(-1);
+}
+
+function h$fstatat(dirfd, path, path_off, stat, stat_off, flag) {
+#ifndef GHCJS_BROWSER
+  if(h$isNode()) {
+    var fp = h$calculate_at(dirfd, path, path_off);
+    try {
+      if (flag & h$base_at_symlink_nofollow) {
+        var fs = h$fs.lstatSync(fp);
+        h$base_fillStat(fs, stat, stat_off);
+        return 0;
+      }
+      else {
+        var fs = h$fs.statSync(fp);
+        h$base_fillStat(fs, stat, stat_off);
+        return 0;
+      }
+
+    } catch(e) {
+      h$setErrno(e);
+      return -1;
+    }
+  }
+#endif
+
+  return h$unsupported(-1);
+}
+
+function h$unlinkat(dirfd, path, path_off, flag) {
+#ifndef GHCJS_BROWSER
+  if(h$isNode()) {
+    var fp = h$calculate_at(dirfd, path, path_off);
+    try {
+      if (flag & h$base_at_removedir) {
+        h$fs.rmdirSync(fp);
+        return 0;
+      }
+      else {
+        h$fs.unlinkSync(fp);
+        return 0;
+      }
+
+    } catch(e) {
+      h$setErrno(e);
+      return -1;
+    }
+  }
+#endif
+
+  return h$unsupported(-1);
+}
+
+function h$dup(fd) {
+#ifndef GHCJS_BROWSER
+  if(h$isNode()) {
+    try {
+      // NodeJS doesn't provide "dup" (see
+      // https://github.com/nodejs/node/issues/41733), so we do this hack that
+      // probably only works on Linux.
+      return h$fs.openSync("/proc/self/fd/"+fd);
+    } catch(e) {
+      h$setErrno(e);
+      return -1;
+    }
+  }
+  else
+#endif
+    h$unsupported(-1);
+}
+
+function h$fdopendir(fd) {
+#ifndef GHCJS_BROWSER
+  if(h$isNode()) {
+    try {
+      // NodeJS doesn't provide "fdopendir", so we do this hack that probably
+      // only works on Linux.
+      return h$fs.opendirSync("/proc/self/fd/"+fd);
+    } catch(e) {
+      h$setErrno(e);
+      return -1;
+    }
+  }
+  else
+#endif
+    h$unsupported(-1);
+}
+
+
 function h$base_isatty(fd) {
     TRACE_IO("base_isatty " + fd)
     //  return 1; // fixme debug
@@ -333,25 +453,55 @@ function h$realpath(path,off,resolved,resolved_off) {
     h$unsupported(-1);
 }
 
-function h$base_open(file, file_off, how, mode, c) {
-  return h$open(file,file_off,how,mode,c);
+function h$path_is_abs(path) {
+ return path.charAt(0) === '/';
 }
 
-function h$openat(dirfd, file, file_off, how, mode) {
-  if (dirfd != h$base_at_fdcwd) {
-    // we only support AT_FDWCD (open) until NodeJS provides "openat"
-    return h$unsupported(-1);
+function h$path_join2(p1,p2) {
+  // Emscripten would normalize the path here. We don't for now.
+ return (p1 + '/' + p2);
+}
+
+// Compute path from a FD and a path
+function h$calculate_at(dirfd, file, file_off) {
+  var path = h$decodeUtf8z(file,file_off);
+
+  if (h$path_is_abs(path)) {
+    return path;
+  }
+
+  // relative path
+  var dir;
+  if (dirfd == h$base_at_fdcwd) {
+    dir = h$process.cwd();
   }
+#ifndef GHCJS_BROWSER
+  else if (h$isNode()) {
+    // hack that probably only works on Linux with /proc mounted
+    dir = h$fs.readlinkSync("/proc/self/fd/"+dirfd);
+  }
+#endif
   else {
-    return h$open(file,file_off,how,mode,undefined);
+    return h$unsupported(-1);
   }
+
+  return h$path_join2(dir,path);
+}
+
+function h$openat(dirfd, file, file_off, how, mode, c) {
+  var path = h$calculate_at(dirfd, file, file_off);
+  return h$base_open(path, how, mode, c);
+}
+
+function h$open(file, file_off, how, mode, c) {
+  var path = h$decodeUtf8z(file, file_off);
+  return h$base_open(path, how, mode, c);
 }
 
-function h$open(file, file_off, how, mode,c) {
+function h$base_open(fp, how, mode, c) {
 #ifndef GHCJS_BROWSER
     if(h$isNode()) {
         var flags, off;
-        var fp   = h$decodeUtf8z(file, file_off);
         TRACE_IO("open: " + fp)
         var acc  = how & h$base_o_accmode;
         // passing a number lets node.js use it directly as the flags (undocumented)
@@ -586,6 +736,9 @@ const h$base_o_noctty   = 0x20000;
 const h$base_o_nonblock = 0x00004;
 const h$base_o_binary   = 0x00000;
 const h$base_at_fdcwd   = -100;
+const h$base_at_symlink_nofollow = 0x100;
+const h$base_at_removedir        = 0x200;
+const h$base_at_symlink_follow   = 0x400;
 
 
 function h$base_stat_check_mode(mode,p) {


=====================================
libraries/ghc-internal/src/GHC/Internal/System/Posix/Internals.hs
=====================================
@@ -537,11 +537,11 @@ foreign import javascript interruptible "h$base_lseek"
    c_lseek :: CInt -> COff -> CInt -> IO COff
 foreign import javascript interruptible "h$base_lstat"
    lstat :: CFilePath -> Ptr CStat -> IO CInt
-foreign import javascript interruptible "h$base_open"
+foreign import javascript interruptible "h$open"
    c_open :: CFilePath -> CInt -> CMode -> IO CInt
-foreign import javascript interruptible "h$base_open"
+foreign import javascript interruptible "h$open"
    c_interruptible_open_ :: CFilePath -> CInt -> CMode -> IO CInt
-foreign import javascript interruptible "h$base_open"
+foreign import javascript interruptible "h$open"
    c_safe_open_ :: CFilePath -> CInt -> CMode -> IO CInt
 foreign import javascript interruptible "h$base_read"
    c_read :: CInt -> Ptr Word8 -> CSize -> IO CSsize



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1f95c5e4238ef0a55649fd878bd11c7c221c531a...c68be3563152a9b0e1ee065eabc3a00e0d829b4a

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1f95c5e4238ef0a55649fd878bd11c7c221c531a...c68be3563152a9b0e1ee065eabc3a00e0d829b4a
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20240826/e48204e7/attachment-0001.html>


More information about the ghc-commits mailing list