gitoriaLog in with ident

tickets

All repositories: gitoria

ReadmeCodePull requestsReleasesTicketsSettings
Commit38f9d10f38f9d10ftickets: Hybriel master 06617221 (plugin allocators 3a781359 + 413f60e4, mpackdb 2cb7ae5e, http1 773de63e); gate 249/0, connect 60/0mre38f9d10f/plugins/fs/server.hl

4.5 KB

  1. file(String path) {
  2. return __native("fs.file", path)
  3. }
  4. readFile(String path) {
  5. return __native("fs.read_file", path)
  6. }
  7. \* Read a whole file as Bytes (ticket #88): every byte as it is on disk,
  8. nothing decoded — the way back for what writeFile stored from a Bytes. *\
  9. readBytes(String path) {
  10. return toBytes(__native("fs.read_file", path))
  11. }
  12. listDir(String path) {
  13. return __native("fs.list_dir", path)
  14. }
  15. \* Does this path exist? (mission 077) The one call in hl:fs that cannot fail:
  16. it answers true/false, never an Error event — probing a path is a question,
  17. not an operation. Relative paths resolve against the SCRIPT's directory like
  18. every other hl:fs path. *\
  19. exists(String path) {
  20. return __native("fs.exists", path)
  21. }
  22. \* Watch a directory tree for changes (the dev-reload bell): an ordinary
  23. event-loop source — register it and every save arrives as an event.
  24. __native("eventloop.register", watch("."), "changed")
  25. on changed(ev) { … ev.name … }
  26. `exclude` (2026-08-30) names directories the descent must NOT enter — a
  27. path string, or a list of them. Omit it and the whole tree is watched, as
  28. it always was. The paths are compared RESOLVED (relative ones against the
  29. script's directory, like every hl:fs path) and normalised, so `./sessions`,
  30. `sessions` and `var/../sessions` are the same directory, and a sibling
  31. named `sessions-old` is NOT inside `sessions`.
  32. watch(".", "./sessions")
  33. watch(".", ["./sessions", "/var/cache/app"])
  34. A program that writes to a directory it also watches needs this: without
  35. it the only escape was that the walker skips dot-directories (which it
  36. still does — `.git` is the reason), i.e. renaming the directory. *\
  37. watch(String path, exclude) {
  38. return __native("fs.watch", path, exclude)
  39. }
  40. \* Write a whole file, ATOMICALLY (2026-08-28). Everything above this line
  41. reads; hl:fs could report a file's `chmod` and never set one, which is why
  42. nothing in this language could persist anything until now.
  43. The write goes to a sibling temp file, is fsynced, and is then renamed over
  44. the target — so a concurrent reader sees the whole OLD file or the whole NEW
  45. one, never a half of either. That matters more than it sounds: the first
  46. caller is the session store, and a truncated session file does not read as
  47. an error, it reads as a logged-out user.
  48. `mode` defaults to 0600 — a file this program wrote, for this program. Pass
  49. one to loosen it; nothing here consults the umask on your behalf.
  50. `contents` is a String or a Bytes (ticket #88): a Bytes is written raw,
  51. byte for byte — an uploaded image stays an image. *\
  52. writeFile(
  53. String path
  54. contents \\ a String or a Bytes
  55. Number mode
  56. ) {
  57. if (hlTypeName(contents) == 'Bytes') {
  58. return __native("fs.write_file_hex", path, contents.hex(), mode)
  59. }
  60. return __native("fs.write_file", path, contents, mode)
  61. }
  62. \* Append to a file — the log's shape, not the session store's (2026-09-27, a
  63. creator ask after routger's two). Opened O_APPEND, never truncated: the file
  64. is created (at `mode`, default 0600, same as writeFile) if it is not there
  65. yet, and every call after that lands its bytes after whatever is already on
  66. disk. `writeFile`'s atomicity is a RENAME over a temp file — there is no
  67. "old" or "new" whole file to swap here, since an append MUTATES the one
  68. that is already there — but O_APPEND carries its own, narrower guarantee:
  69. the kernel positions a single write() at the CURRENT end of file and
  70. performs it as one operation, so two processes each appending one line
  71. never interleave their bytes mid-line, and a reader never sees a torn
  72. append. That is what "a single write of a line lands whole" buys — call it
  73. once per line (or per record) you want that guarantee for.
  74. `contents` is a String or a Bytes (ticket #88), same as writeFile: a Bytes
  75. is appended raw, byte for byte. *\
  76. appendFile(
  77. String path
  78. contents \\ a String or a Bytes
  79. Number mode
  80. ) {
  81. if (hlTypeName(contents) == 'Bytes') {
  82. return __native("fs.append_file_hex", path, contents.hex(), mode)
  83. }
  84. return __native("fs.append_file", path, contents, mode)
  85. }
  86. \* Make a directory and every missing parent. Already-there is SUCCESS: the
  87. caller wants the directory to exist, not to be the one who created it.
  88. `mode` defaults to 0700. *\
  89. mkDir(String path, Number mode) {
  90. return __native("fs.mk_dir", path, mode)
  91. }
  92. \* Delete a path. IDEMPOTENT: true when the path is gone on return, and a path
  93. that was already gone counts. A sweep must not fail because something else
  94. deleted the file first. *\
  95. remove(String path) {
  96. return __native("fs.remove", path)
  97. }

Branches

Latest commits

  • 38f9d10ftickets: Hybriel master 06617221 (plugin allocators 3a781359 + 413f60e4, mpackdb 2cb7ae5e, http1 773de63e); gate 249/0, connect 60/0mre
  • d3db6139tickets: Hybriel master 190aa11d (fc838894 GC correctness, #126 closure scopes, #127); gate 249/0, connect 60/0mre
  • bce182e3tickets: Hybriel master 7eea0d32 (#126 memory, #48 lambda copies its argument); migrate.hl lambdas take &logmre
  • 4137be0fantcolony#40: mission references point to the moved missionsmre
  • 9bfba36aantcolony#40: history (LOG.md), worker briefs (missions/) and reports moved here from antcolony, numbered per project; old numbers in antcolony docs/mission-map.mdmre
  • c7bd2645tickets: Hybriel master 73267707 (#122 fixed); compactNow workaround removed (#110 covered)mre
  • 2ab91ee9tickets: gate checks rows appear once (session sync); re-vendor to ff51cf46 stopped on hybriel#122, stays 837fe120mre
  • e01c2b1dtickets#24: installable app (manifest, service worker, offline list), own icon; gate waits for the hello's pongmre
  • 752fbb7fdeploy.sh: back up live storage/.sessions/.env before every deploy (newest 5 kept)mre
  • 38bdd5e4deploy.sh: never send .git or .gitignore to Byrodinmre
  • f12fa1bcState of 2026-09-27, before the move to gitoriamre