Merge remote-tracking branch 'locpyl-tidnyd/mingw-port' into jb/rc

* locpyl-tidnyd/mingw-port: (136 commits)
  compat: minor refactoring
  compat: add m1brew
  compat: mingw: fix dependency patch path
  compat: mingw: put downloaded dependencies under $NIX_STORE (default to pkg/build so that git ignores them)
  compat: mingw: add seh_handler_decorator comments, move SEH handler to compat/mingw/seh_handler.c
  vere: update argon2u dependency to urbit/argon2@a4c1e3f7
  compat: fix missing newlines at end of file
  vere: ignore more intermediate build files
  vere: mingw: fix seh_handler_decorator.mk
  vere: mingw: get rid of libsigsegv
  vere: mingw: bump curl version and get rid of CURLOPT_SSL_CTX_FUNCTION typecheck warning
  vere: get rid of curl typecheck warnings for CURLOPT_WRITEFUNCTION
  mingw: add rsignal_raise to rsignal.h; raise on same thread
  u3: Makefile: include compat/*/*.mk
  mingw: rerun build action
  graph-validators: hotfix broken vale:dais caused by removal of +bunt from clay
  kiln: don't crash on fuse
  clay: formatting
  pill: update
  zuse: added +ram method to ordered map and made comments on methods accurate
  ...
This commit is contained in:
Joe Bryan 2021-07-15 13:34:13 -04:00
commit 07e2a6ba0d
102 changed files with 5267 additions and 1001 deletions

View File

@ -116,3 +116,24 @@ jobs:
- run: nix-build -A hs.urbit-king.components.exes.urbit-king --arg enableStatic true - run: nix-build -A hs.urbit-king.components.exes.urbit-king --arg enableStatic true
- run: nix-build -A hs-checks - run: nix-build -A hs-checks
- run: nix-build shell.nix - run: nix-build shell.nix
mingw:
runs-on: windows-latest
defaults:
run:
shell: C:\msys64\msys2_shell.cmd -mingw64 -defterm -no-start -here -c ". <(cygpath '{0}')"
working-directory: ./pkg/urbit
steps:
- uses: actions/checkout@v2
with:
lfs: true
# echo suppresses pacman prompt
- run: echo|./configure
env:
CACHIX_CACHE: locpyl-tidnyd-test1
CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }}
- run: make build/urbit build/urbit-worker
- run: build/urbit -l -d -B ../../bin/solid.pill -F bus && curl -f --data '{"source":{"dojo":"+hood/exit"},"sink":{"app":"hood"}}' http://localhost:12321

1
.gitignore vendored
View File

@ -54,6 +54,7 @@ release/
dist/ dist/
out/ out/
work/ work/
pkg/*/*.a
*.o *.o
# Landscape Dev # Landscape Dev

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:d7b7cf24e56ab078cf1dcb82e4e7744f188c5221c08772d6cfb15f59ce81aaa5 oid sha256:88acd8aa1aae3d11579ada954b6e0b06c940de7856d22017cc1a1442de97fcf3
size 11198219 size 13650762

90
nix/sources-pmnsh.json Normal file
View File

@ -0,0 +1,90 @@
{
"curl": {
"branch": "master",
"description": "A command line tool and library for transferring data with URL syntax",
"homepage": "http://curl.se/",
"pmnsh": {
"include": "include",
"lib": "lib/.libs",
"prepare": "autoreconf -vfi && ./configure --disable-shared --disable-ldap --disable-rtsp --without-brotli --without-libidn2 --without-libpsl --without-nghttp2 --with-openssl",
"make": "-C lib libcurl.la"
},
"owner": "curl",
"repo": "curl",
"rev": "curl-7_77_0",
"type": "tarball",
"url": "https://github.com/curl/curl/archive/curl-7_77_0.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"lmdb": {
"branch": "mdb.master",
"description": "LMDB library",
"homepage": "http://www.lmdb.tech/",
"pmnsh": {
"strip": 2,
"make": "liblmdb.a"
},
"owner": "LMDB",
"repo": "lmdb",
"rev": "48a7fed59a8aae623deff415dda27097198ca0c1",
"type": "tarball",
"url": "https://github.com/LMDB/lmdb/archive/48a7fed59a8aae623deff415dda27097198ca0c1.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"secp256k1": {
"branch": "master",
"description": "Optimized C library for ECDSA signatures and secret/public key operations on curve secp256k1.",
"homepage": null,
"pmnsh": {
"include": "include",
"lib": ".libs",
"prepare": "./autogen.sh && ./configure --disable-shared --enable-module-recovery CFLAGS=-DSECP256K1_API=",
"make": "libsecp256k1.la"
},
"owner": "bitcoin-core",
"repo": "secp256k1",
"rev": "26de4dfeb1f1436dae1fcf17f57bdaa43540f940",
"type": "tarball",
"url": "https://github.com/bitcoin-core/secp256k1/archive/26de4dfeb1f1436dae1fcf17f57bdaa43540f940.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"uv": {
"branch": "v1.x",
"description": "Cross-platform asynchronous I/O",
"homepage": "http://libuv.org/",
"pmnsh": {
"include": "include",
"lib": ".libs",
"prepare": "./autogen.sh && ./configure --disable-shared",
"make": "libuv.la",
"compat": {
"m1brew": false
}
},
"owner": "libuv",
"repo": "libuv",
"rev": "v1.40.0",
"type": "tarball",
"url": "https://github.com/libuv/libuv/archive/v1.40.0.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"ent": {
"pmnsh": {
"prepare": "./configure"
}
},
"ge-additions": {
"pmnsh": {
"make": "CFLAGS=-I../ed25519"
}
},
"libaes_siv": {
"pmnsh": {
"compat": {
"m1brew": {
"make": "CFLAGS=$(pkg-config --cflags openssl)"
}
}
}
}
}

View File

@ -3,18 +3,26 @@
"branch": "master", "branch": "master",
"description": "With argon2u. Based off https://github.com/P-H-C/phc-winner-argon2", "description": "With argon2u. Based off https://github.com/P-H-C/phc-winner-argon2",
"homepage": "", "homepage": "",
"pmnsh": {
"include": ["include", "src/blake2"],
"make": "libargon2.a"
},
"owner": "urbit", "owner": "urbit",
"repo": "argon2", "repo": "argon2",
"rev": "4da94a611ee62bad87ab2b131ffda3bcc0723d9c", "rev": "a4c1e3f7138c2e577376beb99f964cf71e1c8b1b",
"sha256": "0bqq1hg367l4jkb6cqhxlblpvdbwz3l586qsfakwzfd9wdvnm3yc", "sha256": "1j8a15fx2kn5aa3scmb5qnsfk627kfvsq5ppz9j0pv2d1xck527x",
"type": "tarball", "type": "tarball",
"url": "https://github.com/urbit/argon2/archive/4da94a611ee62bad87ab2b131ffda3bcc0723d9c.tar.gz", "url": "https://github.com/urbit/argon2/archive/a4c1e3f7138c2e577376beb99f964cf71e1c8b1b.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz" "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
}, },
"ed25519": { "ed25519": {
"branch": "master", "branch": "master",
"description": "Submodule included by Urbit", "description": "Submodule included by Urbit",
"homepage": null, "homepage": null,
"pmnsh": {
"strip": 1,
"make": "all"
},
"owner": "urbit", "owner": "urbit",
"repo": "ed25519", "repo": "ed25519",
"rev": "76385f2ebbbc9580a9c236952d68d11d73a6135c", "rev": "76385f2ebbbc9580a9c236952d68d11d73a6135c",
@ -24,15 +32,25 @@
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz" "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
}, },
"h2o": { "h2o": {
"branch": "v2.2.x", "branch": "master",
"description": "H2O - the optimized HTTP/1, HTTP/2, HTTP/3 server", "description": "H2O - the optimized HTTP/1, HTTP/2, HTTP/3 server",
"homepage": "https://h2o.examp1e.net", "homepage": "https://h2o.examp1e.net",
"pmnsh": {
"include": "include",
"prepare": "cmake .",
"make": "libh2o",
"compat": {
"mingw": {
"prepare": "cmake -G\"MSYS Makefiles\" ."
}
}
},
"owner": "h2o", "owner": "h2o",
"repo": "h2o", "repo": "h2o",
"rev": "7359e98d78d018a35f5da7523feac69f64eddb4b", "rev": "v2.2.6",
"sha256": "0qni676wqvxx0sl0pw9j0ph7zf2krrzqc1zwj73mgpdnsr8rsib7", "sha256": "0qni676wqvxx0sl0pw9j0ph7zf2krrzqc1zwj73mgpdnsr8rsib7",
"type": "tarball", "type": "tarball",
"url": "https://github.com/h2o/h2o/archive/7359e98d78d018a35f5da7523feac69f64eddb4b.tar.gz", "url": "https://github.com/h2o/h2o/archive/v2.2.6.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz" "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
}, },
"hackage.nix": { "hackage.nix": {
@ -63,6 +81,9 @@
"branch": "master", "branch": "master",
"description": null, "description": null,
"homepage": null, "homepage": null,
"pmnsh": {
"make": "libscrypt.a CFLAGS_EXTRA=-ffast-math"
},
"owner": "urbit", "owner": "urbit",
"repo": "libscrypt", "repo": "libscrypt",
"rev": "029693ff1cbe4f69d3a2da87d0f4f034f92cc0c2", "rev": "029693ff1cbe4f69d3a2da87d0f4f034f92cc0c2",
@ -75,6 +96,9 @@
"branch": "master", "branch": "master",
"description": null, "description": null,
"homepage": null, "homepage": null,
"pmnsh": {
"make": "static"
},
"owner": "urbit", "owner": "urbit",
"repo": "murmur3", "repo": "murmur3",
"rev": "71a75d57ca4e7ca0f7fc2fd84abd93595b0624ca", "rev": "71a75d57ca4e7ca0f7fc2fd84abd93595b0624ca",
@ -111,6 +135,19 @@
"branch": "master", "branch": "master",
"description": null, "description": null,
"homepage": null, "homepage": null,
"pmnsh": {
"include": "source/include",
"compat": {
"m1brew": {
"lib": "build/template-FAST_INT64",
"make": "-C build/template-FAST_INT64 libsoftfloat3.a"
},
"mingw": {
"lib": "build/Win64-MinGW-w64",
"make": "-C build/Win64-MinGW-w64 libsoftfloat3.a"
}
}
},
"owner": "urbit", "owner": "urbit",
"repo": "berkeley-softfloat-3", "repo": "berkeley-softfloat-3",
"rev": "ec4c7e31b32e07aad80e52f65ff46ac6d6aad986", "rev": "ec4c7e31b32e07aad80e52f65ff46ac6d6aad986",

View File

@ -875,7 +875,7 @@
%ge (dy-run-generator (dy-cage p.p.p.bil) q.p.bil) %ge (dy-run-generator (dy-cage p.p.p.bil) q.p.bil)
%sa %sa
=+ .^(=dais:clay cb+(en-beam he-beak /[p.bil])) =+ .^(=dais:clay cb+(en-beam he-beak /[p.bil]))
(dy-hand p.bil bunt:dais) (dy-hand p.bil *vale:dais)
:: ::
%as %as
=/ cag=cage (dy-cage p.q.bil) =/ cag=cage (dy-cage p.q.bil)

View File

@ -1,6 +1,5 @@
:: graph-store [landscape] :: graph-store [landscape]
:: ::
::
/+ store=graph-store, sigs=signatures, res=resource, default-agent, dbug, verb /+ store=graph-store, sigs=signatures, res=resource, default-agent, dbug, verb
~% %graph-store-top ..part ~ ~% %graph-store-top ..part ~
|% |%
@ -724,7 +723,7 @@
:+ %add-nodes :+ %add-nodes
[ship term] [ship term]
%- ~(gas by *(map index:store node:store)) %- ~(gas by *(map index:store node:store))
%+ turn (tap:orm `graph:store`(subset:orm p.u.graph start end)) %+ turn (tap:orm `graph:store`(lot:orm p.u.graph start end))
|= [=atom =node:store] |= [=atom =node:store]
^- [index:store node:store] ^- [index:store node:store]
[~[atom] node] [~[atom] node]
@ -775,7 +774,7 @@
%+ turn %+ turn
=- ?.(older (slag (safe-sub (lent -) count) -) (scag count -)) =- ?.(older (slag (safe-sub (lent -) count) -) (scag count -))
%- tap:orm %- tap:orm
%+ subset:orm u.graph %+ lot:orm u.graph
=/ idx =/ idx
(snag (dec (lent index)) index) (snag (dec (lent index)) index)
?:(older [`idx ~] [~ `idx]) ?:(older [`idx ~] [~ `idx])
@ -826,7 +825,7 @@
:+ %add-nodes :+ %add-nodes
[ship term] [ship term]
%- ~(gas by *(map index:store node:store)) %- ~(gas by *(map index:store node:store))
%+ turn (tap:orm `graph:store`(subset:orm p.children.u.node end start)) %+ turn (tap:orm `graph:store`(lot:orm p.children.u.node end start))
|= [=atom =node:store] |= [=atom =node:store]
^- [index:store node:store] ^- [index:store node:store]
[(snoc index atom) node] [(snoc index atom) node]
@ -840,7 +839,7 @@
=/ update-log=(unit update-log:store) (~(get by update-logs) [ship term]) =/ update-log=(unit update-log:store) (~(get by update-logs) [ship term])
?~ update-log [~ ~] ?~ update-log [~ ~]
:: orm-log is ordered backwards, so swap start and end :: orm-log is ordered backwards, so swap start and end
``noun+!>((subset:orm-log u.update-log end start)) ``noun+!>((lot:orm-log u.update-log end start))
:: ::
[%x %update-log @ @ ~] [%x %update-log @ @ ~]
=/ =ship (slav %p i.t.t.path) =/ =ship (slav %p i.t.t.path)
@ -858,7 +857,7 @@
%+ biff m-update-log %+ biff m-update-log
|= =update-log:store |= =update-log:store
=/ result=(unit [=time =update:store]) =/ result=(unit [=time =update:store])
(peek:orm-log:store update-log) (pry:orm-log:store update-log)
(bind result |=([=time update:store] time)) (bind result |=([=time update:store] time))
== ==
:: ::

View File

@ -256,7 +256,7 @@
=/ graph=graph:graph-store :: graph in subscription is bunted =/ graph=graph:graph-store :: graph in subscription is bunted
(get-graph-mop:gra rid) (get-graph-mop:gra rid)
=/ node=(unit node:graph-store) =/ node=(unit node:graph-store)
(bind (peek:orm:graph-store graph) |=([@ =node:graph-store] node)) (bind (pry:orm:graph-store graph) |=([@ =node:graph-store] node))
=/ assoc=(unit association:metadata) =/ assoc=(unit association:metadata)
(peek-association:met %graph rid) (peek-association:met %graph rid)
=^ cards state =^ cards state

View File

@ -0,0 +1,15 @@
:: Kiln: Fuse local desk from (optionally-)foreign sources
::
:::: /hoon/fuse/hood/gen
::
/* help-text %txt /gen/hood/fuse/help/txt
=, clay
::
::::
::
:- %say
|= [[now=@da eny=@uvJ bec=beak] [arg=[?(~ [des=desk bas=beak con=(list [beak germ]) ~])]] ~]
:- %kiln-fuse
?~ arg
((slog (turn `wain`help-text |=(=@t leaf+(trip t)))) ~)
[des bas con]:arg

View File

@ -0,0 +1,8 @@
Usage:
|fuse %destination-desk base-beak ~[[source-beak %some-germ] [another-beak %another-germ]]
A fuse replaces the contents of %destination-desk with the merge of the
specified beaks according to their merge strategies. This has no dependence
on the previous state of %destination-desk so any commits/work there will
be overwritten.

View File

@ -1,5 +1,5 @@
/- gr=group, md=metadata-store, ga=graph-store /- gr=group, md=metadata-store, ga=graph-store
/+ re=resource /+ re=resource, graph=graph-store
!: !:
:- %say :- %say
|= $: [now=@da eny=@uvJ =beak] |= $: [now=@da eny=@uvJ =beak]
@ -86,9 +86,9 @@
%+ scry update:ga %+ scry update:ga
[%x %graph-store /graph/(scot %p entity.r)/[name.r]/noun] [%x %graph-store /graph/(scot %p entity.r)/[name.r]/noun]
?> ?=(%add-graph -.q.upd) ?> ?=(%add-graph -.q.upd)
=/ mo ((ordered-map atom node:ga) gth) =* mo orm:graph
=/ week=(list [@da node:ga]) =/ week=(list [@da node:ga])
(tap:mo (subset:mo graph.q.upd ~ `(sub now ~d7))) (tap:mo (lot:mo graph.q.upd ~ `(sub now ~d7)))
:- (lent week) :- (lent week)
%~ wyt in %~ wyt in
%+ roll week %+ roll week

View File

@ -55,6 +55,12 @@
cas=case :: cas=case ::
gim=?(%auto germ) :: gim=?(%auto germ) ::
== ==
+$ kiln-fuse
$@ ~
$: syd=desk
bas=beak
con=(list [beak germ])
==
-- --
|= [bowl:gall state] |= [bowl:gall state]
?> =(src our) ?> =(src our)
@ -381,6 +387,11 @@
?~ +< abet ?~ +< abet
abet:abet:(merge:(work syd) ali sud cas gim) abet:abet:(merge:(work syd) ali sud cas gim)
:: ::
++ poke-fuse
|= k=kiln-fuse
?~ k abet
abet:(emit [%pass /kiln/fuse/[syd.k] %arvo %c [%fuse syd.k bas.k con.k]])
::
++ poke-cancel ++ poke-cancel
|= a=@tas |= a=@tas
abet:(emit %pass /cancel %arvo %c [%drop a]) abet:(emit %pass /cancel %arvo %c [%drop a])
@ -430,6 +441,7 @@
%kiln-info =;(f (f !<(_+<.f vase)) poke-info) %kiln-info =;(f (f !<(_+<.f vase)) poke-info)
%kiln-label =;(f (f !<(_+<.f vase)) poke-label) %kiln-label =;(f (f !<(_+<.f vase)) poke-label)
%kiln-merge =;(f (f !<(_+<.f vase)) poke-merge) %kiln-merge =;(f (f !<(_+<.f vase)) poke-merge)
%kiln-fuse =;(f (f !<(_+<.f vase)) poke-fuse)
%kiln-mount =;(f (f !<(_+<.f vase)) poke-mount) %kiln-mount =;(f (f !<(_+<.f vase)) poke-mount)
%kiln-ota =;(f (f !<(_+<.f vase)) poke:update) %kiln-ota =;(f (f !<(_+<.f vase)) poke:update)
%kiln-ota-info =;(f (f !<(_+<.f vase)) poke-ota-info) %kiln-ota-info =;(f (f !<(_+<.f vase)) poke-ota-info)
@ -489,6 +501,8 @@
++ take |=(way=wire ?>(?=([@ ~] way) (work i.way))) :: general handler ++ take |=(way=wire ?>(?=([@ ~] way) (work i.way))) :: general handler
++ take-mere :: ++ take-mere ::
|= [way=wire are=(each (set path) (pair term tang))] |= [way=wire are=(each (set path) (pair term tang))]
?. ?=([@ ~] way)
abet
abet:abet:(mere:(take way) are) abet:abet:(mere:(take way) are)
:: ::
++ take-coup-fancy :: ++ take-coup-fancy ::

View File

@ -21,7 +21,10 @@
(most ;~(plug com gaw) taut-rule) (most ;~(plug com gaw) taut-rule)
:: ::
%+ rune tis %+ rune tis
;~(plug sym ;~(pfix gap fas (more fas urs:ab))) ;~(plug sym ;~(pfix gap stap))
::
%+ rune sig
;~((glue gap) sym wyde:vast stap)
:: ::
%+ rune cen %+ rune cen
;~(plug sym ;~(pfix gap ;~(pfix cen sym))) ;~(plug sym ;~(pfix gap ;~(pfix cen sym)))
@ -37,7 +40,7 @@
;~ (glue gap) ;~ (glue gap)
sym sym
;~(pfix cen sym) ;~(pfix cen sym)
;~(pfix fas (more fas urs:ab)) stap
== ==
:: ::
%+ stag %tssg %+ stag %tssg

View File

@ -490,7 +490,7 @@
=/ m (strand ,vase) =/ m (strand ,vase)
^- form:m ^- form:m
;< =riot:clay bind:m ;< =riot:clay bind:m
(warp ship desk ~ %sing %b case /[mak]) (warp ship desk ~ %sing %e case /[mak])
?~ riot ?~ riot
(strand-fail %build-nave >arg< ~) (strand-fail %build-nave >arg< ~)
?> =(%nave p.r.u.riot) ?> =(%nave p.r.u.riot)

View File

@ -33,7 +33,7 @@
++ grab ++ grab
|% |%
++ noun ++ noun
|= p=* |: p=`*`%*(. *indexed-post index.p [0 ~])
=/ ip ;;(indexed-post p) =/ ip ;;(indexed-post p)
?> ?=([@ ~] index.p.ip) ?> ?=([@ ~] index.p.ip)
ip ip

View File

@ -49,7 +49,7 @@
++ grab ++ grab
|% |%
++ noun ++ noun
|= p=* |: p=`*`%*(. *indexed-post index.p [0 0 ~])
=/ ip ;;(indexed-post p) =/ ip ;;(indexed-post p)
?+ index.p.ip ~|(index+index.p.ip !!) ?+ index.p.ip ~|(index+index.p.ip !!)
:: top-level link post; title and url :: top-level link post; title and url

View File

@ -43,7 +43,7 @@
:: +noun: validate post :: +noun: validate post
:: ::
++ noun ++ noun
|= p=* |: p=`*`%*(. *indexed-post contents.p [%text '']~)
=/ ip ;;(indexed-post p) =/ ip ;;(indexed-post p)
?> ?=(^ contents.p.ip) ?> ?=(^ contents.p.ip)
ip ip

View File

@ -58,7 +58,7 @@
:: +noun: validate publish note :: +noun: validate publish note
:: ::
++ noun ++ noun
|= p=* |: p=`*`%*(. *indexed-post index.p [0 ~])
=/ ip ;;(indexed-post p) =/ ip ;;(indexed-post p)
?+ index.p.ip !! ?+ index.p.ip !!
:: top level post must have no content :: top level post must have no content

View File

@ -5452,12 +5452,14 @@
:::: 4k: atom printing :::: 4k: atom printing
:: ::
++ co ++ co
!:
~% %co ..co ~ ~% %co ..co ~
=< |_ lot=coin =< |_ lot=coin
++ rear |=(rom=tape rend(rep rom)) ++ rear |=(rom=tape rend(rep rom))
++ rent `@ta`(rap 3 rend) ++ rent ~+ `@ta`(rap 3 rend)
++ rend ++ rend
^- tape ^- tape
~+
?: ?=(%blob -.lot) ?: ?=(%blob -.lot)
['~' '0' ((v-co 1) (jam p.lot))] ['~' '0' ((v-co 1) (jam p.lot))]
?: ?=(%many -.lot) ?: ?=(%many -.lot)
@ -5602,18 +5604,17 @@
|= a=dn |= a=dn
?: ?=([%i *] a) (weld ?:(s.a "inf" "-inf") rep) ?: ?=([%i *] a) (weld ?:(s.a "inf" "-inf") rep)
?: ?=([%n *] a) (weld "nan" rep) ?: ?=([%n *] a) (weld "nan" rep)
=/ f=(pair tape @) =; rep ?:(s.a rep ['-' rep])
%. a.a =/ f ((d-co 1) a.a)
%+ ed-co(rep ~) [10 1] =^ e e.a
|=([a=? b=@ c=tape] [~(d ne b) ?.(a c ['.' c])]) =/ e=@s (sun:si (lent f))
=. e.a (sum:si e.a (sun:si (dec q.f))) =/ sci :(sum:si e.a e -1)
=/ res ?: (syn:si (dif:si e.a --3)) [--1 sci] :: 12000 -> 12e3 e>+2
%+ weld p.f ?: !(syn:si (dif:si sci -2)) [--1 sci] :: 0.001 -> 1e-3 e<-2
?~ e.a [(sum:si sci --1) --0] :: 1.234e2 -> '.'@3 -> 123 .4
rep =? rep !=(--0 e.a)
%+ weld ?:((syn:si e.a) "e" "e-") :(weld ?:((syn:si e.a) "e" "e-") ((d-co 1) (abs:si e.a)))
((d-co 1) (abs:si e.a)) (weld (ed-co e f) rep)
?:(s.a res ['-' res])
:: ::
++ s-co ++ s-co
|= esc=(list @) ^- tape |= esc=(list @) ^- tape
@ -5659,20 +5660,13 @@
:: - used only for @r* floats :: - used only for @r* floats
:: ::
++ ed-co ++ ed-co
|= [[bas=@ min=@] par=$-([? @ tape] tape)] |= [exp=@s int=tape] ^- tape
=| [fir=? cou=@ud] =/ [pos=? dig=@u] [=(--1 (cmp:si exp --0)) (abs:si exp)]
|= hol=@ ?. pos
^- [tape @] (into (weld (reap +(dig) '0') int) 1 '.')
?: &(=(0 hol) =(0 min)) =/ len (lent int)
[rep cou] ?: (lth dig len) (into int dig '.')
=/ [dar=@ rad=@] (dvr hol bas) (weld int (reap (sub dig len) '0'))
%= $
min ?:(=(0 min) 0 (dec min))
hol dar
rep (par &(=(0 dar) !fir) rad rep)
fir |
cou +(cou)
==
:: ::
:: +ox-co: format '.'-separated digit sequences in numeric base :: +ox-co: format '.'-separated digit sequences in numeric base
:: ::
@ -5965,9 +5959,8 @@
:: ::
++ spat |=(pax=path (crip (spud pax))) :: render path to cord ++ spat |=(pax=path (crip (spud pax))) :: render path to cord
++ spud |=(pax=path ~(ram re (smyt pax))) :: render path to tape ++ spud |=(pax=path ~(ram re (smyt pax))) :: render path to tape
++ stab :: parse cord to path ++ stab |=(zep=@t `path`(rash zep stap)) :: parse cord to path
=+ fel=;~(pfix fas (more fas urs:ab)) ++ stap ;~(pfix fas (more fas urs:ab)) :: path parser
|=(zep=@t `path`(rash zep fel))
:: ::
:::: 4n: virtualization :::: 4n: virtualization
:: ::
@ -6627,7 +6620,7 @@
+$ seminoun +$ seminoun
:: partial noun; blocked subtrees are ~ :: partial noun; blocked subtrees are ~
:: ::
$~ [[%full ~] ~] $~ [[%full / ~ ~] ~]
[mask=stencil data=noun] [mask=stencil data=noun]
:: ::
:: +stencil: noun knowledge map :: +stencil: noun knowledge map

View File

@ -762,6 +762,11 @@
her=@p dem=desk cas=case :: source her=@p dem=desk cas=case :: source
how=germ :: method how=germ :: method
== :: == ::
$: %fuse :: merge many
des=desk :: target desk
bas=beak :: base desk
con=(list [beak germ]) :: merges
==
[%mont pot=term bem=beam] :: mount to unix [%mont pot=term bem=beam] :: mount to unix
[%dirk des=desk] :: mark mount dirty [%dirk des=desk] :: mark mount dirty
[%ogre pot=$@(desk beam)] :: delete mount point [%ogre pot=$@(desk beam)] :: delete mount point
@ -928,6 +933,7 @@
:: /- sur-file :: surface imports from /sur :: /- sur-file :: surface imports from /sur
:: /+ lib-file :: library imports from /lib :: /+ lib-file :: library imports from /lib
:: /= face /path :: imports built hoon file at path :: /= face /path :: imports built hoon file at path
:: /~ face type /path :: imports built hoon files from directory
:: /% face %mark :: imports mark definition from /mar :: /% face %mark :: imports mark definition from /mar
:: /$ face %from %to :: imports mark converter from /mar :: /$ face %from %to :: imports mark converter from /mar
:: /* face %mark /path :: unbuilt file imports, as mark :: /* face %mark /path :: unbuilt file imports, as mark
@ -936,6 +942,7 @@
$: sur=(list taut) $: sur=(list taut)
lib=(list taut) lib=(list taut)
raw=(list [face=term =path]) raw=(list [face=term =path])
raz=(list [face=term =spec =path])
maz=(list [face=term =mark]) maz=(list [face=term =mark])
caz=(list [face=term =mars]) caz=(list [face=term =mars])
bar=(list [face=term =mark =path]) bar=(list [face=term =mark =path])
@ -955,7 +962,6 @@
$_ $_
^? ^?
|% |%
++ bunt *typ
++ diff |~([old=typ new=typ] *dif) ++ diff |~([old=typ new=typ] *dif)
++ form *mark ++ form *mark
++ join |~([a=dif b=dif] *(unit (unit dif))) ++ join |~([a=dif b=dif] *(unit (unit dif)))
@ -970,7 +976,6 @@
+$ dais +$ dais
$_ ^| $_ ^|
|_ sam=vase |_ sam=vase
++ bunt sam
++ diff |~(new=_sam *vase) ++ diff |~(new=_sam *vase)
++ form *mark ++ form *mark
++ join |~([a=vase b=vase] *(unit (unit vase))) ++ join |~([a=vase b=vase] *(unit (unit vase)))

View File

@ -1944,11 +1944,11 @@
=/ =bone bone.shut-packet =/ =bone bone.shut-packet
:: ::
?: ?=(%& -.meat.shut-packet) ?: ?=(%& -.meat.shut-packet)
=+ ?~ dud ~ =+ ?. &(?=(^ dud) msg.veb) ~
%. ~ %. ~
%+ slog %- slog
:_ tang.u.dud
leaf+"ames: {<her.channel>} fragment crashed {<mote.u.dud>}" leaf+"ames: {<her.channel>} fragment crashed {<mote.u.dud>}"
?.(msg.veb ~ tang.u.dud)
(run-message-sink bone %hear lane shut-packet ?=(~ dud)) (run-message-sink bone %hear lane shut-packet ?=(~ dud))
:: Just try again on error, printing trace :: Just try again on error, printing trace
:: ::
@ -1967,20 +1967,12 @@
++ on-memo ++ on-memo
|= [=bone payload=* valence=?(%plea %boon)] |= [=bone payload=* valence=?(%plea %boon)]
^+ peer-core ^+ peer-core
:: if we haven't been trying to talk to %live, reset timer
::
=? last-contact.qos.peer-state
?& ?=(%live -.qos.peer-state)
%- ~(all by snd.peer-state)
|= =message-pump-state
=(~ live.packet-pump-state.message-pump-state)
==
now
::
=/ =message-blob (dedup-message (jim payload)) =/ =message-blob (dedup-message (jim payload))
=. peer-core (run-message-pump bone %memo message-blob) =. peer-core (run-message-pump bone %memo message-blob)
:: ::
?: &(=(%boon valence) ?=(?(%dead %unborn) -.qos.peer-state)) ?: ?& =(%boon valence)
(gte now (add ~s30 last-contact.qos.peer-state))
==
check-clog check-clog
peer-core peer-core
:: +dedup-message: replace with any existing copy of this message :: +dedup-message: replace with any existing copy of this message
@ -2535,7 +2527,7 @@
++ assert ++ assert
^+ message-pump ^+ message-pump
=/ top-live =/ top-live
(peek:packet-queue:*make-packet-pump live.packet-pump-state.state) (pry:packet-queue:*make-packet-pump live.packet-pump-state.state)
?. |(?=(~ top-live) (lte current.state message-num.key.u.top-live)) ?. |(?=(~ top-live) (lte current.state message-num.key.u.top-live))
~| [%strange-current current=current.state key.u.top-live] ~| [%strange-current current=current.state key.u.top-live]
!! !!
@ -2603,7 +2595,7 @@
=| acc=(unit static-fragment) =| acc=(unit static-fragment)
^+ [static-fragment=acc live=live.state] ^+ [static-fragment=acc live=live.state]
:: ::
%^ (traverse:packet-queue _acc) live.state acc %^ (dip:packet-queue _acc) live.state acc
|= $: acc=_acc |= $: acc=_acc
key=live-packet-key key=live-packet-key
val=live-packet-val val=live-packet-val
@ -2681,7 +2673,7 @@
=/ acc =/ acc
resends=*(list static-fragment) resends=*(list static-fragment)
:: ::
%^ (traverse:packet-queue _acc) live.state acc %^ (dip:packet-queue _acc) live.state acc
|= $: acc=_acc |= $: acc=_acc
key=live-packet-key key=live-packet-key
val=live-packet-val val=live-packet-val
@ -2734,7 +2726,7 @@
:: ::
^+ [acc live=live.state] ^+ [acc live=live.state]
:: ::
%^ (traverse:packet-queue _acc) live.state acc %^ (dip:packet-queue _acc) live.state acc
|= $: acc=_acc |= $: acc=_acc
key=live-packet-key key=live-packet-key
val=live-packet-val val=live-packet-val
@ -2781,7 +2773,7 @@
:: ::
^+ [metrics=metrics.state live=live.state] ^+ [metrics=metrics.state live=live.state]
:: ::
%^ (traverse:packet-queue pump-metrics) live.state acc=metrics.state %^ (dip:packet-queue pump-metrics) live.state acc=metrics.state
|= $: metrics=pump-metrics |= $: metrics=pump-metrics
key=live-packet-key key=live-packet-key
val=live-packet-val val=live-packet-val
@ -2804,10 +2796,10 @@
:: ::
++ set-wake ++ set-wake
^+ packet-pump ^+ packet-pump
:: if nonempty .live, peek at head to get next wake time :: if nonempty .live, pry at head to get next wake time
:: ::
=/ new-wake=(unit @da) =/ new-wake=(unit @da)
?~ head=(peek:packet-queue live.state) ?~ head=(pry:packet-queue live.state)
~ ~
`(next-expiry:gauge u.head) `(next-expiry:gauge u.head)
:: no-op if no change :: no-op if no change

View File

@ -186,7 +186,7 @@
=* timers timers.state =* timers timers.state
:: if no timers, cancel existing wakeup timer or no-op :: if no timers, cancel existing wakeup timer or no-op
:: ::
=/ first=(unit [date=@da *]) (peek:timer-map timers.state) =/ first=(unit [date=@da *]) (pry:timer-map timers.state)
?~ first ?~ first
?~ next-wake ?~ next-wake
event-core event-core
@ -351,7 +351,7 @@
[%timers %next ~] [%timers %next ~]
:^ ~ ~ %noun :^ ~ ~ %noun
!> ^- (unit @da) !> ^- (unit @da)
(bind (peek:timer-map timers) head) (bind (pry:timer-map timers) head)
:: ::
[%timers @ ~] [%timers @ ~]
?~ til=(slaw %da i.t.tyl) ?~ til=(slaw %da i.t.tyl)

View File

@ -59,6 +59,12 @@
:: ::
+$ cult (jug wove duct) +$ cult (jug wove duct)
:: ::
:: State for ongoing %fuse merges. `con` maintains the ordering,
:: `sto` stores the data needed to merge, and `bas` is the base
:: beak for the merge.
::
+$ melt [bas=beak con=(list [beak germ]) sto=(map beak (unit dome:clay))]
::
:: Domestic desk state. :: Domestic desk state.
:: ::
:: Includes subscriber list, dome (desk content), possible commit state (for :: Includes subscriber list, dome (desk content), possible commit state (for
@ -69,6 +75,7 @@
dom=dome :: desk state dom=dome :: desk state
per=regs :: read perms per path per=regs :: read perms per path
pew=regs :: write perms per path pew=regs :: write perms per path
fiz=melt :: state for mega merges
== ==
:: ::
:: Desk state. :: Desk state.
@ -118,11 +125,11 @@
:: Ford cache :: Ford cache
:: ::
+$ ford-cache +$ ford-cache
$: files=(map path [res=vase dez=(set path)]) $: files=(map path [res=vase dez=(set [dir=? =path])])
naves=(map mark [res=vase dez=(set path)]) naves=(map mark [res=vase dez=(set [dir=? =path])])
marks=(map mark [res=dais dez=(set path)]) marks=(map mark [res=dais dez=(set [dir=? =path])])
casts=(map mars [res=vase dez=(set path)]) casts=(map mars [res=vase dez=(set [dir=? =path])])
tubes=(map mars [res=tube dez=(set path)]) tubes=(map mars [res=tube dez=(set [dir=? =path])])
== ==
:: $reef-cache: built system files :: $reef-cache: built system files
:: ::
@ -212,6 +219,7 @@
dom=dome :: revision state dom=dome :: revision state
per=regs :: read perms per path per=regs :: read perms per path
pew=regs :: write perms per path pew=regs :: write perms per path
fiz=melt :: domestic mega merges
== :: == ::
:: ::
:: Foreign request manager. :: Foreign request manager.
@ -303,6 +311,7 @@
$: %c :: to %clay $: %c :: to %clay
$> $? %info :: internal edit $> $? %info :: internal edit
%merg :: merge desks %merg :: merge desks
%fuse :: merge many
%pork :: %pork ::
%warp :: %warp ::
%werp :: %werp ::
@ -428,18 +437,23 @@
:: ::
++ an ++ an
|_ nak=ankh |_ nak=ankh
:: +dug: produce ankh at path
::
++ dug
|= =path
^- (unit ankh)
?~ path `nak
?~ kid=(~(get by dir.nak) i.path)
~
$(nak u.kid, path t.path)
:: +get: produce file at path :: +get: produce file at path
:: ::
++ get ++ get
|= =path |= =path
^- (unit cage) ^- (unit cage)
?~ path ?~ nik=(dug path) ~
?~ fil.nak ?~ fil.u.nik ~
~ `q.u.fil.u.nik
`q.u.fil.nak
?~ kid=(~(get by dir.nak) i.path)
~
$(nak u.kid, path t.path)
-- --
++ with-face |=([face=@tas =vase] vase(p [%face face p.vase])) ++ with-face |=([face=@tas =vase] vase(p [%face face p.vase]))
++ with-faces ++ with-faces
@ -472,7 +486,7 @@
+$ state +$ state
$: baked=(map path cage) $: baked=(map path cage)
cache=ford-cache cache=ford-cache
stack=(list (set path)) stack=(list (set [dir=? =path]))
cycle=(set build) cycle=(set build)
== ==
+$ args +$ args
@ -493,8 +507,8 @@
:: +pop-stack: pop build stack, copying deps downward :: +pop-stack: pop build stack, copying deps downward
:: ::
++ pop-stack ++ pop-stack
^- [(set path) _stack.nub] ^- [(set [dir=? =path]) _stack.nub]
=^ top=(set path) stack.nub stack.nub =^ top=(set [dir=? =path]) stack.nub stack.nub
=? stack.nub ?=(^ stack.nub) =? stack.nub ?=(^ stack.nub)
stack.nub(i (~(uni in i.stack.nub) top)) stack.nub(i (~(uni in i.stack.nub) top))
[top stack.nub] [top stack.nub]
@ -559,7 +573,6 @@
=/ dif diff:deg =/ dif diff:deg
^- (nave typ dif) ^- (nave typ dif)
|% |%
++ bunt +<.cor
++ diff ++ diff
|= [old=typ new=typ] |= [old=typ new=typ]
^- dif ^- dif
@ -581,7 +594,6 @@
=/ dif _*diff:grad:cor =/ dif _*diff:grad:cor
^- (nave:clay typ dif) ^- (nave:clay typ dif)
|% |%
++ bunt +<.cor
++ diff |=([old=typ new=typ] (diff:~(grad cor old) new)) ++ diff |=([old=typ new=typ] (diff:~(grad cor old) new))
++ form form:grad:cor ++ form form:grad:cor
++ join ++ join
@ -622,7 +634,6 @@
:_ nub :_ nub
^- dais ^- dais
|_ sam=vase |_ sam=vase
++ bunt (slap nav limb/%bunt)
++ diff ++ diff
|= new=vase |= new=vase
(slam (slap nav limb/%diff) (slop sam new)) (slam (slap nav limb/%diff) (slop sam new))
@ -649,7 +660,7 @@
|= diff=vase |= diff=vase
(slam (slap nav limb/%pact) (slop sam diff)) (slam (slap nav limb/%pact) (slop sam diff))
++ vale ++ vale
|= =noun |: noun=q:(slap nav !,(*hoon *vale))
(slam (slap nav limb/%vale) noun/noun) (slam (slap nav limb/%vale) noun/noun)
-- --
:: +build-cast: produce gate to convert mark .a to, statically typed :: +build-cast: produce gate to convert mark .a to, statically typed
@ -805,9 +816,11 @@
=^ res=vase nub (run-pile pile) =^ res=vase nub (run-pile pile)
res res
:: ::
++ build-file ++ build-dependency
|= =path |= dep=(each [dir=path fil=path] path)
^- [vase state] ^- [vase state]
=/ =path
?:(?=(%| -.dep) p.dep fil.p.dep)
~| %error-building^path ~| %error-building^path
?^ got=(~(get by files.cache.nub) path) ?^ got=(~(get by files.cache.nub) path)
=? stack.nub ?=(^ stack.nub) =? stack.nub ?=(^ stack.nub)
@ -816,7 +829,9 @@
?: (~(has in cycle.nub) file+path) ?: (~(has in cycle.nub) file+path)
~|(cycle+file+path^stack.nub !!) ~|(cycle+file+path^stack.nub !!)
=. cycle.nub (~(put in cycle.nub) file+path) =. cycle.nub (~(put in cycle.nub) file+path)
=. stack.nub [(sy path ~) stack.nub] =. stack.nub
=- [(sy - ~) stack.nub]
?:(?=(%| -.dep) dep [& dir.p.dep])
=^ cag=cage nub (read-file path) =^ cag=cage nub (read-file path)
?> =(%hoon p.cag) ?> =(%hoon p.cag)
=/ tex=tape (trip !<(@t q.cag)) =/ tex=tape (trip !<(@t q.cag))
@ -826,11 +841,42 @@
=. files.cache.nub (~(put by files.cache.nub) path [res top]) =. files.cache.nub (~(put by files.cache.nub) path [res top])
[res nub] [res nub]
:: ::
++ build-file
|= =path
(build-dependency |+path)
:: +build-directory: builds files in top level of a directory
::
:: this excludes files directly at /path/hoon,
:: instead only including files in the unix-style directory at /path,
:: such as /path/file/hoon, but not /path/more/file/hoon.
::
++ build-directory
|= =path
^- [(map @ta vase) state]
=/ fiz=(list @ta)
=/ nuk=(unit _ankh) (~(dug an ankh) path)
?~ nuk ~
%+ murn
~(tap by dir.u.nuk)
|= [nom=@ta nak=_ankh]
?. ?=([~ [~ *] *] (~(get by dir.nak) %hoon)) ~
`nom
::
=| rez=(map @ta vase)
|-
?~ fiz
[rez nub]
=* nom=@ta i.fiz
=/ pax=^path (weld path nom %hoon ~)
=^ res nub (build-dependency &+[path pax])
$(fiz t.fiz, rez (~(put by rez) nom res))
::
++ run-pile ++ run-pile
|= =pile |= =pile
=^ sut=vase nub (run-tauts bud %sur sur.pile) =^ sut=vase nub (run-tauts bud %sur sur.pile)
=^ sut=vase nub (run-tauts sut %lib lib.pile) =^ sut=vase nub (run-tauts sut %lib lib.pile)
=^ sut=vase nub (run-raw sut raw.pile) =^ sut=vase nub (run-raw sut raw.pile)
=^ sut=vase nub (run-raz sut raz.pile)
=^ sut=vase nub (run-maz sut maz.pile) =^ sut=vase nub (run-maz sut maz.pile)
=^ sut=vase nub (run-caz sut caz.pile) =^ sut=vase nub (run-caz sut caz.pile)
=^ sut=vase nub (run-bar sut bar.pile) =^ sut=vase nub (run-bar sut bar.pile)
@ -869,7 +915,10 @@
(most ;~(plug com gaw) taut-rule) (most ;~(plug com gaw) taut-rule)
:: ::
%+ rune tis %+ rune tis
;~(plug sym ;~(pfix gap fas (more fas urs:ab))) ;~(plug sym ;~(pfix gap stap))
::
%+ rune sig
;~((glue gap) sym wyde:vast stap)
:: ::
%+ rune cen %+ rune cen
;~(plug sym ;~(pfix gap ;~(pfix cen sym))) ;~(plug sym ;~(pfix gap ;~(pfix cen sym)))
@ -885,7 +934,7 @@
;~ (glue gap) ;~ (glue gap)
sym sym
;~(pfix cen sym) ;~(pfix cen sym)
;~(pfix fas (more fas urs:ab)) ;~(pfix stap)
== ==
:: ::
%+ stag %tssg %+ stag %tssg
@ -931,6 +980,30 @@
=. p.pin [%face face.i.raw p.pin] =. p.pin [%face face.i.raw p.pin]
$(sut (slop pin sut), raw t.raw) $(sut (slop pin sut), raw t.raw)
:: ::
++ run-raz
|= [sut=vase raz=(list [face=term =spec =path])]
^- [vase state]
?~ raz [sut nub]
=^ res=(map @ta vase) nub
(build-directory path.i.raz)
=; pin=vase
=. p.pin [%face face.i.raz p.pin]
$(sut (slop pin sut), raz t.raz)
::
=/ =type (~(play ut p.sut) [%kttr spec.i.raz])
:: ensure results nest in the specified type,
:: and produce a homogenous map containing that type.
::
:- %- ~(play ut p.sut)
[%kttr %make [%wing ~[%map]] ~[[%base %atom %ta] spec.i.raz]]
|-
?~ res ~
?. (~(nest ut type) | p.q.n.res)
~| [%nest-fail path.i.raz p.n.res]
!!
:- [p.n.res q.q.n.res]
[$(res l.res) $(res r.res)]
::
++ run-maz ++ run-maz
|= [sut=vase maz=(list [face=term =mark])] |= [sut=vase maz=(list [face=term =mark])]
^- [vase state] ^- [vase state]
@ -1043,12 +1116,12 @@
~ ~
=/ rus rus:(~(gut by hoy.ruf) her *rung) =/ rus rus:(~(gut by hoy.ruf) her *rung)
%+ ~(gut by rus) syd %+ ~(gut by rus) syd
[lim=~2000.1.1 ref=`*rind qyx=~ dom=*dome per=~ pew=~] [lim=~2000.1.1 ref=`*rind qyx=~ dom=*dome per=~ pew=~ fiz=*melt]
:: administrative duct, domestic +rede :: administrative duct, domestic +rede
:: ::
:+ ~ `hun.rom.ruf :+ ~ `hun.rom.ruf
=/ jod (~(gut by dos.rom.ruf) syd *dojo) =/ jod (~(gut by dos.rom.ruf) syd *dojo)
[lim=now ref=~ [qyx dom per pew]:jod] [lim=now ref=~ [qyx dom per pew fiz]:jod]
:: ::
=* red=rede ->+ =* red=rede ->+
|% |%
@ -1065,7 +1138,7 @@
:: ::
%= ruf %= ruf
hun.rom (need hun) hun.rom (need hun)
dos.rom (~(put by dos.rom.ruf) syd [qyx dom per pew]:red) dos.rom (~(put by dos.rom.ruf) syd [qyx dom per pew fiz]:red)
== ==
:: ::
:: Handle `%sing` requests :: Handle `%sing` requests
@ -1256,6 +1329,24 @@
=/ =path [%question desk (scot %ud index) ~] =/ =path [%question desk (scot %ud index) ~]
(emit duct %pass wire %a %plea ship %c path `riff-any`[%1 riff]) (emit duct %pass wire %a %plea ship %c path `riff-any`[%1 riff])
:: ::
++ foreign-capable
|= =rave
|^
?- -.rave
%many &
%sing (good-care care.mood.rave)
%next (good-care care.mood.rave)
%mult
%- ~(all in paths.mool.rave)
|= [=care =path]
(good-care care)
==
::
++ good-care
|= =care
(~(has in ^~((silt `(list ^care)`~[%u %w %x %y %z]))) care)
--
::
:: Create a request that cannot be filled immediately. :: Create a request that cannot be filled immediately.
:: ::
:: If it's a local request, we just put in in `qyx`, setting a timer if it's :: If it's a local request, we just put in in `qyx`, setting a timer if it's
@ -1275,6 +1366,10 @@
=. rave =. rave
?. ?=([%sing %v *] rave) rave ?. ?=([%sing %v *] rave) rave
[%many %| [%ud let.dom] case.mood.rave path.mood.rave] [%many %| [%ud let.dom] case.mood.rave path.mood.rave]
::
?. (foreign-capable rave)
~|([%clay-bad-foreign-request-care rave] !!)
::
=+ inx=nix.u.ref =+ inx=nix.u.ref
=. +>+.$ =. +>+.$
=< ?>(?=(^ ref) .) =< ?>(?=(^ ref) .)
@ -1582,12 +1677,19 @@
:: ::
++ invalidate ++ invalidate
|* [key=mold value=mold] |* [key=mold value=mold]
|= [cache=(map key [value dez=(set path)]) invalid=(set path)] |= [cache=(map key [value dez=(set [dir=? =path])]) invalid=(set path)]
=/ builds=(list [key value dez=(set path)]) ~(tap by cache) =/ builds=(list [key value dez=(set [dir=? =path])])
~(tap by cache)
|- ^+ cache |- ^+ cache
?~ builds ?~ builds
~ ~
?: ?=(^ (~(int in dez.i.builds) invalid)) ?: %- ~(any in dez.i.builds)
|= [dir=? =path]
?. dir (~(has in invalid) path)
=+ l=(lent path)
%- ~(any in invalid)
|= i=^path
&(=(path (scag l i)) ?=([@ %hoon ~] (slag l i)))
$(builds t.builds) $(builds t.builds)
(~(put by $(builds t.builds)) i.builds) (~(put by $(builds t.builds)) i.builds)
:: ::
@ -1962,32 +2064,178 @@
=/ =wire /merge/[syd]/(scot %p ali-ship)/[ali-desk]/[germ] =/ =wire /merge/[syd]/(scot %p ali-ship)/[ali-desk]/[germ]
(emit hen %pass wire %c %warp ali-ship ali-desk `[%sing %v case /]) (emit hen %pass wire %c %warp ali-ship ali-desk `[%sing %v case /])
:: ::
++ merge ++ make-melt
|= [=ali=ship =ali=desk =germ =riot] |= [bas=beak con=(list [beak germ])]
^+ ..merge ^- melt
|^ :+ bas con
?~ riot %- ~(gas by *(map beak (unit dome:clay)))
(done %| %ali-unavailable >[ali-ship ali-desk germ]< ~) :- [bas *(unit dome:clay)]
=/ ali-dome=dome:clay !<(dome:clay q.r.u.riot) (turn con |=(a=[beak germ] [-.a *(unit dome:clay)]))
=/ ali-yaki=yaki (~(got by hut.ran) (~(got by hit.ali-dome) let.ali-dome)) ::
=/ bob-yaki=(unit yaki) ++ start-fuse
?~ let.dom |= [bas=beak con=(list [beak germ])]
^+ ..start-fuse
=/ moves=(list move)
%+ turn
[[bas *germ] con]
|= [bec=beak germ]
^- move
=/ wir=wire /fuse/[syd]/(scot %p p.bec)/[q.bec]/(scot r.bec)
[hen %pass wir %c %warp p.bec q.bec `[%sing %v r.bec /]]
::
:: We also want to clear the state (fiz) associated with this
:: merge and print a warning if it's non trivial i.e. we're
:: starting a new fuse before the previous one terminated.
::
=/ err=tang
?~ con.fiz
~ ~
(~(get by hut.ran) (~(got by hit.dom) let.dom)) =/ discarded=tang
=/ merge-result (merge-by-germ ali-yaki bob-yaki) %+ turn
?: ?=(%| -.merge-result) ~(tap in sto.fiz)
(done %| p.merge-result) |= [k=beak v=(unit dome:clay)]
?~ p.merge-result ^- tank
(done %& ~) =/ received=tape ?~(v "missing" "received")
=. ..merge (done %& conflicts.u.p.merge-result) leaf+"{<k>} {received}"
(park | new.u.p.merge-result ~ lat.u.p.merge-result) :_ discarded
leaf+"fusing into {<syd>} from {<bas>} {<con>} - overwriting prior fuse"
=. fiz (make-melt bas con)
((slog err) (emil moves))
::
++ take-fuse
|^
::
|= [bec=beak =riot]
^+ ..take-fuse
?~ riot
::
:: By setting fiz to *melt the merge is aborted - any further
:: responses we get for the merge will cause take-fuse to crash
::
=. fiz *melt
((slog [leaf+"clay: fuse failed, missing {<bec>}"]~) ..take-fuse)
?> (~(has by sto.fiz) bec)
=. fiz
:+ bas.fiz con.fiz
(~(put by sto.fiz) bec `!<(dome:clay q.r.u.riot))
=/ all-done=flag
%- ~(all by sto.fiz)
|= res=(unit dome:clay)
^- flag
!=(res ~)
?. all-done
..take-fuse
=| rag=rang
=/ clean-state ..take-fuse
=/ initial-dome=dome:clay (need (~(got by sto.fiz) bas.fiz))
=/ continuation-yaki=yaki
(~(got by hut.ran) (~(got by hit.initial-dome) let.initial-dome))
=/ parents=(list tako) ~[(~(got by hit.initial-dome) let.initial-dome)]
=/ merges con.fiz
|-
^+ ..take-fuse
?~ merges
=/ t=tang [leaf+"{<syd>} fused from {<bas.fiz>} {<con.fiz>}" ~]
=. ..take-fuse (done-fuse clean-state %& ~)
(park | [%| continuation-yaki(p (flop parents))] rag)
=/ [bec=beak g=germ] i.merges
=/ ali-dom=dome:clay (need (~(got by sto.fiz) bec))
=/ result (merge-helper p.bec q.bec g ali-dom `continuation-yaki)
?- -.result
%|
(done-fuse clean-state %| %fuse-merge-failed p.result)
::
%&
=/ merge-result=(unit merge-result) +.result
?~ merge-result
::
:: This merge was a no-op, just continue
::
$(merges t.merges)
?^ conflicts.u.merge-result
::
:: If there are merge conflicts send the error and abort the merge
::
(done-fuse clean-state %& conflicts.u.merge-result)
=/ merged-yaki=yaki
?- -.new.u.merge-result
%|
+.new.u.merge-result
::
%&
::
:: Convert the yuki to yaki
::
=/ yuk=yuki +.new.u.merge-result
=/ lobes=(map path lobe)
%- ~(run by q.yuk)
|= val=(each page lobe)
^- lobe
?- -.val
%& (page-to-lobe +.val)
%| +.val
==
(make-yaki p.yuk lobes now)
==
%= $
continuation-yaki merged-yaki
merges t.merges
hut.ran (~(put by hut.ran) r.merged-yaki merged-yaki)
lat.rag (~(uni by lat.rag) lat.u.merge-result)
parents [(~(got by hit.ali-dom) let.ali-dom) parents]
==
==
:: +done-fuse: restore state after a fuse is attempted, whether it
:: succeeds or fails.
::
++ done-fuse
|= [to-restore=_..take-fuse result=(each (set path) (pair term tang))]
^+ ..take-fuse
=. fiz.to-restore *melt
(done:to-restore result)
--
:: ::
++ done ++ done
|= result=(each (set path) (pair term tang)) |= result=(each (set path) (pair term tang))
^+ ..merge ^+ ..merge
(emit hen %give %mere result) (emit hen %give %mere result)
:: ::
++ merge
|= [=ali=ship =ali=desk =germ =riot]
^+ ..merge
?~ riot
(done %| %ali-unavailable ~[>[ali-ship ali-desk germ]<])
=/ ali-dome=dome:clay !<(dome:clay q.r.u.riot)
=/ result=(each (unit merge-result) (pair term tang))
(merge-helper ali-ship ali-desk germ ali-dome ~)
?- -.result
%|
(done %| +.result)
::
%&
=/ mr=(unit merge-result) +.result
?~ mr
(done %& ~)
=. ..merge (done %& conflicts.u.mr)
(park | new.u.mr ~ lat.u.mr)
==
::
+$ merge-result [conflicts=(set path) new=yoki lat=(map lobe blob)] +$ merge-result [conflicts=(set path) new=yoki lat=(map lobe blob)]
::
++ merge-helper
|= [=ali=ship =ali=desk =germ ali-dome=dome:clay continuation-yaki=(unit yaki)]
^- (each (unit merge-result) [term tang])
|^
^- (each (unit merge-result) [term tang])
=/ ali-yaki=yaki (~(got by hut.ran) (~(got by hit.ali-dome) let.ali-dome))
=/ bob-yaki=(unit yaki)
?~ continuation-yaki
?~ let.dom
~
(~(get by hut.ran) (~(got by hit.dom) let.dom))
continuation-yaki
(merge-by-germ ali-yaki bob-yaki)
::
++ merge-by-germ ++ merge-by-germ
|= [=ali=yaki bob-yaki=(unit yaki)] |= [=ali=yaki bob-yaki=(unit yaki)]
^- (each (unit merge-result) [term tang]) ^- (each (unit merge-result) [term tang])
@ -2005,16 +2253,13 @@
?- germ ?- germ
:: ::
:: If this is a %only-this merge, we check to see if ali's and bob's :: If this is a %only-this merge, we check to see if ali's and bob's
:: commits are the same, in which case we're done. Otherwise, we :: commits are the same, in which case we're done.
:: check to see if ali's commit is in the ancestry of bob's, in :: Otherwise, we create a new commit with bob's data plus ali and
:: which case we're done. Otherwise, we create a new commit with :: bob as parents.
:: bob's data plus ali and bob as parents.
:: ::
%only-this %only-this
?: =(r.ali-yaki r.bob-yaki) ?: =(r.ali-yaki r.bob-yaki)
&+~ &+~
?: (~(has in (reachable-takos:ze r.bob-yaki)) r.ali-yaki)
&+~
:* %& ~ :* %& ~
conflicts=~ conflicts=~
new=&+[[r.bob-yaki r.ali-yaki ~] (to-yuki q.bob-yaki)] new=&+[[r.bob-yaki r.ali-yaki ~] (to-yuki q.bob-yaki)]
@ -2042,8 +2287,6 @@
%take-this %take-this
?: =(r.ali-yaki r.bob-yaki) ?: =(r.ali-yaki r.bob-yaki)
&+~ &+~
?: (~(has in (reachable-takos:ze r.bob-yaki)) r.ali-yaki)
&+~
=/ new-data (~(uni by q.ali-yaki) q.bob-yaki) =/ new-data (~(uni by q.ali-yaki) q.bob-yaki)
:* %& ~ :* %& ~
conflicts=~ conflicts=~
@ -2313,7 +2556,7 @@
=+ (slag (dec (lent path)) path) =+ (slag (dec (lent path)) path)
?~(- %$ i.-) ?~(- %$ i.-)
=/ =dais (get-dais mark) =/ =dais (get-dais mark)
=/ res=(unit (unit vase)) (~(join dais bunt:dais) q.cal q.cob) =/ res=(unit (unit vase)) (~(join dais *vale:dais) q.cal q.cob)
?~ res ?~ res
`[form:dais q.cob] `[form:dais q.cob]
?~ u.res ?~ u.res
@ -2665,6 +2908,9 @@
++ start-request ++ start-request
|= [for=(unit [ship @ud]) rav=rave] |= [for=(unit [ship @ud]) rav=rave]
^+ ..start-request ^+ ..start-request
?: &(?=(^ for) !(foreign-capable rav))
~& [%bad-foreign-request-care from=for rav]
..start-request
=^ [new-sub=(unit rove) sub-results=(list sub-result)] fod.dom =^ [new-sub=(unit rove) sub-results=(list sub-result)] fod.dom
(try-fill-sub for (rave-to-rove rav)) (try-fill-sub for (rave-to-rove rav))
=. ..start-request (send-sub-results sub-results [hen ~ ~]) =. ..start-request (send-sub-results sub-results [hen ~ ~])
@ -2721,14 +2967,23 @@
%r ~| %no-cages-please-they-are-just-way-too-big !! %r ~| %no-cages-please-they-are-just-way-too-big !!
%s ~| %please-dont-get-your-takos-over-a-network !! %s ~| %please-dont-get-your-takos-over-a-network !!
%t ~| %requesting-foreign-directory-is-vaporware !! %t ~| %requesting-foreign-directory-is-vaporware !!
%u ~| %prolly-poor-idea-to-get-rang-over-network !!
%v ~| %weird-shouldnt-get-v-request-from-network !! %v ~| %weird-shouldnt-get-v-request-from-network !!
%z `(validate-z r.rand) %u `(validate-u r.rand)
%w `(validate-w r.rand) %w `(validate-w r.rand)
%x (validate-x [p.p q.p q r]:rand) %x (validate-x [p.p q.p q r]:rand)
%y `[p.r.rand !>(;;(arch q.r.rand))] %y `[p.r.rand !>(;;(arch q.r.rand))]
%z `(validate-z r.rand)
== ==
:: ::
:: Make sure the incoming data is a %u response
::
++ validate-u
|= =page
^- cage
?> ?=(%flag p.page)
:- p.page
!> ;;(? q.page)
::
:: Make sure the incoming data is a %w response :: Make sure the incoming data is a %w response
:: ::
++ validate-w ++ validate-w
@ -2749,7 +3004,11 @@
=/ vale-result =/ vale-result
%- mule |. %- mule |.
%- wrap:fusion %- wrap:fusion
(page-to-cage:(ford:fusion static-ford-args) peg) :: Use %home's marks to validate, so we don't have to build the
:: foreign hoon/zuse
::
=/ args %*(static-ford-args . dom dom:(~(got by dos.rom) %home))
(page-to-cage:(ford:fusion args) peg)
?: ?=(%| -.vale-result) ?: ?=(%| -.vale-result)
%- (slog >%validate-x-failed< p.vale-result) %- (slog >%validate-x-failed< p.vale-result)
~ ~
@ -2762,7 +3021,7 @@
^- cage ^- cage
?> ?=(%uvi p.page) ?> ?=(%uvi p.page)
:- p.page :- p.page
!>(;;(@uvI q.page)) !> ;;(@uvI q.page)
-- --
:: ::
:: Respond to backfill request :: Respond to backfill request
@ -3391,12 +3650,29 @@
|- |-
?: =(b let.dom) ?: =(b let.dom)
hit.dom hit.dom
:: del everything after b
$(hit.dom (~(del by hit.dom) let.dom), let.dom (dec let.dom)) $(hit.dom (~(del by hit.dom) let.dom), let.dom (dec let.dom))
b b
?: =(0 b) ?: =(0 b)
[~ ~] [~ ~]
(data-twixt-takos =(0 ver) (~(get by hit.dom) a) (aeon-to-tako b)) =/ excludes=(set tako)
:: =| acc=(set tako)
=/ lower=@ud 1
|-
:: a should be excluded, so wait until we're past it
?: =(lower +(a))
acc
=/ res=(set tako) (reachable-takos (~(got by hit.dom) lower))
$(acc (~(uni in acc) res), lower +(lower))
=/ includes=(set tako)
=| acc=(set tako)
=/ upper=@ud b
|-
?: =(upper a)
acc
=/ res=(set tako) (reachable-takos (~(got by hit.dom) upper))
$(acc (~(uni in acc) res), upper (dec upper))
[(~(run in (~(dif in includes) excludes)) tako-to-yaki) ~]
:: Traverse parentage and find all ancestor hashes :: Traverse parentage and find all ancestor hashes
:: ::
++ reachable-takos :: reachable ++ reachable-takos :: reachable
@ -3415,30 +3691,6 @@
=. s ^$(p i.p.y) =. s ^$(p i.p.y)
$(p.y t.p.y) $(p.y t.p.y)
:: ::
:: Gets the data between two commit hashes, assuming the first is an
:: ancestor of the second.
::
:: Get all the takos before `a`, then get all takos before `b` except the
:: ones we found before `a`. Then convert the takos to yakis and also get
:: all the data in all the yakis.
::
:: What happens if you run an %init merge on a desk that already
:: had a commit?
::
++ data-twixt-takos
|= [plops=? a=(unit tako) b=tako]
^- [(set yaki) (set plop)]
=+ old=?~(a ~ (reachable-takos u.a))
=/ yal=(set tako)
%- silt
%+ skip
~(tap in (reachable-takos b))
|=(tak=tako (~(has in old) tak))
:- (silt (turn ~(tap in yal) tako-to-yaki))
?. plops
~
(silt (turn ~(tap in (new-lobes (new-lobes ~ old) yal)) lobe-to-blob))
::
:: Get all the lobes that are referenced in `a` except those that are :: Get all the lobes that are referenced in `a` except those that are
:: already in `b`. :: already in `b`.
:: ::
@ -3528,11 +3780,11 @@
[[~ ~] fod.dom] [[~ ~] fod.dom]
=/ cached=(unit [=vase *]) (~(get by naves.fod.dom) i.path) =/ cached=(unit [=vase *]) (~(get by naves.fod.dom) i.path)
?^ cached ?^ cached
:_(fod.dom [~ ~ %& %nave !>(vase.u.cached)]) :_(fod.dom [~ ~ %& %nave vase.u.cached])
=^ =vase fod.dom =^ =vase fod.dom
%- wrap:fusion %- wrap:fusion
(build-nave:(ford:fusion static-ford-args) i.path) (build-nave:(ford:fusion static-ford-args) i.path)
:_(fod.dom [~ ~ %& %nave !>(vase)]) :_(fod.dom [~ ~ %& %nave vase])
:: ::
++ read-f ++ read-f
!. !.
@ -3958,12 +4210,14 @@
:: ::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
=| :: instrument state =| :: instrument state
$: ver=%7 :: vane version $: ver=%8 :: vane version
ruf=raft :: revision tree ruf=raft :: revision tree
== :: == ::
|= [now=@da eny=@uvJ rof=roof] :: current invocation |= [now=@da eny=@uvJ rof=roof] :: current invocation
~% %clay-top ..part ~
|% :: |% ::
++ call :: handle request ++ call :: handle request
~/ %clay-call
|= $: hen=duct |= $: hen=duct
dud=(unit goof) dud=(unit goof)
wrapped-task=(hobo task) wrapped-task=(hobo task)
@ -4074,6 +4328,14 @@
=/ den ((de now rof hen ruf) our des.req) =/ den ((de now rof hen ruf) our des.req)
abet:(start-merge:den her.req dem.req cas.req how.req) abet:(start-merge:den her.req dem.req cas.req how.req)
[mos ..^$] [mos ..^$]
::
%fuse
?: =(%$ des.req)
~&(%fuse-no-desk !!)
=^ mos ruf
=/ den ((de now rof hen ruf) our des.req)
abet:(start-fuse:den bas.req con.req)
[mos ..^$]
:: ::
%mont %mont
=. hez.ruf ?^(hez.ruf hez.ruf `[[%$ %sync ~] ~]) =. hez.ruf ?^(hez.ruf hez.ruf `[[%$ %sync ~] ~])
@ -4202,11 +4464,41 @@
++ load ++ load
=> |% => |%
+$ raft-any +$ raft-any
$% [%7 raft-7] $% [%8 raft-8]
[%7 raft-7]
[%6 raft-6] [%6 raft-6]
== ==
+$ raft-7 raft +$ raft-8 raft
+$ dojo-7 dojo +$ raft-7
$: rom=room-7
hoy=(map ship rung-7)
ran=rang
mon=(map term beam)
hez=(unit duct)
cez=(map @ta crew)
pud=(unit [=desk =yoki])
==
+$ room-7
$: hun=duct
dos=(map desk dojo-7)
==
+$ rung-7
$: rus=(map desk rede-7)
==
+$ dojo-7
$: qyx=cult
dom=dome
per=regs
pew=regs
==
+$ rede-7
$: lim=@da
ref=(unit rind)
qyx=cult
dom=dome
per=regs
pew=regs
==
+$ ford-cache-7 ford-cache +$ ford-cache-7 ford-cache
+$ raft-6 +$ raft-6
$: rom=room-6 :: domestic $: rom=room-6 :: domestic
@ -4249,7 +4541,8 @@
|= old=raft-any |= old=raft-any
|^ |^
=? old ?=(%6 -.old) 7+(raft-6-to-7 +.old) =? old ?=(%6 -.old) 7+(raft-6-to-7 +.old)
?> ?=(%7 -.old) =? old ?=(%7 -.old) 8+(raft-7-to-8 +.old)
?> ?=(%8 -.old)
..^^$(ruf +.old) ..^^$(ruf +.old)
:: +raft-6-to-7: delete stale ford caches (they could all be invalid) :: +raft-6-to-7: delete stale ford caches (they could all be invalid)
:: ::
@ -4270,9 +4563,30 @@
|= =rede-6 |= =rede-6
rede-6(dom dom.rede-6(fod *ford-cache-7)) rede-6(dom dom.rede-6(fod *ford-cache-7))
== ==
:: +raft-7-to-8: create bunted melts in each dojo/rede
::
++ raft-7-to-8
|= raf=raft-7
^- raft-8
%= raf
dos.rom
%- ~(run by dos.rom.raf)
|= doj=dojo-7
^- dojo
[qyx.doj dom.doj per.doj pew.doj *melt]
::
hoy
%- ~(run by hoy.raf)
|= =rung-7
%- ~(run by rus.rung-7)
|= r=rede-7
^- rede
[lim.r ref.r qyx.r dom.r per.r pew.r *melt]
==
-- --
:: ::
++ scry :: inspect ++ scry :: inspect
~/ %clay-scry
^- roon ^- roon
|= [lyc=gang car=term bem=beam] |= [lyc=gang car=term bem=beam]
^- (unit (unit cage)) ^- (unit (unit cage))
@ -4334,6 +4648,7 @@
== ==
:: ::
++ take :: accept response ++ take :: accept response
~/ %clay-take
|= [tea=wire hen=duct dud=(unit goof) hin=sign] |= [tea=wire hen=duct dud=(unit goof) hin=sign]
^+ [*(list move) ..^$] ^+ [*(list move) ..^$]
?^ dud ?^ dud
@ -4350,6 +4665,18 @@
abet:(merge:den ali-ship ali-desk germ p.hin) abet:(merge:den ali-ship ali-desk germ p.hin)
[mos ..^$] [mos ..^$]
:: ::
?: ?=([%fuse @ @ @ @ ~] tea)
?> ?=(%writ +<.hin)
=* syd i.t.tea
=/ ali-ship=@p (slav %p i.t.t.tea)
=* ali-desk=desk i.t.t.t.tea
=/ ali-case (rash i.t.t.t.t.tea nuck:so)
?> ?=([%$ *] ali-case)
=^ mos ruf
=/ den ((de now rof hen ruf) our i.t.tea)
abet:(take-fuse:den [ali-ship ali-desk (case +.ali-case)] p.hin)
[mos ..^$]
::
?: ?=([%foreign-warp *] tea) ?: ?=([%foreign-warp *] tea)
?> ?=(%writ +<.hin) ?> ?=(%writ +<.hin)
:_ ..^$ :_ ..^$

View File

@ -215,7 +215,7 @@
?: =('subscribe' u.maybe-key) ?: =('subscribe' u.maybe-key)
%. item %. item
%+ pe %subscribe %+ pe %subscribe
(ot id+ni ship+(su fed:ag) app+so path+(su ;~(pfix fas (more fas urs:ab))) ~) (ot id+ni ship+(su fed:ag) app+so path+(su stap) ~)
?: =('unsubscribe' u.maybe-key) ?: =('unsubscribe' u.maybe-key)
%. item %. item
%+ pe %unsubscribe %+ pe %unsubscribe
@ -426,10 +426,12 @@
:- ~ :- ~
%- as-octs:mimes:html %- as-octs:mimes:html
%- crip %- crip
%- zing %- zing ^- ^wall
%- zing ^- (list ^wall)
%+ turn wall %+ turn wall
|= t=tape |= t=tape
"{t}\0a" ^- ^wall
~[t "\0a"]
:: +internal-server-error: 500 page, with a tang :: +internal-server-error: 500 page, with a tang
:: ::
++ internal-server-error ++ internal-server-error
@ -1598,6 +1600,7 @@
:: +channel-event-to-sign: attempt to recover a sign from a channel-event :: +channel-event-to-sign: attempt to recover a sign from a channel-event
:: ::
++ channel-event-to-sign ++ channel-event-to-sign
~% %eyre-channel-event-to-sign ..part ~
|= event=channel-event |= event=channel-event
^- (unit sign:agent:gall) ^- (unit sign:agent:gall)
?. ?=(%fact -.event) `event ?. ?=(%fact -.event) `event
@ -1678,6 +1681,7 @@
== ==
:: ::
++ event-json-to-wall ++ event-json-to-wall
~% %eyre-json-to-wall ..part ~
|= [event-id=@ud =json] |= [event-id=@ud =json]
^- wall ^- wall
:~ (weld "id: " (format-ud-as-integer event-id)) :~ (weld "id: " (format-ud-as-integer event-id))
@ -2095,6 +2099,7 @@
~% %http-server ..part ~ ~% %http-server ..part ~
|% |%
++ call ++ call
~/ %eyre-call
|= [=duct dud=(unit goof) wrapped-task=(hobo task)] |= [=duct dud=(unit goof) wrapped-task=(hobo task)]
^- [(list move) _http-server-gate] ^- [(list move) _http-server-gate]
:: ::
@ -2297,6 +2302,7 @@
== ==
:: ::
++ take ++ take
~/ %eyre-take
|= [=wire =duct dud=(unit goof) =sign] |= [=wire =duct dud=(unit goof) =sign]
^- [(list move) _http-server-gate] ^- [(list move) _http-server-gate]
?^ dud ?^ dud
@ -2484,6 +2490,7 @@
:: +scry: request a path in the urbit namespace :: +scry: request a path in the urbit namespace
:: ::
++ scry ++ scry
~/ %eyre-scry
^- roon ^- roon
|= [lyc=gang car=term bem=beam] |= [lyc=gang car=term bem=beam]
^- (unit (unit cage)) ^- (unit (unit cage))

View File

@ -646,6 +646,7 @@
:: cleared queue in +load 3-to-4 or +load-4-to-5 :: cleared queue in +load 3-to-4 or +load-4-to-5
:: ::
=? stand ?=(~ stand) =? stand ?=(~ stand)
~& [%gall-missing wire hen]
(~(put to *(qeu remote-request)) %missing) (~(put to *(qeu remote-request)) %missing)
~| [full-wire=full-wire hen=hen stand=stand] ~| [full-wire=full-wire hen=hen stand=stand]
=^ rr stand ~(get to stand) =^ rr stand ~(get to stand)

View File

@ -3286,7 +3286,7 @@
++ ship :: string from ship ++ ship :: string from ship
|= a=^ship |= a=^ship
^- json ^- json
(tape (slag 1 (scow %p a))) [%n (rap 3 '"' (rsh [3 1] (scot %p a)) '"' ~)]
:: :: ++numb:enjs:format :: :: ++numb:enjs:format
++ numb :: number from unsigned ++ numb :: number from unsigned
|= a=@u |= a=@u
@ -3458,7 +3458,7 @@
[(rash a fel) b] [(rash a fel) b]
:: :: ++pa:dejs:format :: :: ++pa:dejs:format
++ pa :: string as path ++ pa :: string as path
(su ;~(pfix fas (more fas urs:ab))) (su stap)
:: :: ++pe:dejs:format :: :: ++pe:dejs:format
++ pe :: prefix ++ pe :: prefix
|* [pre=* wit=fist] |* [pre=* wit=fist]
@ -5070,36 +5070,54 @@
|= ord=$-([key key] ?) |= ord=$-([key key] ?)
|= a=* |= a=*
=/ b ;;((tree [key=key val=value]) a) =/ b ;;((tree [key=key val=value]) a)
?> (check-balance:((ordered-map key value) ord) b) ?> (apt:((on key value) ord) b)
b b
:: ::
:: $mk-item: constructor for +ordered-map item type
:: ::
++ mk-item |$ [key val] [key=key val=val] ++ ordered-map on
:: +ordered-map: treap with user-specified horizontal order :: +on: treap with user-specified horizontal order, ordered-map
::
:: Conceptually smaller items go on the left, so the item with the
:: smallest key can be popped off the head. If $key is `@` and
:: .compare is +lte, then the numerically smallest item is the head.
:: ::
:: WARNING: ordered-map will not work properly if two keys can be :: WARNING: ordered-map will not work properly if two keys can be
:: unequal under noun equality but equal via the compare gate :: unequal under noun equality but equal via the compare gate
:: ::
++ ordered-map ++ on
~/ %on
|* [key=mold val=mold] |* [key=mold val=mold]
=> |% => |%
+$ item (mk-item key val) +$ item [key=key val=val]
-- --
:: +compare: item comparator for horizontal order :: +compare: item comparator for horizontal order
:: ::
~% %comp +>+ ~
|= compare=$-([key key] ?) |= compare=$-([key key] ?)
~% %core + ~
|% |%
:: +check-balance: verify horizontal and vertical orderings :: +all: apply logical AND boolean test on all values
:: ::
++ check-balance ++ all
=| [l=(unit key) r=(unit key)] ~/ %all
|= a=(tree item) |= [a=(tree item) b=$-(item ?)]
^- ? ^- ?
|-
?~ a
&
?&((b n.a) $(a l.a) $(a r.a))
:: +any: apply logical OR boolean test on all values
::
++ any
~/ %any
|= [a=(tree item) b=$-(item ?)]
|- ^- ?
?~ a
|
?|((b n.a) $(a l.a) $(a r.a))
:: +apt: verify horizontal and vertical orderings
::
++ apt
~/ %apt
|= a=(tree item)
=| [l=(unit key) r=(unit key)]
|- ^- ?
:: empty tree is valid :: empty tree is valid
:: ::
?~ a %.y ?~ a %.y
@ -5122,64 +5140,22 @@
:: ::
?~(r.a %.y &((mor key.n.a key.n.r.a) $(a r.a, r `key.n.a))) ?~(r.a %.y &((mor key.n.a key.n.r.a) $(a r.a, r `key.n.a)))
== ==
:: +put: ordered item insert :: +bap: convert to list, right to left
:: ::
++ put ++ bap
|= [a=(tree item) =key =val] ~/ %bap
^- (tree item)
:: base case: replace null with single-item tree
::
?~ a [n=[key val] l=~ r=~]
:: base case: overwrite existing .key with new .val
::
?: =(key.n.a key) a(val.n val)
:: if item goes on left, recurse left then rebalance vertical order
::
?: (compare key key.n.a)
=/ l $(a l.a)
?> ?=(^ l)
?: (mor key.n.a key.n.l)
a(l l)
l(r a(l r.l))
:: item goes on right; recurse right then rebalance vertical order
::
=/ r $(a r.a)
?> ?=(^ r)
?: (mor key.n.a key.n.r)
a(r r)
r(l a(r l.r))
:: +peek: produce head (smallest item) or null
::
++ peek
|= a=(tree item) |= a=(tree item)
^- (unit item) ^- (list item)
:: =| b=(list item)
?~ a ~ |- ^+ b
?~ l.a `n.a ?~ a b
$(a l.a) $(a r.a, b [n.a $(a l.a)])
::
:: +pop: produce .head (smallest item) and .rest or crash if empty
::
++ pop
|= a=(tree item)
^- [head=item rest=(tree item)]
::
?~ a !!
?~ l.a [n.a r.a]
::
=/ l $(a l.a)
:- head.l
:: load .rest.l back into .a and rebalance
::
?: |(?=(~ rest.l) (mor key.n.a key.n.rest.l))
a(l rest.l)
rest.l(r a(r r.rest.l))
:: +del: delete .key from .a if it exists, producing value iff deleted :: +del: delete .key from .a if it exists, producing value iff deleted
:: ::
++ del ++ del
~/ %del
|= [a=(tree item) =key] |= [a=(tree item) =key]
^- [(unit val) (tree item)] ^- [(unit val) (tree item)]
::
?~ a [~ ~] ?~ a [~ ~]
:: we found .key at the root; delete and rebalance :: we found .key at the root; delete and rebalance
:: ::
@ -5192,30 +5168,15 @@
[found a(l lef)] [found a(l lef)]
=+ [found rig]=$(a r.a) =+ [found rig]=$(a r.a)
[found a(r rig)] [found a(r rig)]
:: +nip: remove root; for internal use :: +dip: stateful partial inorder traversal
::
++ nip
|= a=(tree item)
^- (tree item)
::
?> ?=(^ a)
:: delete .n.a; merge and balance .l.a and .r.a
::
|- ^- (tree item)
?~ l.a r.a
?~ r.a l.a
?: (mor key.n.l.a key.n.r.a)
l.a(r $(l.a r.l.a))
r.a(l $(r.a l.r.a))
:: +traverse: stateful partial inorder traversal
:: ::
:: Mutates .state on each run of .f. Starts at .start key, or if :: Mutates .state on each run of .f. Starts at .start key, or if
:: .start is ~, starts at the head (item with smallest key). Stops :: .start is ~, starts at the head. Stops when .f produces .stop=%.y.
:: when .f produces .stop=%.y. Traverses from smaller to larger :: Traverses from left to right keys.
:: keys. Each run of .f can replace an item's value or delete the :: Each run of .f can replace an item's value or delete the item.
:: item.
:: ::
++ traverse ++ dip
~/ %dip
|* state=mold |* state=mold
|= $: a=(tree item) |= $: a=(tree item)
=state =state
@ -5274,63 +5235,18 @@
=/ rig main(a r.a) =/ rig main(a r.a)
rig(a a(r a.rig)) rig(a a(r a.rig))
-- --
:: +tap: convert to list, smallest to largest
::
++ tap
|= a=(tree item)
^- (list item)
::
=| b=(list item)
|- ^+ b
?~ a b
::
$(a l.a, b [n.a $(a r.a)])
:: +bap: convert to list, largest to smallest
::
++ bap
|= a=(tree item)
^- (list item)
::
=| b=(list item)
|- ^+ b
?~ a b
::
$(a r.a, b [n.a $(a l.a)])
:: +gas: put a list of items :: +gas: put a list of items
:: ::
++ gas ++ gas
~/ %gas
|= [a=(tree item) b=(list item)] |= [a=(tree item) b=(list item)]
^- (tree item) ^- (tree item)
::
?~ b a ?~ b a
$(b t.b, a (put a i.b)) $(b t.b, a (put a i.b))
:: +uni: unify two ordered maps
::
:: .b takes precedence over .a if keys overlap.
::
++ uni
|= [a=(tree item) b=(tree item)]
^- (tree item)
::
?~ b a
?~ a b
?: =(key.n.a key.n.b)
::
[n=n.b l=$(a l.a, b l.b) r=$(a r.a, b r.b)]
::
?: (mor key.n.a key.n.b)
::
?: (compare key.n.b key.n.a)
$(l.a $(a l.a, r.b ~), b r.b)
$(r.a $(a r.a, l.b ~), b l.b)
::
?: (compare key.n.a key.n.b)
$(l.b $(b l.b, r.a ~), a r.a)
$(r.b $(b r.b, l.a ~), a l.a)
::
:: +get: get val at key or return ~ :: +get: get val at key or return ~
:: ::
++ get ++ get
~/ %get
|= [a=(tree item) b=key] |= [a=(tree item) b=key]
^- (unit val) ^- (unit val)
?~ a ~ ?~ a ~
@ -5339,11 +5255,24 @@
?: (compare b key.n.a) ?: (compare b key.n.a)
$(a l.a) $(a l.a)
$(a r.a) $(a r.a)
:: +got: need value at key
:: ::
:: +subset: take a range excluding start and/or end and all elements ++ got
|= [a=(tree item) b=key]
^- val
(need (get a b))
:: +has: check for key existence
::
++ has
~/ %has
|= [a=(tree item) b=key]
^- ?
!=(~ (get a b))
:: +lot: take a subset range excluding start and/or end and all elements
:: outside the range :: outside the range
:: ::
++ subset ++ lot
~/ %lot
|= $: tre=(tree item) |= $: tre=(tree item)
start=(unit key) start=(unit key)
end=(unit key) end=(unit key)
@ -5389,6 +5318,154 @@
$(a (nip a(r ~))) $(a (nip a(r ~)))
== ==
-- --
:: +nip: remove root; for internal use
::
++ nip
~/ %nip
|= a=(tree item)
^- (tree item)
?> ?=(^ a)
:: delete .n.a; merge and balance .l.a and .r.a
::
|- ^- (tree item)
?~ l.a r.a
?~ r.a l.a
?: (mor key.n.l.a key.n.r.a)
l.a(r $(l.a r.l.a))
r.a(l $(r.a l.r.a))
::
:: +pop: produce .head (leftmost item) and .rest or crash if empty
::
++ pop
~/ %pop
|= a=(tree item)
^- [head=item rest=(tree item)]
?~ a !!
?~ l.a [n.a r.a]
=/ l $(a l.a)
:- head.l
:: load .rest.l back into .a and rebalance
::
?: |(?=(~ rest.l) (mor key.n.a key.n.rest.l))
a(l rest.l)
rest.l(r a(r r.rest.l))
:: +pry: produce head (leftmost item) or null
::
++ pry
~/ %pry
|= a=(tree item)
^- (unit item)
?~ a ~
|-
?~ l.a `n.a
$(a l.a)
:: +put: ordered item insert
::
++ put
~/ %put
|= [a=(tree item) =key =val]
^- (tree item)
:: base case: replace null with single-item tree
::
?~ a [n=[key val] l=~ r=~]
:: base case: overwrite existing .key with new .val
::
?: =(key.n.a key) a(val.n val)
:: if item goes on left, recurse left then rebalance vertical order
::
?: (compare key key.n.a)
=/ l $(a l.a)
?> ?=(^ l)
?: (mor key.n.a key.n.l)
a(l l)
l(r a(l r.l))
:: item goes on right; recurse right then rebalance vertical order
::
=/ r $(a r.a)
?> ?=(^ r)
?: (mor key.n.a key.n.r)
a(r r)
r(l a(r l.r))
:: +ram: produce tail (rightmost item) or null
::
++ ram
~/ %ram
|= a=(tree item)
^- (unit item)
?~ a ~
|-
?~ r.a `n.a
$(a r.a)
:: +run: apply gate to transform all values in place
::
++ run
~/ %run
|* [a=(tree item) b=$-(val *)]
|-
?~ a a
[n=[key.n.a (b val.n.a)] l=$(a l.a) r=$(a r.a)]
:: +tab: tabulate a subset excluding start element with a max count
::
++ tab
~/ %tab
|= [a=(tree item) b=(unit key) c=@]
^- (list item)
|^
(flop e:(tabulate (del-span a b) b c))
::
++ tabulate
|= [a=(tree item) b=(unit key) c=@]
^- [d=@ e=(list item)]
?: ?&(?=(~ b) =(c 0))
[0 ~]
=| f=[d=@ e=(list item)]
|- ^+ f
?: ?|(?=(~ a) =(d.f c)) f
=. f $(a l.a)
?: =(d.f c) f
=. f [+(d.f) [n.a e.f]]
?:(=(d.f c) f $(a r.a))
::
++ del-span
|= [a=(tree item) b=(unit key)]
^- (tree item)
?~ a a
?~ b a
?: =(key.n.a u.b)
r.a
?: (compare key.n.a u.b)
$(a r.a)
a(l $(a l.a))
--
:: +tap: convert to list, left to right
::
++ tap
~/ %tap
|= a=(tree item)
^- (list item)
=| b=(list item)
|- ^+ b
?~ a b
$(a l.a, b [n.a $(a r.a)])
:: +uni: unify two ordered maps
::
:: .b takes precedence over .a if keys overlap.
::
++ uni
~/ %uni
|= [a=(tree item) b=(tree item)]
^- (tree item)
?~ b a
?~ a b
?: =(key.n.a key.n.b)
[n=n.b l=$(a l.a, b l.b) r=$(a r.a, b r.b)]
?: (mor key.n.a key.n.b)
?: (compare key.n.b key.n.a)
$(l.a $(a l.a, r.b ~), b r.b)
$(r.a $(a r.a, l.b ~), b l.b)
?: (compare key.n.a key.n.b)
$(l.b $(b l.b, r.a ~), a r.a)
$(r.b $(b r.b, l.a ~), a l.a)
-- --
:: :: :: ::
:::: ++userlib :: (2u) non-vane utils :::: ++userlib :: (2u) non-vane utils
@ -5535,7 +5612,8 @@
:: :: ++unm:chrono:userlib :: :: ++unm:chrono:userlib
++ unm :: Urbit to Unix ms ++ unm :: Urbit to Unix ms
|= a=@da |= a=@da
(div (mul (sub a ~1970.1.1) 1.000) ~s1) =- (div (mul - 1.000) ~s1)
(sub (add a (div ~s1 2.000)) ~1970.1.1)
:: :: ++unt:chrono:userlib :: :: ++unt:chrono:userlib
++ unt :: Urbit to Unix time ++ unt :: Urbit to Unix time
|= a=@da |= a=@da

View File

@ -23,7 +23,7 @@
=/ src "." =/ src "."
%+ expect-eq %+ expect-eq
!> ^- pile:fusion !> ^- pile:fusion
:* ~ ~ ~ ~ ~ ~ :* ~ ~ ~ ~ ~ ~ ~
tssg+[%dbug [/sur/foo/hoon [[1 1] [1 2]]] [%cnts ~[[%.y 1]] ~]]~ tssg+[%dbug [/sur/foo/hoon [[1 1] [1 2]]] [%cnts ~[[%.y 1]] ~]]~
== ==
!> (parse-pile:(ford):fusion /sur/foo/hoon src) !> (parse-pile:(ford):fusion /sur/foo/hoon src)
@ -32,7 +32,7 @@
=/ src "/% moo %mime\0a." =/ src "/% moo %mime\0a."
%+ expect-eq %+ expect-eq
!> ^- pile:fusion !> ^- pile:fusion
:* sur=~ lib=~ raw=~ :* sur=~ lib=~ raw=~ raz=~
maz=[face=%moo mark=%mime]~ maz=[face=%moo mark=%mime]~
caz=~ bar=~ caz=~ bar=~
tssg+[%dbug [/sur/foo/hoon [[2 1] [2 2]]] [%cnts ~[[%.y 1]] ~]]~ tssg+[%dbug [/sur/foo/hoon [[2 1] [2 2]]] [%cnts ~[[%.y 1]] ~]]~
@ -43,7 +43,7 @@
=/ src "/$ goo %mime %txt\0a." =/ src "/$ goo %mime %txt\0a."
%+ expect-eq %+ expect-eq
!> ^- pile:fusion !> ^- pile:fusion
:* sur=~ lib=~ raw=~ maz=~ :* sur=~ lib=~ raw=~ raz=~ maz=~
caz=[face=%goo from=%mime to=%txt]~ caz=[face=%goo from=%mime to=%txt]~
bar=~ bar=~
tssg+[%dbug [/sur/foo/hoon [[2 1] [2 2]]] [%cnts ~[[%.y 1]] ~]]~ tssg+[%dbug [/sur/foo/hoon [[2 1] [2 2]]] [%cnts ~[[%.y 1]] ~]]~
@ -74,7 +74,7 @@
[`%hood-drum %hood-drum] [`%hood-drum %hood-drum]
[`%hood-write %hood-write] [`%hood-write %hood-write]
== ==
raw=~ maz=~ caz=~ bar=~ raw=~ raz=~ maz=~ caz=~ bar=~
tssg+[%dbug [/sur/foo/hoon [[10 1] [10 2]]] [%cnts ~[[%.y 1]] ~]]~ tssg+[%dbug [/sur/foo/hoon [[10 1] [10 2]]] [%cnts ~[[%.y 1]] ~]]~
== ==
!> (parse-pile:(ford):fusion /sur/foo/hoon src) !> (parse-pile:(ford):fusion /sur/foo/hoon src)
@ -112,10 +112,10 @@
;: weld ;: weld
%+ expect-eq %+ expect-eq
!>(*mime) !>(*mime)
(slap res limb/%bunt) (slap res !,(*hoon *vale))
:: ::
%+ expect-eq %+ expect-eq
!> (~(gas in *(set path)) /mar/mime/hoon ~) !> (~(gas in *(set [? path])) |^/mar/mime/hoon ~)
!> dez:(~(got by files.cache.nub) /mar/mime/hoon) !> dez:(~(got by files.cache.nub) /mar/mime/hoon)
== ==
:: ::
@ -139,10 +139,10 @@
;: weld ;: weld
%+ expect-eq %+ expect-eq
!>(*@t) !>(*@t)
(slap res limb/%bunt) (slap res !,(*hoon *vale))
:: ::
%+ expect-eq %+ expect-eq
!> (~(gas in *(set path)) /mar/udon/hoon /lib/cram/hoon ~) !> (~(gas in *(set [? path])) |^/mar/udon/hoon |^/lib/cram/hoon ~)
!> dez:(~(got by files.cache.nub) /mar/udon/hoon) !> dez:(~(got by files.cache.nub) /mar/udon/hoon)
== ==
:: ::
@ -170,7 +170,7 @@
=/ changes =/ changes
%- my %- my
:~ [/mar/mime/hoon &+hoon+mar-mime] :~ [/mar/mime/hoon &+hoon+mar-mime]
[/lib/foo/hoon &+hoon+'/% moo %mime\0abunt:moo'] [/lib/foo/hoon &+hoon+'/% moo %mime\0a*vale:moo']
== ==
=/ ford =/ ford
%: ford:fusion %: ford:fusion
@ -224,7 +224,7 @@
(slap res (ream '(+ [*^ [%bob ~] ~])')) (slap res (ream '(+ [*^ [%bob ~] ~])'))
:: ::
%+ expect-eq %+ expect-eq
!> (~(gas in *(set path)) /gen/hello/hoon ~) !> (~(gas in *(set [? path])) |^/gen/hello/hoon ~)
!> dez:(~(got by files.cache.nub) /gen/hello/hoon) !> dez:(~(got by files.cache.nub) /gen/hello/hoon)
== ==
:: ::
@ -249,10 +249,10 @@
!>((slab %read %get-our -.res)) !>((slab %read %get-our -.res))
:: ::
%+ expect-eq %+ expect-eq
!> %- ~(gas in *(set path)) !> %- ~(gas in *(set [? path]))
:~ /lib/strandio/hoon :~ [| /lib/strandio/hoon]
/lib/strand/hoon [| /lib/strand/hoon]
/sur/spider/hoon [| /sur/spider/hoon]
== ==
!> dez:(~(got by files.cache.nub) /lib/strandio/hoon) !> dez:(~(got by files.cache.nub) /lib/strandio/hoon)
== ==

View File

@ -2353,7 +2353,6 @@
:^ ~ ~ %dais :^ ~ ~ %dais
!> ^- dais:clay !> ^- dais:clay
|_ sam=vase |_ sam=vase
++ bunt !!
++ diff !! ++ diff !!
++ form !! ++ form !!
++ join !! ++ join !!

View File

@ -179,10 +179,15 @@
%+ expect-eq %+ expect-eq
!> [%n '1000'] !> [%n '1000']
!> (time ~1970.1.1..0.0.1) !> (time ~1970.1.1..0.0.1)
:: timestamps should invert
::
%+ expect-eq
!> [%n '1001']
!> (time (from-unix-ms:chrono:userlib 1.001))
:: ship - store ship identity as a string :: ship - store ship identity as a string
:: ::
%+ expect-eq %+ expect-eq
!> [%s 'zod'] !> [%n '"zod"']
!> (ship ~zod) !> (ship ~zod)
== ==
:: dejs - recursive processing of `json` values :: dejs - recursive processing of `json` values

View File

@ -9,6 +9,7 @@
(items-from-keys (gulf 0 6)) (items-from-keys (gulf 0 6))
:: ::
=/ atom-map ((ordered-map @ud @tas) lte) =/ atom-map ((ordered-map @ud @tas) lte)
=/ gte-atom-map ((ordered-map @ud @tas) gte)
:: ::
|% |%
++ test-ordered-map-gas ^- tang ++ test-ordered-map-gas ^- tang
@ -17,7 +18,7 @@
:: ::
%+ expect-eq %+ expect-eq
!> %.y !> %.y
!> (check-balance:atom-map a) !> (apt:atom-map a)
:: ::
++ test-ordered-map-tap ^- tang ++ test-ordered-map-tap ^- tang
:: ::
@ -27,6 +28,72 @@
!> test-items !> test-items
!> (tap:atom-map a) !> (tap:atom-map a)
:: ::
++ test-ordered-map-tab-gte ^- tang
::
=/ a=(tree [@ud @tas]) (gas:gte-atom-map ~ test-items)
::
%+ expect-eq
!> (flop test-items)
!> (tab:gte-atom-map a ~ 7)
::
++ test-ordered-map-tab-gte-starting-from ^- tang
::
=/ a=(tree [@ud @tas]) (gas:gte-atom-map ~ test-items)
=/ small-test-items=(list [@ud @tas])
(items-from-keys (gulf 2 5))
::
%+ expect-eq
!> (flop small-test-items)
!> (tab:gte-atom-map a [~ 6] 4)
::
++ test-ordered-map-tab-gte-count ^- tang
::
=/ a=(tree [@ud @tas]) (gas:gte-atom-map ~ test-items)
=/ small-test-items=(list [@ud @tas])
(items-from-keys (gulf 4 6))
::
%+ expect-eq
!> (flop small-test-items)
!> (tab:gte-atom-map a ~ 3)
::
++ test-ordered-map-tab ^- tang
::
=/ a=(tree [@ud @tas]) (gas:atom-map ~ test-items)
::
%+ expect-eq
!> test-items
!> (tab:atom-map a ~ 7)
::
++ test-ordered-map-tab-starting-from ^- tang
::
=/ a=(tree [@ud @tas]) (gas:atom-map ~ test-items)
=/ small-test-items=(list [@ud @tas])
(items-from-keys (gulf 1 4))
::
%+ expect-eq
!> small-test-items
!> (tab:atom-map a [~ 0] 4)
::
++ test-ordered-map-tab-count ^- tang
::
=/ a=(tree [@ud @tas]) (gas:atom-map ~ test-items)
=/ small-test-items=(list [@ud @tas])
(items-from-keys (gulf 0 2))
::
%+ expect-eq
!> small-test-items
!> (tab:atom-map a ~ 3)
::
++ test-ordered-map-tab-more-than-exist ^- tang
::
=/ specific-test-items=(list [@ud @tas])
(items-from-keys (gulf 1 6))
=/ a=(tree [@ud @tas]) (gas:atom-map ~ specific-test-items)
::
%+ expect-eq
!> specific-test-items
!> (tab:atom-map a [~ 0] 8)
::
++ test-ordered-map-pop ^- tang ++ test-ordered-map-pop ^- tang
:: ::
=/ a=(tree [@ud @tas]) (gas:atom-map ~ test-items) =/ a=(tree [@ud @tas]) (gas:atom-map ~ test-items)
@ -35,13 +102,13 @@
!> [[0 %a] (gas:atom-map ~ (items-from-keys (gulf 1 6)))] !> [[0 %a] (gas:atom-map ~ (items-from-keys (gulf 1 6)))]
!> (pop:atom-map a) !> (pop:atom-map a)
:: ::
++ test-ordered-map-peek ^- tang ++ test-ordered-map-pry ^- tang
:: ::
=/ a=(tree [@ud @tas]) (gas:atom-map ~ test-items) =/ a=(tree [@ud @tas]) (gas:atom-map ~ test-items)
:: ::
%+ expect-eq %+ expect-eq
!> `[0 %a] !> `[0 %a]
!> (peek:atom-map a) !> (pry:atom-map a)
:: ::
++ test-ordered-map-nip ^- tang ++ test-ordered-map-nip ^- tang
:: ::
@ -53,61 +120,61 @@
!> (gas:atom-map ~ ~[[0^%a] [1^%b] [2^%c] [3^%d] [4^%e] [5^%f]]) !> (gas:atom-map ~ ~[[0^%a] [1^%b] [2^%c] [3^%d] [4^%e] [5^%f]])
!> b !> b
:: ::
++ test-ordered-map-subset ^- tang ++ test-ordered-map-lot ^- tang
:: ::
=/ a=(tree [@ud @tas]) (gas:atom-map ~ test-items) =/ a=(tree [@ud @tas]) (gas:atom-map ~ test-items)
:: ::
=/ b (subset:atom-map a `0 `4) =/ b (lot:atom-map a `0 `4)
:: ::
%+ expect-eq %+ expect-eq
!> (gas:atom-map ~ ~[[1^%b] [2^%c] [3^%d]]) !> (gas:atom-map ~ ~[[1^%b] [2^%c] [3^%d]])
!> b !> b
:: ::
++ test-ordered-map-null-start-subset ^- tang ++ test-ordered-map-null-start-lot ^- tang
:: ::
=/ a=(tree [@ud @tas]) (gas:atom-map ~ test-items) =/ a=(tree [@ud @tas]) (gas:atom-map ~ test-items)
:: ::
=/ b (subset:atom-map a ~ `5) =/ b (lot:atom-map a ~ `5)
:: ::
%+ expect-eq %+ expect-eq
!> (gas:atom-map ~ ~[[0^%a] [1^%b] [2^%c] [3^%d] [4^%e]]) !> (gas:atom-map ~ ~[[0^%a] [1^%b] [2^%c] [3^%d] [4^%e]])
!> b !> b
:: ::
++ test-ordered-map-null-end-subset ^- tang ++ test-ordered-map-null-end-lot ^- tang
:: ::
=/ a=(tree [@ud @tas]) (gas:atom-map ~ test-items) =/ a=(tree [@ud @tas]) (gas:atom-map ~ test-items)
:: ::
=/ b (subset:atom-map a `1 ~) =/ b (lot:atom-map a `1 ~)
:: ::
%+ expect-eq %+ expect-eq
!> (gas:atom-map ~ ~[[2^%c] [3^%d] [4^%e] [5^%f] [6^%g]]) !> (gas:atom-map ~ ~[[2^%c] [3^%d] [4^%e] [5^%f] [6^%g]])
!> b !> b
:: ::
++ test-ordered-map-double-null-subset ^- tang ++ test-ordered-map-double-null-lot ^- tang
:: ::
=/ a=(tree [@ud @tas]) (gas:atom-map ~ test-items) =/ a=(tree [@ud @tas]) (gas:atom-map ~ test-items)
:: ::
=/ b (subset:atom-map a ~ ~) =/ b (lot:atom-map a ~ ~)
:: ::
%+ expect-eq %+ expect-eq
!> (gas:atom-map ~ ~[[0^%a] [1^%b] [2^%c] [3^%d] [4^%e] [5^%f] [6^%g]]) !> (gas:atom-map ~ ~[[0^%a] [1^%b] [2^%c] [3^%d] [4^%e] [5^%f] [6^%g]])
!> b !> b
:: ::
++ test-ordered-map-not-found-start-subset ^- tang ++ test-ordered-map-not-found-start-lot ^- tang
:: ::
=/ a=(tree [@ud @tas]) (gas:atom-map ~ ~[[1^%b]]) =/ a=(tree [@ud @tas]) (gas:atom-map ~ ~[[1^%b]])
:: ::
=/ b (subset:atom-map a `0 ~) =/ b (lot:atom-map a `0 ~)
:: ::
%+ expect-eq %+ expect-eq
!> (gas:atom-map ~ ~[[1^%b]]) !> (gas:atom-map ~ ~[[1^%b]])
!> b !> b
:: ::
++ test-ordered-map-traverse ^- tang ++ test-ordered-map-dip ^- tang
:: ::
=/ a=(tree [@ud @tas]) (gas:atom-map ~ test-items) =/ a=(tree [@ud @tas]) (gas:atom-map ~ test-items)
:: ::
=/ b %- (traverse:atom-map ,(list [@ud @tas])) =/ b %- (dip:atom-map ,(list [@ud @tas]))
:* a :* a
state=~ state=~
:: ::
@ -129,11 +196,11 @@
!> -.b !> -.b
== ==
:: ::
++ test-ordered-map-traverse-delete-all ^- tang ++ test-ordered-map-dip-delete-all ^- tang
;: weld ;: weld
=/ q ((ordered-map ,@ ,~) lte) =/ q ((ordered-map ,@ ,~) lte)
=/ o (gas:q ~ ~[1/~ 2/~ 3/~]) =/ o (gas:q ~ ~[1/~ 2/~ 3/~])
=/ b ((traverse:q ,~) o ~ |=([~ key=@ ~] [~ %| ~])) =/ b ((dip:q ,~) o ~ |=([~ key=@ ~] [~ %| ~]))
%+ expect-eq %+ expect-eq
!> [~ ~] !> [~ ~]
!> b !> b
@ -147,7 +214,7 @@
?:((lth aa ba) %.y ?:((gth aa ba) %.n (lte ab bb))) ?:((lth aa ba) %.y ?:((gth aa ba) %.n (lte ab bb)))
=/ q ((ordered-map ,[@ @] ,~) compare) =/ q ((ordered-map ,[@ @] ,~) compare)
=/ o (gas:q ~ c) =/ o (gas:q ~ c)
=/ b ((traverse:q ,~) o ~ |=([~ key=[@ @] ~] [~ %| ~])) =/ b ((dip:q ,~) o ~ |=([~ key=[@ @] ~] [~ %| ~]))
%+ expect-eq %+ expect-eq
!> [~ ~] !> [~ ~]
!> b !> b

1
pkg/ent/configure vendored
View File

@ -7,6 +7,7 @@ log () {
for impl in ENT_GETENTROPY_UNISTD \ for impl in ENT_GETENTROPY_UNISTD \
ENT_GETENTROPY_SYSRANDOM \ ENT_GETENTROPY_SYSRANDOM \
ENT_GETRANDOM_SYSCALL \ ENT_GETRANDOM_SYSCALL \
ENT_GETENTROPY_BCRYPTGENRANDOM \
ENT_DEV_URANDOM ENT_DEV_URANDOM
do do
export IMPL=$impl export IMPL=$impl

View File

@ -57,6 +57,16 @@ int ent_getentropy(void* buf, size_t len) {
return 0; return 0;
} }
// Use `BCryptGenRandom` on Windows ////////////////////////////////////////////
#elif defined(ENT_GETENTROPY_BCRYPTGENRANDOM)
#include <windows.h>
#include <bcrypt.h>
int ent_getentropy(void* buf, size_t len) {
return BCryptGenRandom(NULL, (PUCHAR)buf, len, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
}
#else #else
#error "One of these must be set: ENT_DEV_URANDOM, ENT_GETENTROPY_UNISTD, ENT_GETENTROPY_SYSRANDOM, ENT_GETRANDOM_SYSCALL" #error "One of these must be set: ENT_GETENTROPY_BCRYPTGENRANDOM, ENT_DEV_URANDOM, ENT_GETENTROPY_UNISTD, ENT_GETENTROPY_SYSRANDOM, ENT_GETRANDOM_SYSCALL"
#endif #endif

View File

@ -3,3 +3,4 @@
tests export-ignore tests export-ignore
hashtable_tests export-ignore hashtable_tests export-ignore
shell.nix export-ignore shell.nix export-ignore
*.patch -text

View File

@ -1,3 +1,5 @@
# Configuration Result # Configuration Result
/config.mk /config.mk
/include/config.h /include/config.h
/include/ca-bundle.h
/include/ivory.h

View File

@ -1,4 +1,5 @@
include config.mk include config.mk
include $(foreach dir,$(compat),$(wildcard compat/$(dir)/*.mk))
jets = jets/tree.c $(wildcard jets/*/*.c) jets = jets/tree.c $(wildcard jets/*/*.c)
noun = $(wildcard noun/*.c) noun = $(wildcard noun/*.c)
@ -9,7 +10,9 @@ worker = $(wildcard worker/*.c)
tests = $(wildcard tests/*.c) tests = $(wildcard tests/*.c)
bench = $(wildcard bench/*.c) bench = $(wildcard bench/*.c)
common = $(jets) $(noun) $(ur) $(vere) compat := $(foreach dir,$(compat),$(wildcard compat/$(dir)/*.c))
common = $(jets) $(noun) $(ur) $(vere) $(compat)
headers = $(shell find include -type f) headers = $(shell find include -type f)
common_objs = $(shell echo $(common) | sed 's/\.c/.o/g') common_objs = $(shell echo $(common) | sed 's/\.c/.o/g')
@ -29,7 +32,7 @@ CFLAGS := $(CFLAGS)
################################################################################ ################################################################################
.PHONY: all test clean mkproper .PHONY: all test clean mrproper
################################################################################ ################################################################################
@ -74,9 +77,11 @@ build/urbit-worker: $(common_objs) $(worker_objs)
@mkdir -p ./build @mkdir -p ./build
@$(CC) $^ $(LDFLAGS) -o $@ @$(CC) $^ $(LDFLAGS) -o $@
%.o: %.c $(headers) # CCDEPS and CCEXTRA are empty except in MingW build,
# which uses them to inject a C source transform step
%.o: %.c $(headers) $(CCDEPS)
@echo CC $< @echo CC $<
@$(CC) -I./include $(CFLAGS) -c $< -o $@ @$(CC) -I./include $(CFLAGS) $< $(CCEXTRA) -c -o $@
tags: $(all_srcs) $(headers) tags: $(all_srcs) $(headers)
ctags $^ ctags $^

View File

@ -0,0 +1,22 @@
#!/usr/bin/env bash
# support running off a tarball that doesn't contain binary pills
(( $($1 ../../bin/ivory.pill) > 512 )) || curl -L https://github.com/urbit/urbit/raw/urbit-v$URBIT_VERSION/bin/ivory.pill > ../../bin/ivory.pill
poor_mans_xxd () {
cch=0
echo "unsigned char $2[] = {"
while IFS='' read line
do
for i in $line
do
echo -n " 0x$i,"
cch=$((cch+1))
done
echo
done < <(od -An -v -tx1 $1)
echo "};"
echo "unsigned int $2_len = $cch;"
}
[ -e include/ca-bundle.h ] || poor_mans_xxd $2 include_ca_bundle_crt >include/ca-bundle.h
[ -e include/ivory.h ] || poor_mans_xxd ../../bin/ivory.pill u3_Ivory_pill >include/ivory.h

View File

@ -0,0 +1,14 @@
# paths to brew packages
CFLAGS := $(CFLAGS) -I/opt/homebrew/include
LDFLAGS := $(LDFLAGS) -L/opt/homebrew/lib
# force linker to use static libraries
LDFLAGS := $(shell compat/m1brew/use-static-libs.sh $(LDFLAGS))
# add extra osx libraries
LDFLAGS := $(LDFLAGS) -framework SystemConfiguration
ifdef debug
CFLAGS := $(CFLAGS) -O0 -g
else
# clang hangs on noun/allocate.c if -g is specified with -O3
CFLAGS := $(CFLAGS) -O3
endif

View File

@ -0,0 +1,13 @@
diff --git a/Makefile b/Makefile
new file mode 100644
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,8 @@
+.PHONY: all clean
+
+all: *.c *.h
+ $(CC) -c -O3 -Wall -Werror *.c
+ $(AR) rcs libed25519.a *.o
+
+clean:
+ rm -f *.o *.a

View File

@ -0,0 +1,12 @@
diff --git a/configure b/configure
--- a/configure
+++ b/configure
@@ -15,7 +15,7 @@ do
log "Trying IMPL=$IMPL"
if IMPL=$impl make >/dev/null 2>/dev/null
- then sed -i 's|$(error IMPL must be set)|IMPL='"$impl"'|' Makefile
+ then sed -i "" 's|$(error IMPL must be set)|IMPL='"$impl"'|' Makefile
log "IMPL=$IMPL works"
exit 0
else log "IMPL=$IMPL failed"

View File

@ -0,0 +1,17 @@
diff --git a/Makefile b/Makefile
index 783c537..3156ee2 100644
--- a/Makefile
+++ b/Makefile
@@ -12,10 +12,9 @@ LDFLAGS_EXTRA?=-Wl,-z,relro
all: reference
-OBJS= crypto_scrypt-nosse.o sha256.o crypto-mcf.o b64.o crypto-scrypt-saltgen.o crypto_scrypt-check.o crypto_scrypt-hash.o slowequals.o
+OBJS= crypto_scrypt-nosse.o sha256.o crypto-mcf.o b64.o slowequals.o
-libscrypt.so.0: $(OBJS)
- $(CC) $(LDFLAGS) -shared -o libscrypt.so.0 $(OBJS) -lm -lc
+libscrypt.a: $(OBJS)
ar rcs libscrypt.a $(OBJS)
reference: libscrypt.so.0 main.o crypto_scrypt-hexconvert.o

View File

@ -0,0 +1,13 @@
diff --git a/makefile b/makefile
--- a/makefile
+++ b/makefile
@@ -12,5 +12,9 @@ shared: murmur3.c murmur3.h
$(CC) -fPIC -O3 -c murmur3.c
$(CC) -shared -Wl,--export-dynamic murmur3.o -o libmurmur3.so
+static: murmur3.c murmur3.h
+ $(CC) -fPIC -O3 -c murmur3.c
+ $(AR) rcs libmurmur3.a murmur3.o
+
clean:
rm -rf example *.o *.so

View File

@ -0,0 +1,85 @@
diff --git a/build/template-FAST_INT64/Makefile b/build/template-FAST_INT64/Makefile
--- a/build/template-FAST_INT64/Makefile
+++ b/build/template-FAST_INT64/Makefile
@@ -34,28 +34,27 @@
#
#=============================================================================
-# Edit lines marked with `==>'. See "SoftFloat-source.html".
+SOURCE_DIR ?= ../../source
+SPECIALIZE_TYPE ?= 8086-SSE
-==> SOURCE_DIR ?= ../../source
-==> SPECIALIZE_TYPE ?= 8086
+SOFTFLOAT_OPTS ?= \
+ -DSOFTFLOAT_ROUND_ODD -DINLINE_LEVEL=5 -DSOFTFLOAT_FAST_DIV32TO16 \
+ -DSOFTFLOAT_FAST_DIV64TO32
-==> SOFTFLOAT_OPTS ?= \
-==> -DSOFTFLOAT_ROUND_ODD -DINLINE_LEVEL=5 -DSOFTFLOAT_FAST_DIV32TO16 \
-==> -DSOFTFLOAT_FAST_DIV64TO32
+DELETE = rm -f
+C_INCLUDES = -I. -I$(SOURCE_DIR)/$(SPECIALIZE_TYPE) -I$(SOURCE_DIR)/include
+COMPILE_C = \
+ cc -c -DSOFTFLOAT_FAST_INT64 $(SOFTFLOAT_OPTS) $(C_INCLUDES) -O2 -o $@
+MAKELIB = ar crs $@
+LIBNAME = libsoftfloat3
-==> DELETE = rm -f
-==> C_INCLUDES = -I. -I$(SOURCE_DIR)/$(SPECIALIZE_TYPE) -I$(SOURCE_DIR)/include
-==> COMPILE_C = \
-==> cc -c -DSOFTFLOAT_FAST_INT64 $(SOFTFLOAT_OPTS) $(C_INCLUDES) -O2 -o $@
-==> MAKELIB = ar crs $@
+OBJ = .o
+LIB = .a
-==> OBJ = .o
-==> LIB = .a
-
-==> OTHER_HEADERS =
+OTHER_HEADERS =
.PHONY: all
-all: softfloat$(LIB)
+all: $(LIBNAME)$(LIB)
OBJS_PRIMITIVES = \
s_eq128$(OBJ) \
@@ -381,11 +380,11 @@ $(OBJS_PRIMITIVES) $(OBJS_OTHERS): %$(OBJ): $(SOURCE_DIR)/%.c
$(OBJS_SPECIALIZE): %$(OBJ): $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/%.c
$(COMPILE_C) $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/$*.c
-softfloat$(LIB): $(OBJS_ALL)
+$(LIBNAME)$(LIB): $(OBJS_ALL)
$(DELETE) $@
$(MAKELIB) $^
.PHONY: clean
clean:
- $(DELETE) $(OBJS_ALL) softfloat$(LIB)
+ $(DELETE) $(OBJS_ALL) $(LIBNAME)$(LIB)
diff --git a/build/template-FAST_INT64/platform.h b/build/template-FAST_INT64/platform.h
--- a/build/template-FAST_INT64/platform.h
+++ b/build/template-FAST_INT64/platform.h
@@ -34,17 +34,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
-// Edit lines marked with `==>'. See "SoftFloat-source.html".
-
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
-==> #define LITTLEENDIAN 1
+#define LITTLEENDIAN 1
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
-==> #define INLINE inline
+#define INLINE inline
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
-==> #define THREAD_LOCAL _Thread_local
+#define THREAD_LOCAL _Thread_local

View File

@ -0,0 +1,23 @@
#!/bin/bash
set -euo pipefail
declare -a ldirs
for i in $@
do
case $i in
-L*) ldirs+=(${i:2});;
esac
done
for i in $@
do
case $i in
-l*)
lib=$(find ${ldirs[@]} -name lib${i:2}.a)
if [ "$lib" != "" ]
then
echo $lib
else
echo $i
fi;;
*) echo $i;;
esac
done

View File

@ -0,0 +1,355 @@
#include "c/portable.h"
#include <fcntl.h>
#include <sys/utime.h>
#include <windows.h>
// set default CRT file mode to binary
// note that mingw binmode.o does nothing
#undef _fmode
int _fmode = _O_BINARY;
// set standard I/O fds to binary too, because
// MSVCRT creates them before MingW sets _fmode
static void __attribute__ ((constructor)) _set_stdio_to_binary()
{
_setmode(0, _O_BINARY);
_setmode(1, _O_BINARY);
_setmode(2, _O_BINARY);
}
// from https://github.com/git/git/blob/master/compat/mingw.c
// -----------------------------------------------------------------------
int err_win_to_posix(DWORD winerr)
{
int error = ENOSYS;
switch(winerr) {
case ERROR_ACCESS_DENIED: error = EACCES; break;
case ERROR_ACCOUNT_DISABLED: error = EACCES; break;
case ERROR_ACCOUNT_RESTRICTION: error = EACCES; break;
case ERROR_ALREADY_ASSIGNED: error = EBUSY; break;
case ERROR_ALREADY_EXISTS: error = EEXIST; break;
case ERROR_ARITHMETIC_OVERFLOW: error = ERANGE; break;
case ERROR_BAD_COMMAND: error = EIO; break;
case ERROR_BAD_DEVICE: error = ENODEV; break;
case ERROR_BAD_DRIVER_LEVEL: error = ENXIO; break;
case ERROR_BAD_EXE_FORMAT: error = ENOEXEC; break;
case ERROR_BAD_FORMAT: error = ENOEXEC; break;
case ERROR_BAD_LENGTH: error = EINVAL; break;
case ERROR_BAD_PATHNAME: error = ENOENT; break;
case ERROR_BAD_PIPE: error = EPIPE; break;
case ERROR_BAD_UNIT: error = ENODEV; break;
case ERROR_BAD_USERNAME: error = EINVAL; break;
case ERROR_BROKEN_PIPE: error = EPIPE; break;
case ERROR_BUFFER_OVERFLOW: error = ENAMETOOLONG; break;
case ERROR_BUSY: error = EBUSY; break;
case ERROR_BUSY_DRIVE: error = EBUSY; break;
case ERROR_CALL_NOT_IMPLEMENTED: error = ENOSYS; break;
case ERROR_CANNOT_MAKE: error = EACCES; break;
case ERROR_CANTOPEN: error = EIO; break;
case ERROR_CANTREAD: error = EIO; break;
case ERROR_CANTWRITE: error = EIO; break;
case ERROR_CRC: error = EIO; break;
case ERROR_CURRENT_DIRECTORY: error = EACCES; break;
case ERROR_DEVICE_IN_USE: error = EBUSY; break;
case ERROR_DEV_NOT_EXIST: error = ENODEV; break;
case ERROR_DIRECTORY: error = EINVAL; break;
case ERROR_DIR_NOT_EMPTY: error = ENOTEMPTY; break;
case ERROR_DISK_CHANGE: error = EIO; break;
case ERROR_DISK_FULL: error = ENOSPC; break;
case ERROR_DRIVE_LOCKED: error = EBUSY; break;
case ERROR_ENVVAR_NOT_FOUND: error = EINVAL; break;
case ERROR_EXE_MARKED_INVALID: error = ENOEXEC; break;
case ERROR_FILENAME_EXCED_RANGE: error = ENAMETOOLONG; break;
case ERROR_FILE_EXISTS: error = EEXIST; break;
case ERROR_FILE_INVALID: error = ENODEV; break;
case ERROR_FILE_NOT_FOUND: error = ENOENT; break;
case ERROR_GEN_FAILURE: error = EIO; break;
case ERROR_HANDLE_DISK_FULL: error = ENOSPC; break;
case ERROR_INSUFFICIENT_BUFFER: error = ENOMEM; break;
case ERROR_INVALID_ACCESS: error = EACCES; break;
case ERROR_INVALID_ADDRESS: error = EFAULT; break;
case ERROR_INVALID_BLOCK: error = EFAULT; break;
case ERROR_INVALID_DATA: error = EINVAL; break;
case ERROR_INVALID_DRIVE: error = ENODEV; break;
case ERROR_INVALID_EXE_SIGNATURE: error = ENOEXEC; break;
case ERROR_INVALID_FLAGS: error = EINVAL; break;
case ERROR_INVALID_FUNCTION: error = ENOSYS; break;
case ERROR_INVALID_HANDLE: error = EBADF; break;
case ERROR_INVALID_LOGON_HOURS: error = EACCES; break;
case ERROR_INVALID_NAME: error = EINVAL; break;
case ERROR_INVALID_OWNER: error = EINVAL; break;
case ERROR_INVALID_PARAMETER: error = EINVAL; break;
case ERROR_INVALID_PASSWORD: error = EPERM; break;
case ERROR_INVALID_PRIMARY_GROUP: error = EINVAL; break;
case ERROR_INVALID_SIGNAL_NUMBER: error = EINVAL; break;
case ERROR_INVALID_TARGET_HANDLE: error = EIO; break;
case ERROR_INVALID_WORKSTATION: error = EACCES; break;
case ERROR_IO_DEVICE: error = EIO; break;
case ERROR_IO_INCOMPLETE: error = EINTR; break;
case ERROR_LOCKED: error = EBUSY; break;
case ERROR_LOCK_VIOLATION: error = EACCES; break;
case ERROR_LOGON_FAILURE: error = EACCES; break;
case ERROR_MAPPED_ALIGNMENT: error = EINVAL; break;
case ERROR_META_EXPANSION_TOO_LONG: error = E2BIG; break;
case ERROR_MORE_DATA: error = EPIPE; break;
case ERROR_NEGATIVE_SEEK: error = ESPIPE; break;
case ERROR_NOACCESS: error = EFAULT; break;
case ERROR_NONE_MAPPED: error = EINVAL; break;
case ERROR_NOT_ENOUGH_MEMORY: error = ENOMEM; break;
case ERROR_NOT_READY: error = EAGAIN; break;
case ERROR_NOT_SAME_DEVICE: error = EXDEV; break;
case ERROR_NO_DATA: error = EPIPE; break;
case ERROR_NO_MORE_SEARCH_HANDLES: error = EIO; break;
case ERROR_NO_PROC_SLOTS: error = EAGAIN; break;
case ERROR_NO_SUCH_PRIVILEGE: error = EACCES; break;
case ERROR_OPEN_FAILED: error = EIO; break;
case ERROR_OPEN_FILES: error = EBUSY; break;
case ERROR_OPERATION_ABORTED: error = EINTR; break;
case ERROR_OUTOFMEMORY: error = ENOMEM; break;
case ERROR_PASSWORD_EXPIRED: error = EACCES; break;
case ERROR_PATH_BUSY: error = EBUSY; break;
case ERROR_PATH_NOT_FOUND: error = ENOENT; break;
case ERROR_PIPE_BUSY: error = EBUSY; break;
case ERROR_PIPE_CONNECTED: error = EPIPE; break;
case ERROR_PIPE_LISTENING: error = EPIPE; break;
case ERROR_PIPE_NOT_CONNECTED: error = EPIPE; break;
case ERROR_PRIVILEGE_NOT_HELD: error = EACCES; break;
case ERROR_READ_FAULT: error = EIO; break;
case ERROR_SEEK: error = EIO; break;
case ERROR_SEEK_ON_DEVICE: error = ESPIPE; break;
case ERROR_SHARING_BUFFER_EXCEEDED: error = ENFILE; break;
case ERROR_SHARING_VIOLATION: error = EACCES; break;
case ERROR_STACK_OVERFLOW: error = ENOMEM; break;
case ERROR_SUCCESS: error = 0; break;
case ERROR_SWAPERROR: error = ENOENT; break;
case ERROR_TOO_MANY_MODULES: error = EMFILE; break;
case ERROR_TOO_MANY_OPEN_FILES: error = EMFILE; break;
case ERROR_UNRECOGNIZED_MEDIA: error = ENXIO; break;
case ERROR_UNRECOGNIZED_VOLUME: error = ENODEV; break;
case ERROR_WAIT_NO_CHILDREN: error = ECHILD; break;
case ERROR_WRITE_FAULT: error = EIO; break;
case ERROR_WRITE_PROTECT: error = EROFS; break;
}
return error;
}
// from msys2 mingw-packages-dev patches
// -----------------------------------------------------------------------
static DWORD __map_mmap_prot_page(const int prot)
{
DWORD protect = 0;
if (prot == PROT_NONE)
return protect;
if ((prot & PROT_EXEC) != 0)
{
protect = ((prot & PROT_WRITE) != 0) ?
PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
}
else
{
protect = ((prot & PROT_WRITE) != 0) ?
PAGE_READWRITE : PAGE_READONLY;
}
return protect;
}
static DWORD __map_mmap_prot_file(const int prot)
{
DWORD desiredAccess = 0;
if (prot == PROT_NONE)
return desiredAccess;
if ((prot & PROT_READ) != 0)
desiredAccess |= FILE_MAP_READ;
if ((prot & PROT_WRITE) != 0)
desiredAccess |= FILE_MAP_WRITE;
if ((prot & PROT_EXEC) != 0)
desiredAccess |= FILE_MAP_EXECUTE;
return desiredAccess;
}
void* mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off)
{
HANDLE fm, h;
void * map = MAP_FAILED;
const DWORD dwFileOffsetLow = (sizeof(off_t) <= sizeof(DWORD)) ?
(DWORD)off : (DWORD)(off & 0xFFFFFFFFL);
const DWORD dwFileOffsetHigh = (sizeof(off_t) <= sizeof(DWORD)) ?
(DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL);
const DWORD protect = __map_mmap_prot_page(prot);
const DWORD desiredAccess = __map_mmap_prot_file(prot);
errno = 0;
if (len == 0
/* Usupported protection combinations */
|| prot == PROT_EXEC)
{
errno = EINVAL;
return MAP_FAILED;
}
if ((flags & MAP_ANON) == 0)
{
h = (HANDLE)_get_osfhandle(fildes);
if (h == INVALID_HANDLE_VALUE)
{
errno = EBADF;
return MAP_FAILED;
}
}
else h = INVALID_HANDLE_VALUE;
fm = CreateFileMapping(h, NULL, protect, 0, len, NULL);
if (fm == NULL)
{
errno = err_win_to_posix(GetLastError());
return MAP_FAILED;
}
map = MapViewOfFileEx(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len, addr);
errno = err_win_to_posix(GetLastError());
CloseHandle(fm);
if (map == NULL)
return MAP_FAILED;
if ((flags & MAP_FIXED) != 0 && map != addr)
{
UnmapViewOfFile(map);
errno = EEXIST;
return MAP_FAILED;
}
return map;
}
int munmap(void *addr, size_t len)
{
if (UnmapViewOfFile(addr))
return 0;
errno = err_win_to_posix(GetLastError());
return -1;
}
int msync(void *addr, size_t len, int flags)
{
if (FlushViewOfFile(addr, len))
return 0;
errno = err_win_to_posix(GetLastError());
return -1;
}
// -----------------------------------------------------------------------
// vere uses kill() only to kill lockfile owner with SIGTERM or SIGKILL
// Windows does not have signals, so I handle SIGKILL as TerminateProcess()
// and return an error in all other cases
int kill(pid_t pid, int sig)
{
if (pid > 0 && sig == SIGKILL) {
HANDLE h = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
if (TerminateProcess(h, -1)) {
CloseHandle(h);
return 0;
}
errno = err_win_to_posix(GetLastError());
CloseHandle(h);
return -1;
}
errno = EINVAL;
return -1;
}
// libgcc built for mingw has included an implementation of mprotect
// via VirtualProtect since olden days, but it takes int rather than size_t
// and therefore fails or does unexpected things for >2GB blocks on 64-bit
// https://github.com/gcc-mirror/gcc/blob/master/libgcc/libgcc2.c
int mprotect (void *addr, size_t len, int prot)
{
DWORD np, op;
if (prot == (PROT_READ | PROT_WRITE | PROT_EXEC))
np = PAGE_EXECUTE_READWRITE;
else if (prot == (PROT_READ | PROT_EXEC))
np = PAGE_EXECUTE_READ;
else if (prot == (PROT_EXEC))
np = PAGE_EXECUTE;
else if (prot == (PROT_READ | PROT_WRITE))
np = PAGE_READWRITE;
else if (prot == (PROT_READ))
np = PAGE_READONLY;
else if (prot == 0)
np = PAGE_NOACCESS;
else
{
errno = EINVAL;
return -1;
}
if (VirtualProtect (addr, len, np, &op))
return 0;
// NB: return code of ntdll!RtlGetLastNtStatus() is useful
// for diagnosing obscure VirtualProtect failures
errno = err_win_to_posix(GetLastError());
return -1;
}
int utimes(const char *path, const struct timeval times[2])
{
struct _utimbuf utb = {.actime = times[0].tv_sec, .modtime = times[1].tv_sec};
return _utime(path, &utb);
}
int fdatasync(int fildes)
{
HANDLE h = (HANDLE)_get_osfhandle(fildes);
if (h == INVALID_HANDLE_VALUE)
{
errno = EBADF;
return -1;
}
if (FlushFileBuffers(h))
{
errno = 0;
return 0;
}
else
{
errno = err_win_to_posix(GetLastError());
return -1;
}
}
intmax_t mdb_get_filesize(HANDLE han_u)
{
LARGE_INTEGER li;
GetFileSizeEx(han_u, &li);
return li.QuadPart;
}
char *realpath(const char *path, char *resolved_path)
{
// TODO
return strdup(path);
}

View File

@ -0,0 +1,18 @@
#ifndef _MINGW_IO_H
#define _MINGW_IO_H
#define mkdir(A, B) mkdir(A)
char *realpath(const char *path, char *resolved_path);
int fdatasync(int fd);
int utimes(const char *path, const struct timeval times[2]);
int kill(pid_t pid, int signum);
#define SIGUSR1 10
#define SIGALRM 14
#define SIGVTALRM 26
#define SIGSTK 31
#define SIG_COUNT 32
#endif//_MINGW_IO_H

View File

@ -0,0 +1,15 @@
# increase default thread stack size and link Windows implibs
LDFLAGS := $(LDFLAGS) -static -Wl,--stack,67108864 -lbcrypt -lntdll -lws2_32
# libcurl
CFLAGS := $(CFLAGS) -DCURL_STATICLIB
LDFLAGS := $(LDFLAGS) -lzstd -lcrypt32
# libh2o
CFLAGS := $(CFLAGS) -DH2O_NO_UNIX_SOCKETS
# libuv
LDFLAGS := $(LDFLAGS) -luserenv -liphlpapi -lpsapi
ifdef debug
CFLAGS := $(CFLAGS) -O0 -g
else
CFLAGS := $(CFLAGS) -O3 -g
endif

View File

@ -0,0 +1,7 @@
#include <signal.h>
// initialize msvcrt signals early, otherwise Ctrl-C does nothing
static void __attribute__ ((constructor)) _init_crt_signals()
{
signal(SIGINT, SIG_DFL);
}

View File

@ -0,0 +1,116 @@
#include "all.h"
#include "vere/vere.h"
/* _dup_std_handle(): creates an inheritable duplicate of a standard handle.
*/
static BOOL
_dup_std_handle(HANDLE* new_u, DWORD typ_u)
{
DWORD dum_u;
HANDLE han_u = GetStdHandle(typ_u);
BOOL con_u = GetConsoleMode(han_u, &dum_u);
if ( con_u ) {
han_u = (HANDLE)_get_osfhandle(open(c3_dev_null, O_RDWR, 0));
}
if ( !DuplicateHandle(GetCurrentProcess(), han_u, GetCurrentProcess(), new_u, 0, TRUE, DUPLICATE_SAME_ACCESS) ) {
fprintf(stderr, "vere: DuplicateHandle(%d): %d\r\n", typ_u, GetLastError());
exit(1);
}
return con_u;
}
/* _on_boot_completed_cb: invoked when the ship has finished booting.
*/
static void _on_boot_completed_cb() {
HANDLE hin_u = GetStdHandle(STD_INPUT_HANDLE);
SetEvent(hin_u);
CloseHandle(hin_u);
}
/* u3_daemon_init(): platform-specific daemon mode initialization.
*/
void
u3_daemon_init()
{
// detect if this process is the child daemon process
//
if ( ResetEvent(GetStdHandle(STD_INPUT_HANDLE)) ) {
u3_Host.bot_f = _on_boot_completed_cb;
return;
}
STARTUPINFOW psi_u;
ZeroMemory(&psi_u, sizeof(psi_u));
psi_u.cb = sizeof(psi_u);
psi_u.dwFlags = STARTF_USESTDHANDLES;
// duplicate standard output and error handles for the child process,
// replacing any raw console handles with handles to /dev/null
// print a warning if raw console output detected
//
// On Windows, console handles become invalid once the console is
// detached. This will cause urbit terminal output to fail. libuv
// provides no way of changing the handle of an open uv_pipe_handle,
// and Windows has no equivalent of dup2() for handles, so I cannot
// substitute a /dev/null handle once the terminal is initialized.
// It is possible to create an anonymous pipe and have the child
// process take over its drain end after it signals that the ship
// has booted, but -d is intended for background operation anyway
// and does not seem to warrant the added complexity.
//
if ( _dup_std_handle(&psi_u.hStdOutput, STD_OUTPUT_HANDLE) |
_dup_std_handle(&psi_u.hStdError, STD_ERROR_HANDLE) )
{
fprintf(stderr, "vere: -d used from a Windows console without redirection\r\n"
" no output from the daemon process will be visible\r\n");
fflush(stderr);
}
// create an event for the child process to signal
// the parent that the ship has finished booting
// pass the handle as "stdin" (otherwise unused with -d)
//
SECURITY_ATTRIBUTES sa_u = {sizeof (SECURITY_ATTRIBUTES), NULL, TRUE};
if ( !(psi_u.hStdInput = CreateEvent(&sa_u, TRUE, FALSE, NULL)) ) {
fprintf(stderr, "vere: CreateEvent: %d\r\n", GetLastError());
exit(1);
}
// create the child process with the same command line as parent
// it will start, re-parse the command line, and call u3_daemon_init
//
PROCESS_INFORMATION ppi_u;
if ( !CreateProcessW(NULL, _wcsdup(GetCommandLineW()), NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &psi_u, &ppi_u) ) {
fprintf(stderr, "vere: CreateProcess: %d\r\n", GetLastError());
exit(1);
}
CloseHandle(ppi_u.hThread);
// wait for the child process to exit or to signal the event
//
DWORD exi_u;
HANDLE han_u[2] = {ppi_u.hProcess, psi_u.hStdInput};
switch ( WaitForMultipleObjects(2, han_u, FALSE, INFINITE) ) {
case WAIT_OBJECT_0:
// the child process exited prematurely, propagate its exit code
//
if ( GetExitCodeProcess(ppi_u.hProcess, &exi_u) ) {
exit(exi_u);
}
fprintf(stderr, "vere: GetExitCodeProcess: %d\r\n", GetLastError());
exit(1);
case WAIT_OBJECT_0 + 1:
// the child process has finished booting, exit normally
//
exit(0);
default:
fprintf(stderr, "vere: WaitForMultipleObjects: %d\r\n", GetLastError());
exit(1);
}
}

View File

@ -0,0 +1,13 @@
diff --git a/Makefile b/Makefile
new file mode 100644
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,8 @@
+.PHONY: all clean
+
+all: *.c *.h
+ $(CC) -c -O3 -Wall -Werror *.c
+ $(AR) rcs libed25519.a *.o
+
+clean:
+ rm -f *.o *.a

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,17 @@
diff --git a/Makefile b/Makefile
index 783c537..3156ee2 100644
--- a/Makefile
+++ b/Makefile
@@ -12,10 +12,9 @@ LDFLAGS_EXTRA?=-Wl,-z,relro
all: reference
-OBJS= crypto_scrypt-nosse.o sha256.o crypto-mcf.o b64.o crypto-scrypt-saltgen.o crypto_scrypt-check.o crypto_scrypt-hash.o slowequals.o
+OBJS= crypto_scrypt-nosse.o sha256.o crypto-mcf.o b64.o slowequals.o
-libscrypt.so.0: $(OBJS)
- $(CC) $(LDFLAGS) -shared -o libscrypt.so.0 $(OBJS) -lm -lc
+libscrypt.a: $(OBJS)
ar rcs libscrypt.a $(OBJS)
reference: libscrypt.so.0 main.o crypto_scrypt-hexconvert.o

View File

@ -0,0 +1,74 @@
diff --git a/mdb.c b/mdb.c
--- a/mdb.c
+++ b/mdb.c
@@ -1707,28 +1707,27 @@ static char *const mdb_errstr[] = {
"MDB_PROBLEM: Unexpected problem - txn should abort",
};
-char *
-mdb_strerror(int err)
+void
+mdb_logerror(FILE* f, int err, const char* fmt, ...)
{
-#ifdef _WIN32
- /** HACK: pad 4KB on stack over the buf. Return system msgs in buf.
- * This works as long as no function between the call to mdb_strerror
- * and the actual use of the message uses more than 4K of stack.
- */
-#define MSGSIZE 1024
-#define PADSIZE 4096
- char buf[MSGSIZE+PADSIZE], *ptr = buf;
-#endif
+ va_list ap;
+ va_start(ap, fmt);
+ vfprintf(f, fmt, ap);
+ va_end(ap);
+
int i;
if (!err)
- return ("Successful return: 0");
+ {
+ fprintf(stderr, ": %s\r\n", "Successful return: 0");
+ return;
+ }
if (err >= MDB_KEYEXIST && err <= MDB_LAST_ERRCODE) {
i = err - MDB_KEYEXIST;
- return mdb_errstr[i];
+ fprintf(stderr, ": %s\r\n", mdb_errstr[i]);
+ return;
}
-#ifdef _WIN32
/* These are the C-runtime error codes we use. The comment indicates
* their numeric value, and the Win32 error they would correspond to
* if the error actually came from a Win32 API. A major mess, we should
@@ -1742,18 +1741,20 @@ mdb_strerror(int err)
case EBUSY: /* 16, CURRENT_DIRECTORY */
case EINVAL: /* 22, BAD_COMMAND */
case ENOSPC: /* 28, OUT_OF_PAPER */
- return strerror(err);
+ fprintf(stderr, ": %s\r\n", strerror(err));
default:
;
}
- buf[0] = 0;
- FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
+ LPSTR ptr;
+ if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, err, 0, ptr, MSGSIZE, (va_list *)buf+MSGSIZE);
- return ptr;
-#else
- return strerror(err);
-#endif
+ NULL, err, 0, (LPSTR)&ptr, sizeof (LPSTR), NULL))
+ {
+ fprintf(stderr, ": %s\r\n", ptr);
+ LocalFree(ptr);
+ } else
+ fprintf(stderr, ": <%d>\r\n", err);
}
/** assert(3) variant in cursor context */

View File

@ -0,0 +1,26 @@
#ifndef _SYS_MMAN_H
#define _SYS_MMAN_H
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
int munmap(void *addr, size_t length);
int msync(void *addr, size_t length, int flags);
int mprotect(void *addr, size_t len, int prot);
#define PROT_NONE 0x00 /* No access. */
#define PROT_READ 0x01 /* Pages can be read. */
#define PROT_WRITE 0x02 /* Pages can be written. */
#define PROT_EXEC 0x04 /* Pages can be executed. */
#define MAP_FILE 0x0001 /* Mapped from a file or device. */
#define MAP_ANON 0x0002 /* Allocated from anonymous virtual memory. */
#define MAP_TYPE 0x000f /* Mask for type field. */
#define MAP_SHARED 0x0010 /* Share changes. */
#define MAP_PRIVATE 0x0000 /* Changes private; copy pages on write. */
#define MAP_FIXED 0x0100 /* Map address must be exactly as requested. */
#define MAP_FAILED ((void *) -1)
#define MS_ASYNC 1 /* Sync memory asynchronously. */
#define MS_SYNC 0 /* Synchronous memory sync. */
#define MS_INVALIDATE 2 /* Invalidate the caches. */
#endif//_SYS_MMAN_H

View File

@ -0,0 +1,13 @@
diff --git a/makefile b/makefile
--- a/makefile
+++ b/makefile
@@ -12,5 +12,9 @@ shared: murmur3.c murmur3.h
$(CC) -fPIC -O3 -c murmur3.c
$(CC) -shared -Wl,--export-dynamic murmur3.o -o libmurmur3.so
+static: murmur3.c murmur3.h
+ $(CC) -fPIC -O3 -c murmur3.c
+ $(AR) rcs libmurmur3.a murmur3.o
+
clean:
rm -rf example *.o *.so

View File

@ -0,0 +1,152 @@
/* compat/mingw/ptty.c
**
*/
#include "all.h"
#include "vere/vere.h"
#include <winternl.h>
/* _ptty_get_type(): detects tty type.
*/
static DWORD
_ptty_get_type(int fd)
{
HANDLE h = (HANDLE)_get_osfhandle(fd);
if (h == INVALID_HANDLE_VALUE)
return FILE_TYPE_UNKNOWN;
DWORD t = GetFileType(h);
if (t != FILE_TYPE_PIPE)
return t ;
// https://github.com/fusesource/jansi-native/commit/461068c67a38647d2890e96250636fc0117074f5
ULONG result;
BYTE buffer[1024];
POBJECT_NAME_INFORMATION nameinfo = (POBJECT_NAME_INFORMATION) buffer;
PWSTR name;
/* get pipe name */
if (!NT_SUCCESS(NtQueryObject(h, ObjectNameInformation, buffer, sizeof(buffer) - sizeof(WCHAR), &result)))
return FILE_TYPE_UNKNOWN;
name = nameinfo->Name.Buffer;
name[nameinfo->Name.Length] = 0;
// check for popular terminal emulators
// that use named pipes to communicate with subprocesses
if (wcsstr(name, L"\\ConEmu") ||
(wcsstr(name, L"msys-") || wcsstr(name, L"cygwin-")) && wcsstr(name, L"-pty"))
return FILE_TYPE_PIPE;
return FILE_TYPE_UNKNOWN;
}
/* _ttyf_nop(): stub function.
*/
static c3_o
_ttyf_nop(u3_utty* uty_u)
{
return c3y;
}
/* _ttyf_start_raw_input(): ends raw input on the tty.
*/
static c3_o
_ttyf_set_normal(u3_utty* uty_u)
{
c3_i e;
if ( 0 != (e = uv_tty_set_mode(&uty_u->pin_u.tty_u, UV_TTY_MODE_NORMAL)) ) {
fprintf(stderr, "uv_tty_set_mode(UV_TTY_MODE_NORMAL) -> %d\r\n", e);
return c3n;
}
return c3y;
}
/* _ttyf_start_raw_input(): sets the tty to raw input.
*/
static c3_o
_ttyf_set_raw(u3_utty* uty_u)
{
c3_i e;
if ( 0 != (e = uv_tty_set_mode(&uty_u->pin_u.tty_u, UV_TTY_MODE_RAW)) ) {
fprintf(stderr, "uv_tty_set_mode(UV_TTY_MODE_RAW) -> %d\r\n", e);
return c3n;
}
return c3y;
}
/* _ttyf_get_winsize(): gets the tty window size.
*/
static c3_o
_ttyf_get_winsize(u3_utty* uty_u, c3_l* col_l, c3_l* row_l)
{
c3_i col_i, row_i;
if ( 0 != uv_tty_get_winsize(&uty_u->pop_u.tty_u, &col_i, &row_i) ) {
return c3n;
}
*col_l = col_i;
*row_l = row_i;
return c3y;
}
/* _ttyf_get_winsize(): gets the tty window size.
*/
static c3_o
_ttyf_nop_winsize(u3_utty* uty_u, c3_l* col_l, c3_l* row_l)
{
return c3n;
}
/* u3_ptty_init(): initialize platform-specific tty.
*/
u3_utty*
u3_ptty_init(uv_loop_t* lup_u, const c3_c** err_c)
{
DWORD pip_l = _ptty_get_type(0);
DWORD pop_l = _ptty_get_type(1);
if ( pip_l == FILE_TYPE_UNKNOWN || pop_l == FILE_TYPE_UNKNOWN) {
*err_c = "not a tty";
return NULL;
}
if ( pip_l != pop_l ) {
*err_c = "partly redirected";
return NULL;
}
c3_i e;
u3_utty* uty_u = c3_calloc(sizeof(u3_utty));
if ( pip_l == FILE_TYPE_CHAR ) {
if ( 0 == (e = uv_tty_init(lup_u, &uty_u->pin_u.tty_u, 0, 0)) &&
0 == (e = uv_tty_init(lup_u, &uty_u->pop_u.tty_u, 1, 0)) )
{
SetConsoleOutputCP(CP_UTF8);
uty_u->sta_f = _ttyf_set_raw;
uty_u->sto_f = _ttyf_set_normal;
uty_u->wsz_f = _ttyf_get_winsize;
}
} else {
if ( 0 == (e = uv_pipe_init(lup_u, &uty_u->pin_u.pop_u, 0)) &&
0 == (e = uv_pipe_init(lup_u, &uty_u->pop_u.pop_u, 0)) &&
0 == (e = uv_pipe_open(&uty_u->pin_u.pop_u, 0)) &&
0 == (e = uv_pipe_open(&uty_u->pop_u.pop_u, 1)) )
{
fprintf(stderr, "vere: running interactive in a terminal emulator is experimental\r\n"
" use -t to disable interactivity or use native Windows console\r\n") ;
uty_u->sta_f = _ttyf_nop;
uty_u->sto_f = _ttyf_nop;
uty_u->wsz_f = _ttyf_nop_winsize;
}
}
if ( e ) {
*err_c = uv_strerror(e);
c3_free(uty_u);
return NULL;
}
uty_u->fid_i = 1;
uty_u->hij_f = _ttyf_nop;
uty_u->loj_f = _ttyf_nop;
return uty_u;
}

View File

@ -0,0 +1,167 @@
#include "all.h"
#include "rsignal.h"
#include <windows.h>
int err_win_to_posix(DWORD winerr);
// The current implementation of rsignal_ is single-threaded,
// but it can be extended to multi-threaded by replacing these
// static variables with a thread id-based hash map.
//
static __p_sig_fn_t _fns[SIG_COUNT];
static volatile DWORD _tid;
static HANDLE _hvt;
void rsignal_install_handler(int sig, __p_sig_fn_t fn)
{
if (sig < 0 || sig >= SIG_COUNT)
return;
DWORD newtid = GetCurrentThreadId();
DWORD oldtid = InterlockedExchange(&_tid, newtid);
if (oldtid != 0 && oldtid != newtid) {
fprintf(stderr, "\r\nrsignal_install_handler: %u -> %u\r\n", oldtid, newtid);
return;
}
__p_sig_fn_t oldfn = InterlockedExchangePointer((PVOID*)&_fns[sig], fn);
if (fn != 0 && oldfn != 0 && oldfn != fn) {
fprintf(stderr, "\r\nrsignal_install_handler: %p -> %p\r\n", oldfn, fn);
}
}
void rsignal_deinstall_handler(int sig)
{
rsignal_install_handler(sig, 0);
}
void rsignal_raise(int sig)
{
if (sig < 0 || sig >= SIG_COUNT)
return;
__p_sig_fn_t oldfn = InterlockedExchangePointer((PVOID*)&_fns[sig], 0);
if (oldfn == 0)
return;
if (_tid == GetCurrentThreadId()) {
oldfn(sig);
return;
}
HANDLE hthread = OpenThread(THREAD_ALL_ACCESS, FALSE, _tid);
if (!hthread) {
fprintf(stderr, "\r\nrsignal_raise: OpenThread(%u): %d\r\n", _tid, GetLastError());
return;
}
if (SuspendThread(hthread) < 0) {
fprintf(stderr, "\r\nrsignal_raise: SuspendThread(%u): %d\r\n", _tid, GetLastError());
goto cleanup;
}
oldfn(sig);
if (!ResumeThread(hthread)) {
fprintf(stderr, "\r\nrsignal_raise: ResumeThread(%u): %d\r\n", _tid, GetLastError());
// abort because the main thread is stuck
abort();
}
cleanup:
CloseHandle(hthread);
}
static void _rsignal_vt_cb(PVOID param, BOOLEAN timedOut)
{
rsignal_raise(SIGVTALRM);
}
int rsignal_setitimer(int type, struct itimerval *in, struct itimerval *out)
{
if (in == 0) {
errno = EFAULT;
return -1;
}
if (type != ITIMER_VIRTUAL || out != 0) {
errno = ENOTSUP;
return -1;
}
if (_hvt != NULL) {
DeleteTimerQueueTimer(NULL, _hvt, NULL);
_hvt = NULL;
}
if (timerisset(&in->it_value) && !CreateTimerQueueTimer(&_hvt, NULL, _rsignal_vt_cb, NULL,
in->it_value.tv_sec * 1000 + in->it_value.tv_usec / 1000,
in->it_interval.tv_sec * 1000 + in->it_interval.tv_usec / 1000, 0))
{
errno = err_win_to_posix(GetLastError());
return -1;
} else {
return 0;
}
}
// direct import from ntdll.dll
extern DWORD64 __imp_KiUserExceptionDispatcher;
static void _rsignal_longjmp(intptr_t* builtin_jb)
{
__builtin_longjmp(builtin_jb, 1);
}
void rsignal_post_longjmp(DWORD tid, intptr_t* builtin_jb)
{
HANDLE hthread = OpenThread(THREAD_ALL_ACCESS, FALSE, tid);
if (!hthread) {
fprintf(stderr, "\r\nrsignal: OpenThread(%u): %d\r\n", tid, GetLastError());
return;
}
CONTEXT context;
context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
if (!GetThreadContext(hthread, &context)) {
fprintf(stderr, "\r\nrsignal: GetThreadContext(%u): %d\r\n", tid, GetLastError());
goto cleanup;
}
// see if the thread is currently handling a structured exception
// if so, let the handler (usually the libsigsegv handler) finish
// and set up the the signal to run at the exception resume point
// otherwise, passing a parameter to fn is completely unreliable
//
DWORD64 kibase;
PRUNTIME_FUNCTION ki = RtlLookupFunctionEntry(__imp_KiUserExceptionDispatcher, &kibase, NULL);
CONTEXT c = context;
while (1)
{
DWORD64 base, frame;
PRUNTIME_FUNCTION f = RtlLookupFunctionEntry(c.Rip, &base, NULL);
if (!f) break;
if (f == ki)
{
// KiUserExceptionDispatcher has a "bare" frame
// with $rsp pointing to the CONTEXT structure
//
((PCONTEXT)c.Rsp)->Rip = (DWORD64)_rsignal_longjmp;
((PCONTEXT)c.Rsp)->Rcx = (DWORD64)builtin_jb;
goto cleanup;
}
PVOID handler_data;
RtlVirtualUnwind(0, base, c.Rip, f, &c, &handler_data, &frame, NULL);
}
context.Rip = (DWORD64)_rsignal_longjmp;
context.Rcx = (DWORD64)builtin_jb;
if (!SetThreadContext(hthread, &context)) {
fprintf(stderr, "\r\nrsignal: SetThreadContext(%u): %d\r\n", tid, GetLastError());
goto cleanup;
}
cleanup:
CloseHandle(hthread);
}

View File

@ -0,0 +1,24 @@
#ifndef _RSIGNAL_H
#define _RSIGNAL_H
typedef struct {
jmp_buf jb;
unsigned long tid;
} rsignal_jmpbuf;
#define rsignal_setjmp(buf) (buf.tid = GetCurrentThreadId(), setjmp(buf.jb))
#define rsignal_longjmp(buf, val) if (buf.tid != GetCurrentThreadId()) {buf.jb.retval = (val); rsignal_post_longjmp(buf.tid, buf.jb.buffer);} else longjmp(buf.jb, val)
void rsignal_raise(int sig);
void rsignal_install_handler(int sig, __p_sig_fn_t fn);
void rsignal_deinstall_handler(int sig);
void rsignal_post_longjmp(unsigned long tid, intptr_t* builtin_jb);
#define ITIMER_VIRTUAL 1
struct itimerval {
struct timeval it_value, it_interval;
};
int rsignal_setitimer(int type, struct itimerval *in, struct itimerval *out);
#endif//_RSIGNAL_H

View File

@ -0,0 +1,25 @@
#include "all.h"
#include "rsignal.h"
#include "vere/vere.h"
/* _mingw_exception_filter: replaces libsigsegv on MingW
*/
EXCEPTION_DISPOSITION _mingw_exception_filter(
IN PEXCEPTION_RECORD ExceptionRecord,
IN ULONG64 EstablisherFrame,
IN OUT PCONTEXT ContextRecord,
IN OUT PDISPATCHER_CONTEXT DispatcherContext)
{
if (ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION &&
ExceptionRecord->ExceptionInformation[0] == 1 &&
u3e_fault((void*)ExceptionRecord->ExceptionInformation[1], 1))
{
return ExceptionContinueExecution;
}
if (ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW) {
rsignal_raise(SIGSTK);
}
return ExceptionContinueSearch;
}

View File

@ -0,0 +1,65 @@
#include <stdio.h>
#include <string.h>
enum { INIT, CPAR, DQ, DQS, SQ, SQS };
char line[1 << 16];
/* seh_handler_decorator: registers u3_exception_handler for all functions in given source file
*/
int main(int argc, const char* argv[])
{
if (argc != 2)
return 1;
int c, state = INIT, curly = 0, emit = 0;
while (fgets(line, sizeof(line), stdin))
{
if (line[0] == '#')
{
emit = !!strstr(line, argv[1]);
fputs(line, stdout);
}
else
for (int i = 0; line[i]; i++)
{
switch (state) {
case INIT:
case CPAR:
switch (line[i]) {
case ' ':
case '\t':
case '\n':
case '\r':
case '\f': break;
case '{': curly++; if (emit && curly == 1 && state == CPAR) goto emit_handler; goto reset;
case '}': curly--; goto reset;
case '"': state = DQ; break;
case '\'': state = SQ; break;
case ')': state = CPAR; break;
reset:
default: state = INIT; break;
} break;
case DQ:
switch (line[i]) {
case '\\': state = DQS; break;
case '"': state = INIT; break;
} break;
case DQS: state = DQ; break;
case SQ:
switch (line[i]) {
case '\\': state = SQS; break;
case '\'': state = INIT; break;
} break;
case SQS: state = SQ; break;
}
fputc(line[i], stdout);
continue;
emit_handler:
fputs("{__asm__(\".seh_handler _mingw_exception_filter,@except\\n\");", stdout);
state = INIT;
}
}
return 0;
}

View File

@ -0,0 +1,24 @@
# This include file injects a step that transforms vere C source to register
# a SEH exception handler for each function that is declared in a .c file.
# It inserts a .seh_handler directive into each function body with __asm__.
# This directive affects the x64 unwind tables (.pdata and .xdata sections)
# emitted by the compiler.
#
# See gas/config/obj-coff-seh.h in binutils source for .seh_handler, and
# https://docs.microsoft.com/en-us/cpp/build/exception-handling-x64
# for a description of how stack unwinding and SEH work in x64 Windows.
#
# When this file sets CCEXTRA, the first invocation of $(CC) in Makefile
# writes preprocessor output to stdout (-E -o -), which is piped to a simple
# parser that inserts __asm__ statements to each function in the .c file
# being compiled. The second invocation of $(CC) reads transformed source
# from stdin (-x cpp-output -). $< argument to $(sehdexe) tells the parser
# which .c file is being compiled.
sehdexe := build/seh_handler_decorator.exe
CCDEPS := $(CCDEPS) $(sehdexe)
CCEXTRA = -E -o -|$(sehdexe) $<|$(CC) $(CFLAGS) -x cpp-output -
$(sehdexe): compat/mingw/seh_handler_decorator.cc
@mkdir -p ./build
@$(CC) $< -o $@

View File

@ -0,0 +1,15 @@
#ifndef _MINGW_SETJMP_H
#define _MINGW_SETJMP_H
// msvcrt setjmp/longjmp are broken on 64-bit systems, use gcc builtins
typedef struct jmp_buf {
intptr_t buffer[5];
int retval;
} jmp_buf;
#define _setjmp setjmp
#define _longjmp longjmp
#define longjmp(buf, val) {buf.retval = (val); __builtin_longjmp(buf.buffer, 1);}
#define setjmp(buf) (__builtin_setjmp(buf.buffer) ? (buf.retval) : 0)
#endif//_MINGW_SETJMP_H

View File

@ -0,0 +1,36 @@
diff --git a/build/Win64-MinGW-w64/Makefile b/build/Win64-MinGW-w64/Makefile
--- a/build/Win64-MinGW-w64/Makefile
+++ b/build/Win64-MinGW-w64/Makefile
@@ -46,7 +46,8 @@ C_INCLUDES = -I. -I$(SOURCE_DIR)/$(SPECIALIZE_TYPE) -I$(SOURCE_DIR)/include
COMPILE_C = \
x86_64-w64-mingw32-gcc -c -Werror-implicit-function-declaration \
-DSOFTFLOAT_FAST_INT64 $(SOFTFLOAT_OPTS) $(C_INCLUDES) -O2 -o $@
-MAKELIB = x86_64-w64-mingw32-ar crs $@
+MAKELIB = x86_64-w64-mingw32-gcc-ar crs $@
+LIBNAME = libsoftfloat3
OBJ = .o
LIB = .a
@@ -54,7 +55,7 @@ LIB = .a
OTHER_HEADERS = $(SOURCE_DIR)/include/opts-GCC.h
.PHONY: all
-all: softfloat$(LIB)
+all: $(LIBNAME)$(LIB)
OBJS_PRIMITIVES = \
s_eq128$(OBJ) \
@@ -380,11 +381,11 @@ $(OBJS_PRIMITIVES) $(OBJS_OTHERS): %$(OBJ): $(SOURCE_DIR)/%.c
$(OBJS_SPECIALIZE): %$(OBJ): $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/%.c
$(COMPILE_C) $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/$*.c
-softfloat$(LIB): $(OBJS_ALL)
+$(LIBNAME)$(LIB): $(OBJS_ALL)
$(DELETE) $@
$(MAKELIB) $^
.PHONY: clean
clean:
- $(DELETE) $(OBJS_ALL) softfloat$(LIB)
+ $(DELETE) $(OBJS_ALL) $(LIBNAME)$(LIB)

View File

@ -0,0 +1,30 @@
diff --git a/src/win/pipe.c b/src/win/pipe.c
index 0f2bb869b..f81245ec6 100644
--- a/src/win/pipe.c
+++ b/src/win/pipe.c
@@ -270,6 +270,12 @@ static int uv_set_pipe_handle(uv_loop_t* loop,
if (!SetNamedPipeHandleState(pipeHandle, &mode, NULL, NULL)) {
err = GetLastError();
+ if ((err == ERROR_INVALID_FUNCTION || err == ERROR_INVALID_PARAMETER) && (duplex_flags & UV_HANDLE_WRITABLE)) {
+ /*
+ * it's not a pipe, but simple writes should be fine
+ * let's trust callers to know what they're doing
+ */
+ } else
if (err == ERROR_ACCESS_DENIED) {
/*
* SetNamedPipeHandleState can fail if the handle doesn't have either
diff --git a/src/win/tty.c b/src/win/tty.c
index c359d5601..1b9d4f853 100644
--- a/src/win/tty.c
+++ b/src/win/tty.c
@@ -367,7 +367,7 @@ int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
flags = ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
break;
case UV_TTY_MODE_RAW:
- flags = ENABLE_WINDOW_INPUT;
+ flags = ENABLE_WINDOW_INPUT | ENABLE_PROCESSED_INPUT;
break;
case UV_TTY_MODE_IO:
return UV_ENOTSUP;

View File

@ -0,0 +1,148 @@
declare -a cdirs
declare -a ldirs
declare -A hdeps
sources=(../../nix/sources.json ../../nix/sources-pmnsh.json)
patches=compat/$1
deriver=urbit-$1-build
markfil=.$1~
depdirs=
nixpath=${NIX_STORE-../build}
# LDFLAGS doesn't like absolute paths
if [ "${nixpath:0:1}" == "/" ]
then
mkdir -p $nixpath
nixpath=$(realpath --relative-to=. $nixpath)
fi
hex2nixbase32 () {
local digits='0123456789abcdfghijklmnpqrsvwxyz'
local bits=0
local left=0 # number of bits left in $bits
local i=0
while ((1))
do
while ((left>=5))
do
echo -n ${digits:$((bits&31)):1}
bits=$((bits>>5))
left=$((left-5))
done
if ((i == ${#1}))
then
break
fi
char=0x${1:i:2}
i=$((i+2))
bits=$((bits|(char<<(left))))
left=$((left+8))
done
echo -n ${digits:$bits:1}
}
buildnixdep () {
echo Building dependency $key...
local cache=https://app.cachix.org/api/v1/cache/${CACHIX_CACHE-}
local hash=
if [ -n "$url" ]
then
hash=${hdeps[$key]}
dir=$nixpath/$hash-$key
if [ -e $dir/$markfil ]
then
# dependency present, don't reupload
hash=
else
# dependency absent, check the binary cache if configured
if [ -n "${CACHIX_CACHE-}" ]
then
echo Checking binary cache for $hash-$key...
narinfo="$cache/${hash}.narinfo"
if curl -fLI "$narinfo"
then
url="$cache/$(curl -fL -H "Accept: application/json" "$narinfo"|jq -r '.url')"
echo Found $url
strip=0
hash=
fi
fi
mkdir -p $dir
pushd $dir
curl -fL "$url"|(tar --strip $strip -xzf - || true)
popd
fi
else
# local dependency
dir=../$key
fi
# patch and build the dependency if necessary
if [ ! -e $dir/$markfil ]
then
local patch=$patches/$key.patch
[ -e $patch ] && patch -d $dir -p 1 <$patch
pushd $dir
eval "$cmdprep"
eval make "$cmdmake"
touch $markfil
popd
fi
# if configured, upload freshly built dependency to binary cache
if [ -n "$hash" -a -n "${CACHIX_AUTH_TOKEN-}" ]
then
(
echo Uploading freshly built $hash-$key to binary cache...
tar -C $dir -czf $hash.tar .
local size=$(stat -c '%s' $hash.tar)
read filehash _ < <(sha256sum $hash.tar)
curl -fL -H "Content-Type: application/gzip" -H "Authorization: Bearer $CACHIX_AUTH_TOKEN" --data-binary @"$hash.tar" "$cache/nar"
curl -fL -H "Content-Type: application/json" -H "Authorization: Bearer $CACHIX_AUTH_TOKEN" --data-binary @- "$cache/${hash}.narinfo" <<EOF
{
"cStoreHash": "$hash",
"cStoreSuffix": "$key",
"cNarHash": "sha256:$(hex2nixbase32 $filehash)",
"cNarSize": $size,
"cFileHash": "$filehash",
"cFileSize": $size,
"cReferences": [],
"cDeriver": "$deriver"
}
EOF
echo Done. ) || true
rm $hash.tar || true
fi
}
# I have to go over the sources files several times
# because jq does not have a way to invoke external programs
jqprep='add|to_entries|.[]|.value.pmnsh as $p|select($p and $p.compat.'$1' != false)|(($p + $p.compat.'$1')|del(.compat)) as $o|'
# list external dependencies, create hash map and directory replacement regex
# use -j and \u0000 to work around https://github.com/stedolan/jq/issues/1870
while read -rd "" key json
do
# create 'store hash' from sources.json data and patch
patch=$patches/$key.patch
read hash _ < <((
echo -n $json
[ -e $patch ] && cat $patch)|sha256sum)
hash=$(hex2nixbase32 $hash)
hdeps[$key]=$hash
depdirs="$depdirs|gsub(\"\\\\.\\\\./$key\";\"\\(\$d)/$hash-$key\")"
done < <(jq --arg deriver "$deriver" -Sscrj "$jqprep"'select(.value.url)|.key," ",{($deriver):(.value|del(.pmnsh) + ({'$1':$o}))},"\u0000"' ${sources[@]})
# build dependencies, create include and library directory arrays
. <(jq --arg nixpath "$nixpath" -sr "$jqprep"'(if .value.url then ".." else $nixpath end) as $d|"
unset dir
key=\(.key|@sh) \\
url=\(.value.url//""|@sh) \\
strip=\($o.strip+1) \\
cmdprep=\($o.prepare//""'"$depdirs"'|@sh) \\
cmdmake=\($o.make//""'"$depdirs"'|@sh) \\
buildnixdep # sets dir
\($o.include//"."|if type == "array" then . else [.] end|map("cdirs+=(-I$dir/\(.))")|join("\n"))
\($o.lib//"."|if type == "array" then . else [.] end|map("ldirs+=(-L$dir/\(.))")|join("\n"))"' ${sources[@]})
CFLAGS="${CFLAGS-} ${cdirs[@]}"
LDFLAGS="${LDFLAGS-} ${ldirs[@]}"

View File

@ -0,0 +1,91 @@
#include "all.h"
#include "vere/vere.h"
#include <sys/wait.h>
/*
This is set to the the write-end of a pipe when Urbit is started in
daemon mode. It's meant to be used as a signal to the parent process
that the child process has finished booting.
*/
static c3_i _child_process_booted_signal_fd = -1;
/*
This should be called whenever the ship has been booted enough to
handle commands from automation code. Specifically, once the Eyre's
`chis` interface is up and running.
In daemon mode, this signals to the parent process that it can
exit. Otherwise, it does nothing.
Once we've sent a signal with `write`, we close the file descriptor
and overwrite the global to make it impossible to accidentally do
this twice.
*/
static void _on_boot_completed_cb() {
c3_c buf[2] = {0,0};
if ( -1 == _child_process_booted_signal_fd ) {
return;
}
if ( 0 == write(_child_process_booted_signal_fd, buf, 1) ) {
c3_assert(!"_on_boot_completed_cb: Can't write to parent FD");
}
close(_child_process_booted_signal_fd);
_child_process_booted_signal_fd = -1;
}
/* u3_daemon_init(): platform-specific daemon mode initialization.
We use a pipe to communicate between the child and the parent. The
parent waits for the child to write something to the pipe and
then exits. If the pipe is closed with nothing written to it, get
the exit status from the child process and also exit with that status.
We want the child to write to the pipe once it's booted, so we put
`_on_boot_completed_cb` into `u3_Host.bot_f`, which is NULL in
non-daemon mode. That gets called once the `chis` service is
available.
In both processes, we are good fork() citizens, and close all unused
file descriptors. Closing `pipefd[1]` in the parent process is
especially important, since the pipe needs to be closed if the child
process dies. When the pipe is closed, the read fails, and that's
how we know that something went wrong.
There are some edge cases around `WEXITSTATUS` that are not handled
here, but I don't think it matters.
*/
void
u3_daemon_init()
{
c3_i pipefd[2];
if ( 0 != pipe(pipefd) ) {
c3_assert(!"Failed to create pipe");
}
pid_t childpid = fork();
if ( 0 == childpid ) {
close(pipefd[0]);
_child_process_booted_signal_fd = pipefd[1];
u3_Host.bot_f = _on_boot_completed_cb;
return;
}
close(pipefd[1]);
close(0);
close(1);
close(2);
c3_c buf[2] = {0,0};
if ( 1 == read(pipefd[0], buf, 1) ) {
exit(0);
}
c3_i status;
wait(&status);
exit(WEXITSTATUS(status));
}

View File

@ -0,0 +1,189 @@
/* compat/posix/ptty.c
**
*/
#include "all.h"
#include "vere/vere.h"
#include <sys/ioctl.h>
#include <termios.h>
/* u3_ptty: POSIX terminal extension to u3_utty.
*/
typedef struct {
u3_utty tty_u; // common tty structure
c3_i cug_i; // blocking fcntl flags
c3_i nob_i; // nonblocking fcntl flags
struct termios bak_u; // cooked terminal state
struct termios raw_u; // raw terminal state
} u3_ptty;
/* _term_tcsetattr(): tcsetattr w/retry on EINTR.
*/
static c3_i
_term_tcsetattr(c3_i fil_i, c3_i act_i, const struct termios* tms_u)
{
c3_i ret_i = 0;
c3_w len_w = 0;
do {
// abort pathological retry loop
//
if ( 100 == ++len_w ) {
fprintf(stderr, "term: tcsetattr loop: %s\r\n", strerror(errno));
return -1;
}
ret_i = tcsetattr(fil_i, act_i, tms_u);
} while ( (-1 == ret_i) && (EINTR == errno) );
return ret_i;
}
/* _ttyf_start_raw_input(): sets the tty to raw input.
*/
static c3_o
_ttyf_start_raw_input(u3_utty* uty_u)
{
u3_ptty* pty_u = (u3_ptty*)uty_u;
if ( 0 != _term_tcsetattr(uty_u->fid_i, TCSADRAIN, &pty_u->raw_u) ) {
return c3n;
}
if ( -1 == fcntl(uty_u->fid_i, F_SETFL, pty_u->nob_i) ) {
c3_assert(!"init-fcntl");
}
return c3y;
}
/* _ttyf_start_raw_input(): ends raw input on the tty.
*/
static c3_o
_ttyf_end_raw_input(u3_utty* uty_u)
{
u3_ptty* pty_u = (u3_ptty*)uty_u;
if ( 0 != _term_tcsetattr(uty_u->fid_i, TCSADRAIN, &pty_u->bak_u) ) {
return c3n;
}
if ( -1 == fcntl(uty_u->fid_i, F_SETFL, pty_u->cug_i) ) {
c3_assert(!"exit-fcntl");
}
return c3y;
}
/* _ttyf_hija(): hijacks the tty for cooked output.
*/
static c3_o
_ttyf_hija(u3_utty* uty_u)
{
u3_ptty* pty_u = (u3_ptty*)uty_u;
if ( 0 != _term_tcsetattr(1, TCSADRAIN, &pty_u->bak_u) ) {
perror("hija-tcsetattr-1");
c3_assert(!"hija-tcsetattr");
}
if ( -1 == fcntl(1, F_SETFL, pty_u->cug_i) ) {
perror("hija-fcntl-1");
c3_assert(!"hija-fcntl");
}
if ( 0 != _term_tcsetattr(0, TCSADRAIN, &pty_u->bak_u) ) {
perror("hija-tcsetattr-0");
c3_assert(!"hija-tcsetattr");
}
if ( -1 == fcntl(0, F_SETFL, pty_u->cug_i) ) {
perror("hija-fcntl-0");
c3_assert(!"hija-fcntl");
}
return c3y;
}
/* _ttyf_loja(): releases the tty from cooked output.
*/
static c3_o
_ttyf_loja(u3_utty* uty_u)
{
u3_ptty* pty_u = (u3_ptty*)uty_u;
if ( 0 != _term_tcsetattr(1, TCSADRAIN, &pty_u->raw_u) ) {
perror("loja-tcsetattr-1");
c3_assert(!"loja-tcsetattr");
}
if ( -1 == fcntl(1, F_SETFL, pty_u->nob_i) ) {
perror("hija-fcntl-1");
c3_assert(!"loja-fcntl");
}
if ( 0 != _term_tcsetattr(0, TCSADRAIN, &pty_u->raw_u) ) {
perror("loja-tcsetattr-0");
c3_assert(!"loja-tcsetattr");
}
if ( -1 == fcntl(0, F_SETFL, pty_u->nob_i) ) {
perror("hija-fcntl-0");
c3_assert(!"loja-fcntl");
}
return c3y;
}
/* _ttyf_get_winsize(): gets the tty window size.
*/
static c3_o
_ttyf_get_winsize(u3_utty* uty_u, c3_l* col_l, c3_l* row_l)
{
struct winsize siz_u;
if ( 0 == ioctl(uty_u->fid_i, TIOCGWINSZ, &siz_u) )
{
*col_l = siz_u.ws_col;
*row_l = siz_u.ws_row;
return c3y;
} else {
return c3n;
}
}
/* u3_ptty_init(): initialize platform-specific tty.
*/
u3_utty*
u3_ptty_init(uv_loop_t* lup_u, const c3_c** err_c)
{
u3_ptty* pty_u = c3_calloc(sizeof(u3_ptty));
u3_utty* uty_u = &pty_u->tty_u;
if ( !isatty(0) || !isatty(1) ) {
*err_c = "not a tty";
c3_free(pty_u);
return NULL;
}
uv_pipe_init(lup_u, &uty_u->pin_u.pop_u, 0);
uv_pipe_init(lup_u, &uty_u->pop_u.pop_u, 0);
uv_pipe_open(&uty_u->pin_u.pop_u, 0);
uv_pipe_open(&uty_u->pop_u.pop_u, 1);
// Load old terminal state to restore.
//
{
if ( 0 != tcgetattr(uty_u->fid_i, &pty_u->bak_u) ) {
c3_assert(!"init-tcgetattr");
}
if ( -1 == fcntl(uty_u->fid_i, F_GETFL, &pty_u->cug_i) ) {
c3_assert(!"init-fcntl");
}
pty_u->cug_i &= ~O_NONBLOCK; // could fix?
pty_u->nob_i = pty_u->cug_i | O_NONBLOCK; // O_NDELAY on older unix
}
// Construct raw termios configuration.
//
{
pty_u->raw_u = pty_u->bak_u;
pty_u->raw_u.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN);
pty_u->raw_u.c_iflag &= ~(ICRNL | INPCK | ISTRIP);
pty_u->raw_u.c_cflag &= ~(CSIZE | PARENB);
pty_u->raw_u.c_cflag |= CS8;
pty_u->raw_u.c_oflag &= ~(OPOST);
pty_u->raw_u.c_cc[VMIN] = 0;
pty_u->raw_u.c_cc[VTIME] = 0;
}
uty_u->fid_i = 1;
uty_u->sta_f = _ttyf_start_raw_input;
uty_u->sto_f = _ttyf_end_raw_input;
uty_u->hij_f = _ttyf_hija;
uty_u->loj_f = _ttyf_loja;
uty_u->wsz_f = _ttyf_get_winsize;
return uty_u;
}

View File

@ -0,0 +1,11 @@
#ifndef _RSIGNAL_H
#define _RSIGNAL_H
#define rsignal_jmpbuf sigjmp_buf
#define rsignal_setjmp(buf) sigsetjmp((buf), 1)
#define rsignal_longjmp siglongjmp
#define rsignal_install_handler signal
#define rsignal_deinstall_handler(sig) signal((sig), SIG_IGN)
#define rsignal_setitimer setitimer
#endif//_RSIGNAL_H

84
pkg/urbit/configure vendored
View File

@ -1,12 +1,12 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -euo pipefail
URBIT_VERSION="$(cat ./version)" URBIT_VERSION="$(cat ./version)"
deps=" \ deps=" \
curl gmp sigsegv argon2 ed25519 ent h2o scrypt uv murmur3 secp256k1 \ curl gmp sigsegv argon2 ed25519 ent h2o scrypt uv murmur3 secp256k1 \
softfloat3 ssl crypto z lmdb ge-additions aes_siv pthread \ softfloat3 aes_siv ssl crypto z lmdb ge-additions pthread \
" "
headers=" \ headers=" \
@ -21,10 +21,28 @@ defmacro () {
defmacro URBIT_VERSION "\"$URBIT_VERSION\"" defmacro URBIT_VERSION "\"$URBIT_VERSION\""
[ -n "$MEMORY_DEBUG" ] && defmacro U3_MEMORY_DEBUG 1 opt_debug=
[ -n "$MEMORY_LOG" ] && defmacro U3_MEMORY_LOG 1
[ -n "$CPU_DEBUG" ] && defmacro U3_CPU_DEBUG 1 while test $# != 0
[ -n "$EVENT_TIME_DEBUG" ] && defmacro U3_EVENT_TIME_DEBUG 1 do
case $1 in
--enable-debug)
opt_debug=1
;;
--disable-debug)
opt_debug=
;;
*)
echo "unrecognized option: $1"
;;
esac
shift
done
[ -n "${MEMORY_DEBUG-}" ] && defmacro U3_MEMORY_DEBUG 1
[ -n "${MEMORY_LOG-}" ] && defmacro U3_MEMORY_LOG 1
[ -n "${CPU_DEBUG-}" ] && defmacro U3_CPU_DEBUG 1
[ -n "${EVENT_TIME_DEBUG-}" ] && defmacro U3_EVENT_TIME_DEBUG 1
if [ -n "${HOST-}" ] if [ -n "${HOST-}" ]
then os=$(sed 's$^[^-]*-\([^-]*\)-.*$\1$' <<< "$HOST") then os=$(sed 's$^[^-]*-\([^-]*\)-.*$\1$' <<< "$HOST")
@ -58,14 +76,53 @@ esac
# TODO Determine if the target cpu is little or big endian. # TODO Determine if the target cpu is little or big endian.
case $(tr A-Z a-z <<< $os) in case $(tr A-Z a-z <<< $os) in
*mingw*)
# ensure required mingw packages are installed
mpkgs=(cmake curl gcc jq make)
pacman -S --needed autoconf automake-wrapper libtool patch ${mpkgs[@]/#/mingw-w64-x86_64-}
. compat/poor-mans-nix-shell.sh mingw
compat/create-include-files.sh 'stat -c %s' /etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt
defmacro U3_OS_mingw 1
deps="${deps/sigsegv}"
compat="${compat-} mingw"
PKG_CONFIG=false
;;
m1brew)
# ensure required packages are installed
brew install -q autoconf automake bash cmake coreutils gmp jq libsigsegv libtool libuv openssl pkgconfig
if (( ${BASH_VERSION%%.*} < 5 ))
then
echo Running bash version $BASH_VERSION is too low, please restart bash to use freshly installed one
exit 1
fi
# for some reason pkg-config does not pick up openssl
export PKG_CONFIG_PATH="$(brew --prefix openssl)/lib/pkgconfig:${PKG_CONFIG_PATH-}"
. compat/poor-mans-nix-shell.sh m1brew
compat/create-include-files.sh 'stat -f %z' /etc/ssl/cert.pem
defmacro U3_OS_osx 1
deps="${deps/ssl/openssl}"
deps="${deps/uv/libuv}"
compat="${compat-} posix m1brew"
;;
*linux*) *linux*)
defmacro U3_OS_linux 1 defmacro U3_OS_linux 1
defmacro U3_OS_PROF 1
;; ;;
*darwin*) *darwin*)
defmacro U3_OS_osx 1 defmacro U3_OS_osx 1
defmacro U3_OS_PROF 1
;; ;;
*apple*) *apple*)
defmacro U3_OS_osx 1 defmacro U3_OS_osx 1
defmacro U3_OS_PROF 1
;; ;;
*freebsd*) *freebsd*)
defmacro U3_OS_bsd 1 defmacro U3_OS_bsd 1
@ -81,18 +138,27 @@ case $(tr A-Z a-z <<< $os) in
esac esac
for dep in ${osdeps-} $deps for dep in ${osdeps-} $deps
do LDFLAGS="${LDFLAGS-} -l$dep" do
${PKG_CONFIG-pkg-config} --cflags --libs $dep 2>/dev/null || true LDFLAGS="${LDFLAGS-} $(${PKG_CONFIG-pkg-config} --libs $dep 2>/dev/null || echo -l$dep)"
CFLAGS="${CFLAGS-} $(${PKG_CONFIG-pkg-config} --cflags $dep 2>/dev/null || true)"
done done
for header in $headers for header in $headers
do LDFLAGS="${LDFLAGS-} -I$header" do LDFLAGS="${LDFLAGS-} -I$header"
done done
compat="${compat-posix}"
for citem in $compat
do
CFLAGS="${CFLAGS-} -Icompat/$citem"
done
cat >config.mk <<EOF cat >config.mk <<EOF
CFLAGS := ${CFLAGS-} -funsigned-char -ffast-math -std=gnu99 CFLAGS := $CFLAGS -funsigned-char -ffast-math -fcommon -std=gnu99
LDFLAGS := $LDFLAGS LDFLAGS := $LDFLAGS
CC := ${CC-cc} CC := ${CC-cc}
compat := $compat
debug := $opt_debug
EOF EOF
echo == config.mk == >&2 echo == config.mk == >&2

View File

@ -1,16 +1,13 @@
/* vere/main.c /* vere/main.c
** **
*/ */
#include <fcntl.h> #define U3_GLOBAL
#include <sys/ioctl.h> #define C3_GLOBAL
#include <sys/stat.h> #include "all.h"
#include <sys/wait.h> #include "vere/vere.h"
#include <limits.h> #if !defined(U3_OS_mingw)
#include <uv.h>
#include <sigsegv.h> #include <sigsegv.h>
#include <stdlib.h> #endif
#include <termios.h>
#include <dirent.h>
#include <openssl/conf.h> #include <openssl/conf.h>
#include <openssl/engine.h> #include <openssl/engine.h>
#include <openssl/err.h> #include <openssl/err.h>
@ -18,13 +15,6 @@
#include <h2o.h> #include <h2o.h>
#include <curl/curl.h> #include <curl/curl.h>
#include <argon2.h> #include <argon2.h>
#include <lmdb.h>
#define U3_GLOBAL
#define C3_GLOBAL
#include "all.h"
#include "vere/vere.h"
#include <vere/db/lmdb.h> #include <vere/db/lmdb.h>
#include "ca-bundle.h" #include "ca-bundle.h"
@ -222,9 +212,9 @@ _main_getopt(c3_i argc, c3_c** argv)
} }
} }
#if defined(U3_OS_bsd) #if !defined(U3_OS_PROF)
if (u3_Host.ops_u.pro == c3y) { if (u3_Host.ops_u.pro == c3y) {
fprintf(stderr, "profiling isn't yet supported on BSD\r\n"); fprintf(stderr, "profiling isn't yet supported on your OS\r\n");
return c3n; return c3n;
} }
#endif #endif
@ -307,7 +297,7 @@ _main_getopt(c3_i argc, c3_c** argv)
} }
struct sockaddr_in t; struct sockaddr_in t;
if ( u3_Host.ops_u.bin_c != 0 && inet_aton(u3_Host.ops_u.bin_c, &t.sin_addr) == 0 ) { if ( u3_Host.ops_u.bin_c != 0 && inet_pton(AF_INET, u3_Host.ops_u.bin_c, &t.sin_addr) == 0 ) {
fprintf(stderr, "-b invalid IP address\n"); fprintf(stderr, "-b invalid IP address\n");
return c3n; return c3n;
} }
@ -373,26 +363,64 @@ _main_getopt(c3_i argc, c3_c** argv)
return c3y; return c3y;
} }
/* _setup_cert_store: writes our embedded certificate database to a temp file /* _cert_store: decoded CA certificates
*/
static STACK_OF(X509_INFO)* _cert_store;
/* _setup_cert_store(): decodes embedded CA certificates
*/ */
static void static void
_setup_cert_store(char* tmp_cert_file_name) _setup_cert_store()
{ {
errno = 0; BIO* cbio = BIO_new_mem_buf(include_ca_bundle_crt, include_ca_bundle_crt_len);
int fd = mkstemp(tmp_cert_file_name); if ( !cbio || !(_cert_store = PEM_X509_INFO_read_bio(cbio, NULL, NULL, NULL)) ) {
if (fd < 1) { u3l_log("boot: failed to decode embedded CA certificates\r\n");
printf("boot: failed to write local ssl temporary certificate store: %s\n",
strerror(errno));
exit(1); exit(1);
} }
if (-1 == write(fd, include_ca_bundle_crt, include_ca_bundle_crt_len)) { BIO_free(cbio);
printf("boot: failed to write local ssl temporary certificate store: %s\n",
strerror(errno));
exit(1);
} }
setenv("SSL_CERT_FILE", tmp_cert_file_name, 1); /* _setup_ssl_x509(): adds embedded CA certificates to a X509_STORE
*/
static void
_setup_ssl_x509(void* arg)
{
X509_STORE* cts = arg;
int i;
for ( i = 0; i < sk_X509_INFO_num(_cert_store); i++ ) {
X509_INFO *itmp = sk_X509_INFO_value(_cert_store, i);
if(itmp->x509) {
X509_STORE_add_cert(cts, itmp->x509);
}
if(itmp->crl) {
X509_STORE_add_crl(cts, itmp->crl);
}
}
}
/* _curl_ssl_ctx_cb(): curl SSL context callback
*/
static CURLcode
_curl_ssl_ctx_cb(CURL* curl, SSL_CTX* sslctx, void* param)
{
X509_STORE* cts = SSL_CTX_get_cert_store(sslctx);
if (!cts || !_cert_store)
return CURLE_ABORTED_BY_CALLBACK;
_setup_ssl_x509(cts);
return CURLE_OK;
}
/* _setup_ssl_curl(): adds embedded CA certificates to a curl context
*/
static void
_setup_ssl_curl(void* arg)
{
CURL* curl = arg;
curl_easy_setopt(curl, CURLOPT_CAINFO, NULL);
curl_easy_setopt(curl, CURLOPT_CAPATH, NULL);
curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, _curl_ssl_ctx_cb);
} }
@ -486,9 +514,11 @@ report(void)
{ {
printf("urbit %s\n", URBIT_VERSION); printf("urbit %s\n", URBIT_VERSION);
printf("gmp: %s\n", gmp_version); printf("gmp: %s\n", gmp_version);
#if !defined(U3_OS_mingw)
printf("sigsegv: %d.%d\n", printf("sigsegv: %d.%d\n",
(libsigsegv_version >> 8) & 0xff, (libsigsegv_version >> 8) & 0xff,
libsigsegv_version & 0xff); libsigsegv_version & 0xff);
#endif
printf("openssl: %s\n", SSLeay_version(SSLEAY_VERSION)); printf("openssl: %s\n", SSLeay_version(SSLEAY_VERSION));
printf("libuv: %s\n", uv_version_string()); printf("libuv: %s\n", uv_version_string());
printf("libh2o: %d.%d.%d\n", printf("libh2o: %d.%d.%d\n",
@ -517,96 +547,6 @@ _stop_exit(c3_i int_i)
u3_king_bail(); u3_king_bail();
} }
/*
This is set to the the write-end of a pipe when Urbit is started in
daemon mode. It's meant to be used as a signal to the parent process
that the child process has finished booting.
*/
static c3_i _child_process_booted_signal_fd = -1;
/*
This should be called whenever the ship has been booted enough to
handle commands from automation code. Specifically, once the Eyre's
`chis` interface is up and running.
In daemon mode, this signals to the parent process that it can
exit. Otherwise, it does nothing.
Once we've sent a signal with `write`, we close the file descriptor
and overwrite the global to make it impossible to accidentally do
this twice.
*/
static void _on_boot_completed_cb() {
c3_c buf[2] = {0,0};
if ( -1 == _child_process_booted_signal_fd ) {
return;
}
if ( 0 == write(_child_process_booted_signal_fd, buf, 1) ) {
c3_assert(!"_on_boot_completed_cb: Can't write to parent FD");
}
close(_child_process_booted_signal_fd);
_child_process_booted_signal_fd = -1;
}
/*
In daemon mode, run the urbit as a background process, but don't
exit from the parent process until the ship is finished booting.
We use a pipe to communicate between the child and the parent. The
parent waits for the child to write something to the pipe and
then exits. If the pipe is closed with nothing written to it, get
the exit status from the child process and also exit with that status.
We want the child to write to the pipe once it's booted, so we put
`_on_boot_completed_cb` into `u3_Host.bot_f`, which is NULL in
non-daemon mode. That gets called once the `chis` service is
available.
In both processes, we are good fork() citizens, and close all unused
file descriptors. Closing `pipefd[1]` in the parent process is
especially important, since the pipe needs to be closed if the child
process dies. When the pipe is closed, the read fails, and that's
how we know that something went wrong.
There are some edge cases around `WEXITSTATUS` that are not handled
here, but I don't think it matters.
*/
static void
_fork_into_background_process()
{
c3_i pipefd[2];
if ( 0 != pipe(pipefd) ) {
c3_assert(!"Failed to create pipe");
}
pid_t childpid = fork();
if ( 0 == childpid ) {
close(pipefd[0]);
_child_process_booted_signal_fd = pipefd[1];
u3_Host.bot_f = _on_boot_completed_cb;
return;
}
close(pipefd[1]);
close(0);
close(1);
close(2);
c3_c buf[2] = {0,0};
if ( 1 == read(pipefd[0], buf, 1) ) {
exit(0);
}
c3_i status;
wait(&status);
exit(WEXITSTATUS(status));
}
/* _stop_on_boot_completed_cb(): exit gracefully after boot is complete /* _stop_on_boot_completed_cb(): exit gracefully after boot is complete
*/ */
static void static void
@ -659,12 +599,24 @@ main(c3_i argc,
} }
// Set `u3_Host.wrk_c` to the worker executable path. // Set `u3_Host.wrk_c` to the worker executable path.
c3_i worker_exe_len = 1 + strlen(argv[0]) + strlen("-worker"); c3_i urbit_exe_len = strlen(argv[0]);
c3_i worker_exe_len = 1 + urbit_exe_len + strlen("-worker");
u3_Host.wrk_c = c3_malloc(worker_exe_len); u3_Host.wrk_c = c3_malloc(worker_exe_len);
#if defined(U3_OS_mingw)
if ( urbit_exe_len >= 4 && !strcmp(argv[0] + urbit_exe_len - 4, ".exe")) {
snprintf(u3_Host.wrk_c, worker_exe_len, "%.*s-worker.exe", urbit_exe_len - 4, argv[0]);
} else {
snprintf(u3_Host.wrk_c, worker_exe_len, "%s-worker", argv[0]); snprintf(u3_Host.wrk_c, worker_exe_len, "%s-worker", argv[0]);
}
#else
snprintf(u3_Host.wrk_c, worker_exe_len, "%s-worker", argv[0]);
#endif
if ( c3y == u3_Host.ops_u.dem ) { if ( c3y == u3_Host.ops_u.dem ) {
_fork_into_background_process(); // In daemon mode, run the urbit as a background process, but don't
// exit from the parent process until the ship is finished booting.
//
u3_daemon_init();
} }
if ( c3y == u3_Host.ops_u.rep ) { if ( c3y == u3_Host.ops_u.rep ) {
@ -688,6 +640,7 @@ main(c3_i argc,
// //
// XX review, may be unnecessary due to similar in u3m_init() // XX review, may be unnecessary due to similar in u3m_init()
// //
#if defined(U3_OS_PROF)
if ( _(u3_Host.ops_u.pro) ) { if ( _(u3_Host.ops_u.pro) ) {
sigset_t set; sigset_t set;
@ -698,12 +651,15 @@ main(c3_i argc,
exit(1); exit(1);
} }
} }
#endif
#if !defined(U3_OS_mingw)
// Handle SIGTSTP as if it was SIGTERM. // Handle SIGTSTP as if it was SIGTERM.
// //
// Configured here using signal() so as to be immediately available. // Configured here using signal() so as to be immediately available.
// //
signal(SIGTSTP, _stop_exit); signal(SIGTSTP, _stop_exit);
#endif
printf("~\n"); printf("~\n");
// printf("welcome.\n"); // printf("welcome.\n");
@ -735,9 +691,6 @@ main(c3_i argc,
} }
// printf("vere: hostname is %s\n", u3_Host.ops_u.nam_c); // printf("vere: hostname is %s\n", u3_Host.ops_u.nam_c);
u3K.certs_c = strdup("/tmp/urbit-ca-cert-XXXXXX");
_setup_cert_store(u3K.certs_c);
if ( c3y == u3_Host.ops_u.dem ) { if ( c3y == u3_Host.ops_u.dem ) {
printf("boot: running as daemon\n"); printf("boot: running as daemon\n");
} }
@ -804,6 +757,18 @@ main(c3_i argc,
} }
} }
#if defined(U3_OS_mingw)
// Initialize event used to transmit Ctrl-C to worker process
//
{
SECURITY_ATTRIBUTES sa = {sizeof(sa), NULL, TRUE};
if ( NULL == (u3_Host.cev_u = CreateEvent(&sa, FALSE, FALSE, NULL)) ) {
u3l_log("boot: failed to create Ctrl-C event: %d\r\n", GetLastError());
exit(1);
}
}
#endif
// Initialize OpenSSL for client and server // Initialize OpenSSL for client and server
// //
{ {
@ -818,6 +783,10 @@ main(c3_i argc,
exit(1); exit(1);
} }
_setup_cert_store();
u3K.ssl_curl_f = _setup_ssl_curl;
u3K.ssl_x509_f = _setup_ssl_x509;
u3_king_commence(); u3_king_commence();
// uninitialize curl // uninitialize curl

View File

@ -72,6 +72,25 @@
# include <sys/resource.h> # include <sys/resource.h>
# include <sys/mman.h> # include <sys/mman.h>
# elif defined(U3_OS_mingw)
# define signal mingw_has_no_usable_signal
# define raise mingw_has_no_usable_raise
# define _POSIX
# include <inttypes.h>
# include <stdlib.h>
# include <string.h>
# include <stdarg.h>
# include <unistd.h>
# include <stdint.h>
# include <assert.h>
# include <setjmp.h>
# include <stdio.h>
# include <dirent.h>
# include <signal.h>
# include <sys/time.h>
# include "mman.h"
# include "compat.h"
# else # else
#error "port: headers" #error "port: headers"
# endif # endif
@ -97,14 +116,10 @@
# define U3_OS_LoomBase 0x36000000 # define U3_OS_LoomBase 0x36000000
# endif # endif
# define U3_OS_LoomBits 29 // ie, 2^29 words == 2GB # define U3_OS_LoomBits 29 // ie, 2^29 words == 2GB
# elif defined(U3_OS_osx) # elif defined(U3_OS_osx) && defined(U3_CPU_aarch64) || defined(U3_OS_mingw)
# ifdef __LP64__ # define U3_OS_LoomBase 0x28000000000
# define U3_OS_LoomBase 0x200000000
# else
# define U3_OS_LoomBase 0x4000000
# endif
# define U3_OS_LoomBits 29 // ie, 2^29 words == 2GB # define U3_OS_LoomBits 29 // ie, 2^29 words == 2GB
# elif defined(U3_OS_bsd) # elif defined(U3_OS_osx) || defined(U3_OS_bsd)
# ifdef __LP64__ # ifdef __LP64__
# define U3_OS_LoomBase 0x200000000 # define U3_OS_LoomBase 0x200000000
# else # else
@ -153,7 +168,7 @@
/* Byte swapping. /* Byte swapping.
*/ */
# if defined(U3_OS_linux) || defined(U3_OS_bsd) # if defined(U3_OS_linux) || defined(U3_OS_bsd) || defined(U3_OS_mingw)
# define c3_bswap_16(x) bswap_16(x) # define c3_bswap_16(x) bswap_16(x)
# define c3_bswap_32(x) bswap_32(x) # define c3_bswap_32(x) bswap_32(x)
# define c3_bswap_64(x) bswap_64(x) # define c3_bswap_64(x) bswap_64(x)
@ -167,7 +182,7 @@
/* Sync. /* Sync.
*/ */
# if defined(U3_OS_linux) # if defined(U3_OS_linux) || defined(U3_OS_mingw)
# define c3_sync(fd) (fdatasync(fd)) # define c3_sync(fd) (fdatasync(fd))
# elif defined(U3_OS_osx) # elif defined(U3_OS_osx)
# define c3_sync(fd) (fcntl(fd, F_FULLFSYNC, 0)) # define c3_sync(fd) (fcntl(fd, F_FULLFSYNC, 0))
@ -182,7 +197,7 @@
# if defined(U3_OS_linux) # if defined(U3_OS_linux)
# include <stdio_ext.h> # include <stdio_ext.h>
# define c3_fpurge __fpurge # define c3_fpurge __fpurge
# elif defined(U3_OS_bsd) || defined(U3_OS_osx) # elif defined(U3_OS_bsd) || defined(U3_OS_osx) || defined(U3_OS_mingw)
# define c3_fpurge fpurge # define c3_fpurge fpurge
# else # else
# error "port: fpurge" # error "port: fpurge"
@ -190,7 +205,7 @@
/* Stat. /* Stat.
*/ */
# if defined(U3_OS_linux) # if defined(U3_OS_linux) || defined(U3_OS_mingw)
# define c3_stat_mtime(dp) (u3_time_t_in_ts((dp)->st_mtime)) # define c3_stat_mtime(dp) (u3_time_t_in_ts((dp)->st_mtime))
# elif defined(U3_OS_osx) # elif defined(U3_OS_osx)
# define c3_stat_mtime(dp) (u3_time_in_ts(&((dp)->st_mtimespec))) # define c3_stat_mtime(dp) (u3_time_in_ts(&((dp)->st_mtimespec)))
@ -200,6 +215,16 @@
# define lseek64 lseek # define lseek64 lseek
# else # else
# error "port: timeconvert" # error "port: timeconvert"
# endif
/* Null.
*/
# if defined(U3_OS_linux) || defined(U3_OS_bsd) || defined(U3_OS_osx)
# define c3_dev_null "/dev/null"
# elif defined(U3_OS_mingw)
# define c3_dev_null "nul"
# else
# error "port: /dev/null"
# endif # endif
/* Static assertion. /* Static assertion.

View File

@ -2,6 +2,9 @@
** **
** This file is in the public domain. ** This file is in the public domain.
*/ */
#include <openssl/opensslv.h>
/** Constants. /** Constants.
**/ **/
/* u3a_bits: number of bits in word-addressed pointer. 29 == 2GB. /* u3a_bits: number of bits in word-addressed pointer. 29 == 2GB.

View File

@ -224,20 +224,38 @@
/* u3_utty: unix tty. /* u3_utty: unix tty.
*/ */
typedef struct _u3_utty { struct _u3_utty;
union {
/* u3_ustm: uv stream.
*/
typedef union _u3_ustm {
uv_pipe_t pop_u; uv_pipe_t pop_u;
uv_tcp_t wax_u; uv_tcp_t wax_u;
}; uv_tty_t tty_u;
} u3_ustm;
/* u3_ttyf: simple unix tty function.
*/
typedef c3_o (*u3_ttyf)(struct _u3_utty* uty_u);
/* u3_utty: unix tty.
*/
typedef struct _u3_utty {
u3_ustm pin_u; // input stream
u3_ustm pop_u; // output stream
struct _u3_utty* nex_u; // next in host list struct _u3_utty* nex_u; // next in host list
u3_ttyf sta_f; // start tty
u3_ttyf sto_f; // clean up tty
u3_ttyf hij_f; // hijack tty for cooked print
u3_ttyf loj_f; // release tty from cooked print
c3_o (*wsz_f)
(struct _u3_utty* uty_u,
c3_l* col_l,
c3_l* row_l); // return tty window size
c3_i fid_i; // file descriptor c3_i fid_i; // file descriptor
c3_w tid_l; // terminal identity number c3_w tid_l; // terminal identity number
u3_utfo ufo_u; // terminfo strings u3_utfo ufo_u; // terminfo strings
c3_i cug_i; // blocking fcntl flags
c3_i nob_i; // nonblocking fcntl flags
u3_utat tat_u; // control state u3_utat tat_u; // control state
struct termios bak_u; // cooked terminal state
struct termios raw_u; // raw terminal state
struct _u3_auto* car_u; // driver hack struct _u3_auto* car_u; // driver hack
} u3_utty; } u3_utty;
@ -301,6 +319,9 @@
c3_d now_d; // event tick c3_d now_d; // event tick
uv_loop_t* lup_u; // libuv event loop uv_loop_t* lup_u; // libuv event loop
u3_usig* sig_u; // signal list u3_usig* sig_u; // signal list
#if defined(U3_OS_mingw)
HANDLE cev_u; // Ctrl-C event handle
#endif
u3_utty* uty_u; // linked terminal list u3_utty* uty_u; // linked terminal list
u3_opts ops_u; // commandline options u3_opts ops_u; // commandline options
c3_i xit_i; // exit code for shutdown c3_i xit_i; // exit code for shutdown
@ -469,6 +490,7 @@
time_t wen_t; // process creation time time_t wen_t; // process creation time
u3_mojo inn_u; // client's stdin u3_mojo inn_u; // client's stdin
u3_moat out_u; // client's stdout u3_moat out_u; // client's stdout
uv_pipe_t err_u; // client's stderr
c3_w wag_w; // config flags c3_w wag_w; // config flags
c3_c* bin_c; // binary path c3_c* bin_c; // binary path
c3_c* pax_c; // directory c3_c* pax_c; // directory
@ -641,7 +663,8 @@
/* u3_king: all executing piers. /* u3_king: all executing piers.
*/ */
typedef struct _u3_king { typedef struct _u3_king {
c3_c* certs_c; // ssl certificate dump void (*ssl_curl_f)(void*); // setup ssl CAs in CURL*
void (*ssl_x509_f)(void*); // setup ssl CAs in X509_STORE*
u3_pier* pir_u; // pier list u3_pier* pir_u; // pier list
uv_timer_t tim_u; // gc timer uv_timer_t tim_u; // gc timer
} u3_king; } u3_king;
@ -716,7 +739,7 @@
*/ */
u3_atom u3_atom
u3_time_in_ts(struct timespec* tim_ts); u3_time_in_ts(struct timespec* tim_ts);
#if defined(U3_OS_linux) #if defined(U3_OS_linux) || defined(U3_OS_mingw)
/* u3_time_t_in_ts(): urbit time from time_t. /* u3_time_t_in_ts(): urbit time from time_t.
*/ */
u3_atom u3_atom
@ -1103,6 +1126,11 @@
void void
u3_term_log_exit(void); u3_term_log_exit(void);
/* u3_ptty_init(): initialize platform-specific tty.
*/
u3_utty*
u3_ptty_init(uv_loop_t* lup_u, const c3_c** err_c);
/** Ames, packet networking. /** Ames, packet networking.
**/ **/
@ -1371,6 +1399,15 @@
void void
u3_king_grab(void* ptr_v); u3_king_grab(void* ptr_v);
/* u3_daemon_init(): platform-specific daemon mode initialization.
*/
void
u3_daemon_init();
/* u3_write_fd(): retry interrupts, continue partial writes, assert errors.
*/
void
u3_write_fd(c3_i fid_i, const void* buf_v, size_t len_i);
c3_w c3_w
u3_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result); u3_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);

View File

@ -1,12 +1,11 @@
/* g/e.c /* g/e.c
** **
*/ */
#include "all.h"
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include "all.h"
#ifdef U3_SNAPSHOT_VALIDATION #ifdef U3_SNAPSHOT_VALIDATION
/* Image check. /* Image check.
*/ */
@ -815,8 +814,8 @@ u3e_save(void)
_ce_image_sync(&u3P.nor_u); _ce_image_sync(&u3P.nor_u);
_ce_image_sync(&u3P.sou_u); _ce_image_sync(&u3P.sou_u);
_ce_patch_delete();
_ce_patch_free(pat_u); _ce_patch_free(pat_u);
_ce_patch_delete();
} }
/* u3e_live(): start the checkpointing system. /* u3e_live(): start the checkpointing system.
@ -853,8 +852,8 @@ u3e_live(c3_o nuu_o, c3_c* dir_c)
_ce_patch_apply(pat_u); _ce_patch_apply(pat_u);
_ce_image_sync(&u3P.nor_u); _ce_image_sync(&u3P.nor_u);
_ce_image_sync(&u3P.sou_u); _ce_image_sync(&u3P.sou_u);
_ce_patch_delete();
_ce_patch_free(pat_u); _ce_patch_free(pat_u);
_ce_patch_delete();
} }
/* Write image files to memory; reinstate protection. /* Write image files to memory; reinstate protection.

View File

@ -1,17 +1,15 @@
/* n/m.c /* n/m.c
** **
*/ */
#include "all.h"
#include "rsignal.h"
#include "vere/vere.h"
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <ctype.h> #include <ctype.h>
#include <sigsegv.h>
#include <curl/curl.h>
#include <openssl/crypto.h> #include <openssl/crypto.h>
#include "all.h"
#include "vere/vere.h"
// XX stack-overflow recovery should be gated by -a // XX stack-overflow recovery should be gated by -a
// //
#undef NO_OVERFLOW #undef NO_OVERFLOW
@ -75,7 +73,17 @@
u3_noun arg); u3_noun arg);
static sigjmp_buf u3_Signal; // u3m_signal uses restricted functionality signals for compatibility reasons:
// some platforms may not provide true POSIX asynchronous signals and their
// compat layer will then implement this restricted functionality subset.
// u3m_signal never needs to interrupt I/O operations, its signal handlers
// do not manipulate signals, do not modify shared state, and always either
// return or longjmp.
//
static rsignal_jmpbuf u3_Signal;
#if !defined(U3_OS_mingw)
#include <sigsegv.h>
#ifndef SIGSTKSZ #ifndef SIGSTKSZ
# define SIGSTKSZ 16384 # define SIGSTKSZ 16384
@ -83,6 +91,7 @@ static sigjmp_buf u3_Signal;
#ifndef NO_OVERFLOW #ifndef NO_OVERFLOW
static uint8_t Sigstk[SIGSTKSZ]; static uint8_t Sigstk[SIGSTKSZ];
#endif #endif
#endif
#if 0 #if 0
/* _cm_punt(): crudely print trace. /* _cm_punt(): crudely print trace.
@ -129,17 +138,25 @@ static void _cm_overflow(void *arg1, void *arg2, void *arg3)
static void static void
_cm_signal_handle(c3_l sig_l) _cm_signal_handle(c3_l sig_l)
{ {
#ifndef U3_OS_mingw
if ( c3__over == sig_l ) { if ( c3__over == sig_l ) {
#ifndef NO_OVERFLOW
sigsegv_leave_handler(_cm_overflow, NULL, NULL, NULL); sigsegv_leave_handler(_cm_overflow, NULL, NULL, NULL);
} #endif
else { } else
#endif
{
u3m_signal(sig_l); u3m_signal(sig_l);
} }
} }
#ifndef NO_OVERFLOW #ifndef NO_OVERFLOW
static void static void
#ifndef U3_OS_mingw
_cm_signal_handle_over(int emergency, stackoverflow_context_t scp) _cm_signal_handle_over(int emergency, stackoverflow_context_t scp)
#else
_cm_signal_handle_over(int x)
#endif
{ {
_cm_signal_handle(c3__over); _cm_signal_handle(c3__over);
} }
@ -330,10 +347,14 @@ _cm_signal_deep(c3_w mil_w)
} }
#ifndef NO_OVERFLOW #ifndef NO_OVERFLOW
#ifndef U3_OS_mingw
stackoverflow_install_handler(_cm_signal_handle_over, Sigstk, SIGSTKSZ); stackoverflow_install_handler(_cm_signal_handle_over, Sigstk, SIGSTKSZ);
#else
rsignal_install_handler(SIGSTK, _cm_signal_handle_over);
#endif #endif
signal(SIGINT, _cm_signal_handle_intr); #endif
signal(SIGTERM, _cm_signal_handle_term); rsignal_install_handler(SIGINT, _cm_signal_handle_intr);
rsignal_install_handler(SIGTERM, _cm_signal_handle_term);
// Provide a little emergency memory, for use in case things // Provide a little emergency memory, for use in case things
// go utterly haywire. // go utterly haywire.
@ -349,11 +370,11 @@ _cm_signal_deep(c3_w mil_w)
itm_u.it_value.tv_sec = (mil_w / 1000); itm_u.it_value.tv_sec = (mil_w / 1000);
itm_u.it_value.tv_usec = 1000 * (mil_w % 1000); itm_u.it_value.tv_usec = 1000 * (mil_w % 1000);
if ( setitimer(ITIMER_VIRTUAL, &itm_u, 0) ) { if ( rsignal_setitimer(ITIMER_VIRTUAL, &itm_u, 0) ) {
u3l_log("loom: set timer failed %s\r\n", strerror(errno)); u3l_log("loom: set timer failed %s\r\n", strerror(errno));
} }
else { else {
signal(SIGVTALRM, _cm_signal_handle_alrm); rsignal_install_handler(SIGVTALRM, _cm_signal_handle_alrm);
} }
} }
@ -365,12 +386,16 @@ _cm_signal_deep(c3_w mil_w)
static void static void
_cm_signal_done() _cm_signal_done()
{ {
signal(SIGINT, SIG_IGN); rsignal_deinstall_handler(SIGINT);
signal(SIGTERM, SIG_IGN); rsignal_deinstall_handler(SIGTERM);
signal(SIGVTALRM, SIG_IGN); rsignal_deinstall_handler(SIGVTALRM);
#ifndef NO_OVERFLOW #ifndef NO_OVERFLOW
#ifndef U3_OS_mingw
stackoverflow_deinstall_handler(); stackoverflow_deinstall_handler();
#else
rsignal_deinstall_handler(SIGSTK);
#endif
#endif #endif
{ {
struct itimerval itm_u; struct itimerval itm_u;
@ -378,7 +403,7 @@ _cm_signal_done()
timerclear(&itm_u.it_interval); timerclear(&itm_u.it_interval);
timerclear(&itm_u.it_value); timerclear(&itm_u.it_value);
if ( setitimer(ITIMER_VIRTUAL, &itm_u, 0) ) { if ( rsignal_setitimer(ITIMER_VIRTUAL, &itm_u, 0) ) {
u3l_log("loom: clear timer failed %s\r\n", strerror(errno)); u3l_log("loom: clear timer failed %s\r\n", strerror(errno));
} }
} }
@ -397,7 +422,7 @@ _cm_signal_done()
void void
u3m_signal(u3_noun sig_l) u3m_signal(u3_noun sig_l)
{ {
siglongjmp(u3_Signal, sig_l); rsignal_longjmp(u3_Signal, sig_l);
} }
/* u3m_file(): load file, as atom, or bail. /* u3m_file(): load file, as atom, or bail.
@ -959,7 +984,7 @@ u3m_soft_top(c3_w mil_w, // timer ms
*/ */
_cm_signal_deep(mil_w); _cm_signal_deep(mil_w);
if ( 0 != (sig_l = sigsetjmp(u3_Signal, 1)) ) { if ( 0 != (sig_l = rsignal_setjmp(u3_Signal)) ) {
// reinitialize trace state // reinitialize trace state
// //
u3t_init(); u3t_init();
@ -1559,6 +1584,10 @@ u3m_wall(u3_noun wol)
static void static void
_cm_limits(void) _cm_limits(void)
{ {
# ifdef U3_OS_mingw
// Windows doesn't have rlimits. Default maximum thread
// stack size is set in the executable file header.
# else
struct rlimit rlm; struct rlimit rlm;
// Moar stack. // Moar stack.
@ -1606,6 +1635,7 @@ _cm_limits(void)
} }
} }
# endif # endif
# endif
} }
/* _cm_signals(): set up interrupts, etc. /* _cm_signals(): set up interrupts, etc.
@ -1613,13 +1643,23 @@ _cm_limits(void)
static void static void
_cm_signals(void) _cm_signals(void)
{ {
# if defined(U3_OS_mingw)
// vere using libsigsegv on MingW is very slow, because libsigsegv
// works by installing a top-level SEH unhandled exception filter.
// The top-level filter runs only after Windows walks the whole stack,
// looking up registered exception filters for every stack frame, and
// finds no filter to handle the exception.
// Instead of libsigsegv, all vere functions register a SEH exception
// filter (see compat/mingw/seh_handler.c) that handles both memory
// access and stack overflow exceptions. It calls u3e_fault directly.
# else
if ( 0 != sigsegv_install_handler(u3e_fault) ) { if ( 0 != sigsegv_install_handler(u3e_fault) ) {
u3l_log("boot: sigsegv install failed\n"); u3l_log("boot: sigsegv install failed\n");
exit(1); exit(1);
} }
// signal(SIGINT, _loom_stop); # endif
# if defined(U3_OS_PROF)
// Block SIGPROF, so that if/when we reactivate it on the // Block SIGPROF, so that if/when we reactivate it on the
// main thread for profiling, we won't get hits in parallel // main thread for profiling, we won't get hits in parallel
// on other threads. // on other threads.
@ -1634,6 +1674,7 @@ _cm_signals(void)
exit(1); exit(1);
} }
} }
# endif
} }
/* u3m_init(): start the environment. /* u3m_init(): start the environment.
@ -1670,7 +1711,7 @@ u3m_init(void)
u3l_log("boot: mapping %dMB failed\r\n", (len_w / (1024 * 1024))); u3l_log("boot: mapping %dMB failed\r\n", (len_w / (1024 * 1024)));
u3l_log("see urbit.org/using/install/#about-swap-space" u3l_log("see urbit.org/using/install/#about-swap-space"
" for adding swap space\r\n"); " for adding swap space\r\n");
if ( -1 != (c3_ps)map_v ) { if ( -1 != (c3_ps)dyn_v ) {
u3l_log("if porting to a new platform, try U3_OS_LoomBase %p\r\n", u3l_log("if porting to a new platform, try U3_OS_LoomBase %p\r\n",
dyn_v); dyn_v);
} }

View File

@ -2,11 +2,10 @@
** **
*/ */
#include <errno.h>
#include <fcntl.h>
#include "all.h" #include "all.h"
#include "ur/ur.h" #include "ur/ur.h"
#include <errno.h>
#include <fcntl.h>
/* _cs_jam_buf: struct for tracking the fibonacci-allocated jam of a noun /* _cs_jam_buf: struct for tracking the fibonacci-allocated jam of a noun
*/ */

View File

@ -519,7 +519,7 @@ u3t_boot(void)
{ {
if ( u3C.wag_w & u3o_debug_cpu ) { if ( u3C.wag_w & u3o_debug_cpu ) {
_ct_lop_o = c3n; _ct_lop_o = c3n;
#if defined(U3_OS_osx) || defined(U3_OS_linux) #if defined(U3_OS_PROF)
// skip profiling if we don't yet have an arvo kernel // skip profiling if we don't yet have an arvo kernel
// //
if ( 0 == u3A->roc ) { if ( 0 == u3A->roc ) {
@ -551,10 +551,6 @@ u3t_boot(void)
itm_v.it_value = itm_v.it_interval; itm_v.it_value = itm_v.it_interval;
setitimer(ITIMER_PROF, &itm_v, 0); setitimer(ITIMER_PROF, &itm_v, 0);
} }
#elif defined(U3_OS_bsd)
// XX "Profiling isn't yet supported on BSD"
#else
# error "port: profiling"
#endif #endif
} }
} }
@ -565,7 +561,7 @@ void
u3t_boff(void) u3t_boff(void)
{ {
if ( u3C.wag_w & u3o_debug_cpu ) { if ( u3C.wag_w & u3o_debug_cpu ) {
#if defined(U3_OS_osx) || defined(U3_OS_linux) #if defined(U3_OS_PROF)
// Mask SIGPROF signals in this thread (and this is the only // Mask SIGPROF signals in this thread (and this is the only
// thread that unblocked them). // thread that unblocked them).
{ {
@ -590,11 +586,6 @@ u3t_boff(void)
sig_s.sa_handler = SIG_IGN; sig_s.sa_handler = SIG_IGN;
sigaction(SIGPROF, &sig_s, 0); sigaction(SIGPROF, &sig_s, 0);
} }
#elif defined(U3_OS_bsd)
// XX "Profiling isn't yet supported on BSD"
#else
# error "port: profiling"
#endif #endif
} }
} }

View File

@ -1,14 +1,13 @@
/* noun/urth.c /* noun/urth.c
** **
*/ */
#include "all.h"
#include "ur/ur.h"
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <ctype.h> #include <ctype.h>
#include "all.h"
#include "ur/ur.h"
/* _cu_atom_to_ref(): allocate indirect atom off-loom. /* _cu_atom_to_ref(): allocate indirect atom off-loom.
*/ */
static inline ur_nref static inline ur_nref

View File

@ -1,8 +1,8 @@
/* g/v.c /* g/v.c
** **
*/ */
#include <stdio.h>
#include "all.h" #include "all.h"
#include <stdio.h>
#define _CVX_LOAD 4 #define _CVX_LOAD 4
#define _CVX_PEEK 22 #define _CVX_PEEK 22

View File

@ -1,21 +1,5 @@
/* vere/auto.c /* vere/auto.c
*/ */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <setjmp.h>
#include <gmp.h>
#include <sigsegv.h>
#include <stdint.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <uv.h>
#include <errno.h>
#include "all.h" #include "all.h"
#include "vere/vere.h" #include "vere/vere.h"

View File

@ -2,11 +2,10 @@
** **
** ethereum-integrated pre-boot validation ** ethereum-integrated pre-boot validation
*/ */
#include <curl/curl.h>
#include <uv.h>
#include "all.h" #include "all.h"
#include "vere/vere.h" #include "vere/vere.h"
#include <curl/curl.h>
#include <uv.h>
/* _dawn_oct_to_buf(): +octs to uv_buf_t /* _dawn_oct_to_buf(): +octs to uv_buf_t
*/ */
@ -45,8 +44,10 @@ _dawn_buf_to_oct(uv_buf_t buf_u)
/* _dawn_curl_alloc(): allocate a response buffer for curl /* _dawn_curl_alloc(): allocate a response buffer for curl
*/ */
static size_t static size_t
_dawn_curl_alloc(void* dat_v, size_t uni_t, size_t mem_t, uv_buf_t* buf_u) _dawn_curl_alloc(void* dat_v, size_t uni_t, size_t mem_t, void* buf_v)
{ {
uv_buf_t* buf_u = buf_v;
size_t siz_t = uni_t * mem_t; size_t siz_t = uni_t * mem_t;
buf_u->base = c3_realloc(buf_u->base, 1 + siz_t + buf_u->len); buf_u->base = c3_realloc(buf_u->base, 1 + siz_t + buf_u->len);
@ -80,7 +81,7 @@ _dawn_post_json(c3_c* url_c, uv_buf_t lod_u)
// XX require TLS, pin default cert? // XX require TLS, pin default cert?
// //
curl_easy_setopt(curl, CURLOPT_CAINFO, u3K.certs_c); u3K.ssl_curl_f(curl);
curl_easy_setopt(curl, CURLOPT_URL, url_c); curl_easy_setopt(curl, CURLOPT_URL, url_c);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _dawn_curl_alloc); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _dawn_curl_alloc);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&buf_u); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&buf_u);
@ -127,7 +128,7 @@ _dawn_get_jam(c3_c* url_c)
// XX require TLS, pin default cert? // XX require TLS, pin default cert?
// //
curl_easy_setopt(curl, CURLOPT_CAINFO, u3K.certs_c); u3K.ssl_curl_f(curl);
curl_easy_setopt(curl, CURLOPT_URL, url_c); curl_easy_setopt(curl, CURLOPT_URL, url_c);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _dawn_curl_alloc); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _dawn_curl_alloc);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&buf_u); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&buf_u);

View File

@ -1,17 +1,18 @@
/* vere/db/lmdb.c /* vere/db/lmdb.c
*/ */
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <lmdb.h>
#include "c/portable.h" #include "c/portable.h"
#include "c/types.h" #include "c/types.h"
#include "c/defs.h" #include "c/defs.h"
#include "vere/db/lmdb.h"
#include <sys/stat.h>
#include <vere/db/lmdb.h> /* mdb_logerror(): writes an error message and lmdb error code to f.
*/
void mdb_logerror(FILE* f, int err, const char* fmt, ...);
/* mdb_get_filesize(): gets the size of a lmdb database file on disk.
*/
intmax_t mdb_get_filesize(mdb_filehandle_t han_u);
// lmdb api wrapper // lmdb api wrapper
// //
@ -42,31 +43,28 @@ u3_lmdb_init(const c3_c* pax_c, size_t siz_i)
c3_w ret_w; c3_w ret_w;
if ( (ret_w = mdb_env_create(&env_u)) ) { if ( (ret_w = mdb_env_create(&env_u)) ) {
fprintf(stderr, "lmdb: init fail: %s\r\n", mdb_strerror(ret_w)); mdb_logerror(stderr, ret_w, "lmdb: init fail");
return 0; return 0;
} }
// Our databases have two tables: META and EVENTS // Our databases have two tables: META and EVENTS
// //
if ( (ret_w = mdb_env_set_maxdbs(env_u, 2)) ) { if ( (ret_w = mdb_env_set_maxdbs(env_u, 2)) ) {
fprintf(stderr, "lmdb: failed to set number of databases: %s\r\n", mdb_logerror(stderr, ret_w, "lmdb: failed to set number of databases");
mdb_strerror(ret_w));
// XX dispose env_u // XX dispose env_u
// //
return 0; return 0;
} }
if ( (ret_w = mdb_env_set_mapsize(env_u, siz_i)) ) { if ( (ret_w = mdb_env_set_mapsize(env_u, siz_i)) ) {
fprintf(stderr, "lmdb: failed to set database size: %s\r\n", mdb_logerror(stderr, ret_w, "lmdb: failed to set database size");
mdb_strerror(ret_w));
// XX dispose env_u // XX dispose env_u
// //
return 0; return 0;
} }
if ( (ret_w = mdb_env_open(env_u, pax_c, 0, 0664)) ) { if ( (ret_w = mdb_env_open(env_u, pax_c, 0, 0664)) ) {
fprintf(stderr, "lmdb: failed to open event log: %s\r\n", mdb_logerror(stderr, ret_w, "lmdb: failed to open event log");
mdb_strerror(ret_w));
// XX dispose env_u // XX dispose env_u
// //
return 0; return 0;
@ -111,18 +109,17 @@ u3_lmdb_stat(MDB_env* env_u, FILE* fil_u)
} }
{ {
c3_i fid_i; mdb_filehandle_t han_u;
struct stat sat_u; mdb_env_get_fd(env_u, &han_u);
mdb_env_get_fd(env_u, &fid_i); intmax_t dis_i = mdb_get_filesize(han_u);
fstat(fid_i, &sat_u);
if ( siz_i != sat_u.st_size ) { if ( siz_i != dis_i ) {
fprintf(fil_u, "MISMATCH:\n"); fprintf(fil_u, "MISMATCH:\n");
} }
fprintf(fil_u, " file size (page): %zu\n", siz_i); fprintf(fil_u, " file size (page): %zu\n", siz_i);
fprintf(fil_u, " file size (stat): %jd\n", (intmax_t)sat_u.st_size); fprintf(fil_u, " file size (stat): %jd\n", dis_i);
} }
} }
@ -140,7 +137,7 @@ u3_lmdb_gulf(MDB_env* env_u, c3_d* low_d, c3_d* hig_d)
// XX why no MDB_RDONLY? // XX why no MDB_RDONLY?
// //
if ( (ret_w = mdb_txn_begin(env_u, 0, 0, &txn_u)) ) { if ( (ret_w = mdb_txn_begin(env_u, 0, 0, &txn_u)) ) {
fprintf(stderr, "lmdb: gulf: txn_begin fail: %s\r\n", mdb_strerror(ret_w)); mdb_logerror(stderr, ret_w, "lmdb: gulf: txn_begin fail");
return c3n; return c3n;
} }
@ -150,7 +147,7 @@ u3_lmdb_gulf(MDB_env* env_u, c3_d* low_d, c3_d* hig_d)
c3_w ops_w = MDB_CREATE | MDB_INTEGERKEY; c3_w ops_w = MDB_CREATE | MDB_INTEGERKEY;
if ( (ret_w = mdb_dbi_open(txn_u, "EVENTS", ops_w, &mdb_u)) ) { if ( (ret_w = mdb_dbi_open(txn_u, "EVENTS", ops_w, &mdb_u)) ) {
fprintf(stderr, "lmdb: gulf: dbi_open fail: %s\r\n", mdb_strerror(ret_w)); mdb_logerror(stderr, ret_w, "lmdb: gulf: dbi_open fail");
// XX confirm // XX confirm
// //
mdb_txn_abort(txn_u); mdb_txn_abort(txn_u);
@ -167,8 +164,7 @@ u3_lmdb_gulf(MDB_env* env_u, c3_d* low_d, c3_d* hig_d)
// creates a cursor to point to the last event // creates a cursor to point to the last event
// //
if ( (ret_w = mdb_cursor_open(txn_u, mdb_u, &cur_u)) ) { if ( (ret_w = mdb_cursor_open(txn_u, mdb_u, &cur_u)) ) {
fprintf(stderr, "lmdb: gulf: cursor_open fail: %s\r\n", mdb_logerror(stderr, ret_w, "lmdb: gulf: cursor_open fail");
mdb_strerror(ret_w));
// XX confirm // XX confirm
// //
mdb_txn_abort(txn_u); mdb_txn_abort(txn_u);
@ -187,8 +183,7 @@ u3_lmdb_gulf(MDB_env* env_u, c3_d* low_d, c3_d* hig_d)
return c3y; return c3y;
} }
else if ( ret_w ) { else if ( ret_w ) {
fprintf(stderr, "lmdb: gulf: head fail: %s\r\n", mdb_logerror(stderr, ret_w, "lmdb: gulf: head fail");
mdb_strerror(ret_w));
mdb_cursor_close(cur_u); mdb_cursor_close(cur_u);
mdb_txn_abort(txn_u); mdb_txn_abort(txn_u);
return c3n; return c3n;
@ -211,7 +206,7 @@ u3_lmdb_gulf(MDB_env* env_u, c3_d* low_d, c3_d* hig_d)
mdb_txn_abort(txn_u); mdb_txn_abort(txn_u);
if ( ret_w ) { if ( ret_w ) {
fprintf(stderr, "lmdb: gulf: last fail: %s\r\n", mdb_strerror(ret_w)); mdb_logerror(stderr, ret_w, "lmdb: gulf: last fail");
return c3n; return c3n;
} }
else { else {
@ -238,7 +233,7 @@ u3_lmdb_read(MDB_env* env_u,
// create a read-only transaction. // create a read-only transaction.
// //
if ( (ret_w = mdb_txn_begin(env_u, 0, MDB_RDONLY, &txn_u)) ) { if ( (ret_w = mdb_txn_begin(env_u, 0, MDB_RDONLY, &txn_u)) ) {
fprintf(stderr, "lmdb: read txn_begin fail: %s\r\n", mdb_strerror(ret_w)); mdb_logerror(stderr, ret_w, "lmdb: read txn_begin fail");
return c3n; return c3n;
} }
@ -248,7 +243,7 @@ u3_lmdb_read(MDB_env* env_u,
c3_w ops_w = MDB_CREATE | MDB_INTEGERKEY; c3_w ops_w = MDB_CREATE | MDB_INTEGERKEY;
if ( (ret_w = mdb_dbi_open(txn_u, "EVENTS", ops_w, &mdb_u)) ) { if ( (ret_w = mdb_dbi_open(txn_u, "EVENTS", ops_w, &mdb_u)) ) {
fprintf(stderr, "lmdb: read: dbi_open fail: %s\r\n", mdb_strerror(ret_w)); mdb_logerror(stderr, ret_w, "lmdb: read: dbi_open fail");
// XX confirm // XX confirm
// //
mdb_txn_abort(txn_u); mdb_txn_abort(txn_u);
@ -267,8 +262,7 @@ u3_lmdb_read(MDB_env* env_u,
// creates a cursor to iterate over keys starting at [eve_d] // creates a cursor to iterate over keys starting at [eve_d]
// //
if ( (ret_w = mdb_cursor_open(txn_u, mdb_u, &cur_u)) ) { if ( (ret_w = mdb_cursor_open(txn_u, mdb_u, &cur_u)) ) {
fprintf(stderr, "lmdb: read: cursor_open fail: %s\r\n", mdb_logerror(stderr, ret_w, "lmdb: read: cursor_open fail");
mdb_strerror(ret_w));
// XX confirm // XX confirm
// //
mdb_txn_abort(txn_u); mdb_txn_abort(txn_u);
@ -278,9 +272,7 @@ u3_lmdb_read(MDB_env* env_u,
// set the cursor to the position of [eve_d] // set the cursor to the position of [eve_d]
// //
if ( (ret_w = mdb_cursor_get(cur_u, &key_u, &val_u, MDB_SET_KEY)) ) { if ( (ret_w = mdb_cursor_get(cur_u, &key_u, &val_u, MDB_SET_KEY)) ) {
fprintf(stderr, "lmdb: read: initial cursor_get failed at %" PRIu64 ": %s\r\n", mdb_logerror(stderr, ret_w, "lmdb: read: initial cursor_get failed at %" PRIu64, eve_d);
eve_d,
mdb_strerror(ret_w));
mdb_cursor_close(cur_u); mdb_cursor_close(cur_u);
// XX confirm // XX confirm
// //
@ -325,8 +317,7 @@ u3_lmdb_read(MDB_env* env_u,
if ( (ret_w = mdb_cursor_get(cur_u, &key_u, &val_u, MDB_NEXT)) if ( (ret_w = mdb_cursor_get(cur_u, &key_u, &val_u, MDB_NEXT))
&& (MDB_NOTFOUND != ret_w) ) && (MDB_NOTFOUND != ret_w) )
{ {
fprintf(stderr, "lmdb: read: error: %s\r\n", mdb_logerror(stderr, ret_w, "lmdb: read: error");
mdb_strerror(ret_w));
ret_o = c3n; ret_o = c3n;
break; break;
} }
@ -359,7 +350,7 @@ u3_lmdb_save(MDB_env* env_u,
// create a write transaction // create a write transaction
// //
if ( (ret_w = mdb_txn_begin(env_u, 0, 0, &txn_u)) ) { if ( (ret_w = mdb_txn_begin(env_u, 0, 0, &txn_u)) ) {
fprintf(stderr, "lmdb: write: txn_begin fail: %s\r\n", mdb_strerror(ret_w)); mdb_logerror(stderr, ret_w, "lmdb: write: txn_begin fail");
return c3n; return c3n;
} }
@ -369,7 +360,7 @@ u3_lmdb_save(MDB_env* env_u,
c3_w ops_w = MDB_CREATE | MDB_INTEGERKEY; c3_w ops_w = MDB_CREATE | MDB_INTEGERKEY;
if ( (ret_w = mdb_dbi_open(txn_u, "EVENTS", ops_w, &mdb_u)) ) { if ( (ret_w = mdb_dbi_open(txn_u, "EVENTS", ops_w, &mdb_u)) ) {
fprintf(stderr, "lmdb: write: dbi_open fail: %s\r\n", mdb_strerror(ret_w)); mdb_logerror(stderr, ret_w, "lmdb: write: dbi_open fail");
mdb_txn_abort(txn_u); mdb_txn_abort(txn_u);
return c3n; return c3n;
} }
@ -401,7 +392,7 @@ u3_lmdb_save(MDB_env* env_u,
// commit transaction // commit transaction
// //
if ( (ret_w = mdb_txn_commit(txn_u)) ) { if ( (ret_w = mdb_txn_commit(txn_u)) ) {
fprintf(stderr, "lmdb: write failed: %s\r\n", mdb_strerror(ret_w)); mdb_logerror(stderr, ret_w, "lmdb: write failed");
return c3n; return c3n;
} }
@ -423,16 +414,14 @@ u3_lmdb_read_meta(MDB_env* env_u,
// create a read transaction // create a read transaction
// //
if ( (ret_w = mdb_txn_begin(env_u, 0, MDB_RDONLY, &txn_u)) ) { if ( (ret_w = mdb_txn_begin(env_u, 0, MDB_RDONLY, &txn_u)) ) {
fprintf(stderr, "lmdb: meta read: txn_begin fail: %s\r\n", mdb_logerror(stderr, ret_w, "lmdb: meta read: txn_begin fail");
mdb_strerror(ret_w));
return read_f(ptr_v, 0, 0); return read_f(ptr_v, 0, 0);
} }
// open the database in the transaction // open the database in the transaction
// //
if ( (ret_w = mdb_dbi_open(txn_u, "META", 0, &mdb_u)) ) { if ( (ret_w = mdb_dbi_open(txn_u, "META", 0, &mdb_u)) ) {
fprintf(stderr, "lmdb: meta read: dbi_open fail: %s\r\n", mdb_logerror(stderr, ret_w, "lmdb: meta read: dbi_open fail");
mdb_strerror(ret_w));
mdb_txn_abort(txn_u); mdb_txn_abort(txn_u);
return read_f(ptr_v, 0, 0); return read_f(ptr_v, 0, 0);
} }
@ -443,7 +432,7 @@ u3_lmdb_read_meta(MDB_env* env_u,
MDB_val val_u; MDB_val val_u;
if ( (ret_w = mdb_get(txn_u, mdb_u, &key_u, &val_u)) ) { if ( (ret_w = mdb_get(txn_u, mdb_u, &key_u, &val_u)) ) {
fprintf(stderr, "lmdb: read failed: %s\r\n", mdb_strerror(ret_w)); mdb_logerror(stderr, ret_w, "lmdb: read failed");
mdb_txn_abort(txn_u); mdb_txn_abort(txn_u);
return read_f(ptr_v, 0, 0); return read_f(ptr_v, 0, 0);
} }
@ -472,16 +461,14 @@ u3_lmdb_save_meta(MDB_env* env_u,
// create a write transaction // create a write transaction
// //
if ( (ret_w = mdb_txn_begin(env_u, 0, 0, &txn_u)) ) { if ( (ret_w = mdb_txn_begin(env_u, 0, 0, &txn_u)) ) {
fprintf(stderr, "lmdb: meta write: txn_begin fail: %s\r\n", mdb_logerror(stderr, ret_w, "lmdb: meta write: txn_begin fail");
mdb_strerror(ret_w));
return c3n; return c3n;
} }
// opens the database in the transaction // opens the database in the transaction
// //
if ( (ret_w = mdb_dbi_open(txn_u, "META", MDB_CREATE, &mdb_u)) ) { if ( (ret_w = mdb_dbi_open(txn_u, "META", MDB_CREATE, &mdb_u)) ) {
fprintf(stderr, "lmdb: meta write: dbi_open fail: %s\r\n", mdb_logerror(stderr, ret_w, "lmdb: meta write: dbi_open fail");
mdb_strerror(ret_w));
mdb_txn_abort(txn_u); mdb_txn_abort(txn_u);
return c3n; return c3n;
} }
@ -493,7 +480,7 @@ u3_lmdb_save_meta(MDB_env* env_u,
MDB_val val_u = { .mv_size = val_i, .mv_data = val_p }; MDB_val val_u = { .mv_size = val_i, .mv_data = val_p };
if ( (ret_w = mdb_put(txn_u, mdb_u, &key_u, &val_u, 0)) ) { if ( (ret_w = mdb_put(txn_u, mdb_u, &key_u, &val_u, 0)) ) {
fprintf(stderr, "lmdb: write failed: %s\r\n", mdb_strerror(ret_w)); mdb_logerror(stderr, ret_w, "lmdb: write failed");
mdb_txn_abort(txn_u); mdb_txn_abort(txn_u);
return c3n; return c3n;
} }
@ -502,10 +489,31 @@ u3_lmdb_save_meta(MDB_env* env_u,
// commit txn // commit txn
// //
if ( (ret_w = mdb_txn_commit(txn_u)) ) { if ( (ret_w = mdb_txn_commit(txn_u)) ) {
fprintf(stderr, "lmdb: meta write: commit failed: %s\r\n", mdb_logerror(stderr, ret_w, "lmdb: meta write: commit failed");
mdb_strerror(ret_w));
return c3n; return c3n;
} }
return c3y; return c3y;
} }
#if !defined(U3_OS_mingw)
/* mdb_logerror(): writes an error message and lmdb error code to f.
*/
void mdb_logerror(FILE* f, int err, const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(f, fmt, ap);
va_end(ap);
fprintf(f, ": %s\r\n", mdb_strerror(err));
}
/* mdb_get_filesize(): gets the size of a lmdb database file on disk.
*/
intmax_t mdb_get_filesize(mdb_filehandle_t han_u)
{
struct stat sat_u;
fstat(han_u, &sat_u);
return (intmax_t)sat_u.st_size;
}
#endif

View File

@ -1,21 +1,5 @@
/* vere/disk.c /* vere/disk.c
*/ */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <setjmp.h>
#include <gmp.h>
#include <sigsegv.h>
#include <stdint.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <uv.h>
#include <errno.h>
#include "all.h" #include "all.h"
#include "vere/vere.h" #include "vere/vere.h"
#include <vere/db/lmdb.h> #include <vere/db/lmdb.h>

View File

@ -4,22 +4,6 @@
*/ */
#include "all.h" #include "all.h"
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <setjmp.h>
#include <gmp.h>
#include <dirent.h>
#include <stdint.h>
#include <uv.h>
#include <errno.h>
#include <libgen.h>
#include <ftw.h>
#include "vere/vere.h" #include "vere/vere.h"
/* assumptions: /* assumptions:

View File

@ -1,15 +1,6 @@
/* vere/ames.c /* vere/ames.c
** **
*/ */
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <uv.h>
#include <errno.h>
#include "all.h" #include "all.h"
#include "vere/vere.h" #include "vere/vere.h"
#include "ur/serial.h" #include "ur/serial.h"

View File

@ -1,13 +1,6 @@
/* vere/behn.c /* vere/behn.c
** **
*/ */
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <dirent.h>
#include <uv.h>
#include <errno.h>
#include "all.h" #include "all.h"
#include "vere/vere.h" #include "vere/vere.h"

View File

@ -1,18 +1,10 @@
/* vere/cttp.c /* vere/cttp.c
** **
*/ */
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <uv.h>
#include <errno.h>
#include <openssl/ssl.h>
#include <h2o.h>
#include "all.h" #include "all.h"
#include "vere/vere.h" #include "vere/vere.h"
#include <openssl/ssl.h>
#include <h2o.h>
/* u3_csat: client connection state. /* u3_csat: client connection state.
*/ */
@ -985,8 +977,8 @@ _cttp_init_tls(void)
// SSL_OP_NO_TLSv1 | // XX test // SSL_OP_NO_TLSv1 | // XX test
SSL_OP_NO_COMPRESSION); SSL_OP_NO_COMPRESSION);
u3K.ssl_x509_f(SSL_CTX_get_cert_store(tls_u));
SSL_CTX_set_verify(tls_u, SSL_VERIFY_PEER, 0); SSL_CTX_set_verify(tls_u, SSL_VERIFY_PEER, 0);
SSL_CTX_set_default_verify_paths(tls_u);
SSL_CTX_set_session_cache_mode(tls_u, SSL_SESS_CACHE_OFF); SSL_CTX_set_session_cache_mode(tls_u, SSL_SESS_CACHE_OFF);
SSL_CTX_set_cipher_list(tls_u, SSL_CTX_set_cipher_list(tls_u,
"ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:" "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:"

View File

@ -1,13 +1,6 @@
/* vere/root.c /* vere/root.c
** **
*/ */
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <dirent.h>
#include <uv.h>
#include <errno.h>
#include "all.h" #include "all.h"
#include "vere/vere.h" #include "vere/vere.h"

View File

@ -1,13 +1,6 @@
/* vere/root.c /* vere/root.c
** **
*/ */
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <dirent.h>
#include <uv.h>
#include <errno.h>
#include "all.h" #include "all.h"
#include "vere/vere.h" #include "vere/vere.h"

View File

@ -1,21 +1,12 @@
/* vere/http.c /* vere/http.c
** **
*/ */
#include <fcntl.h> #include "all.h"
#include <sys/ioctl.h> #include "vere/vere.h"
#include <sys/stat.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <uv.h>
#include <errno.h>
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <openssl/err.h> #include <openssl/err.h>
#include <h2o.h> #include <h2o.h>
#include "all.h"
#include "vere/vere.h"
typedef struct _u3_h2o_serv { typedef struct _u3_h2o_serv {
h2o_globalconf_t fig_u; // h2o global config h2o_globalconf_t fig_u; // h2o global config
h2o_context_t ctx_u; // h2o ctx h2o_context_t ctx_u; // h2o ctx
@ -1468,7 +1459,7 @@ _http_serv_start(u3_http* htp_u)
INADDR_ANY; INADDR_ANY;
if ( 0 != u3_Host.ops_u.bin_c && c3n == htp_u->lop ) { if ( 0 != u3_Host.ops_u.bin_c && c3n == htp_u->lop ) {
inet_aton(u3_Host.ops_u.bin_c, &adr_u.sin_addr); inet_pton(AF_INET, u3_Host.ops_u.bin_c, &adr_u.sin_addr);
} }
uv_tcp_init(u3L, &htp_u->wax_u); uv_tcp_init(u3L, &htp_u->wax_u);
@ -1622,11 +1613,12 @@ _http_write_ports_file(u3_httd* htd_u, c3_c *pax_c)
u3_http* htp_u = htd_u->htp_u; u3_http* htp_u = htd_u->htp_u;
c3_c temp[32];
while ( 0 != htp_u ) { while ( 0 != htp_u ) {
if ( 0 < htp_u->por_s ) { if ( 0 < htp_u->por_s ) {
dprintf(por_i, "%u %s %s\n", htp_u->por_s, u3_write_fd(por_i, temp, snprintf(temp, 32, "%u %s %s\n", htp_u->por_s,
(c3y == htp_u->sec) ? "secure" : "insecure", (c3y == htp_u->sec) ? "secure" : "insecure",
(c3y == htp_u->lop) ? "loopback" : "public"); (c3y == htp_u->lop) ? "loopback" : "public"));
} }
htp_u = htp_u->nex_u; htp_u = htp_u->nex_u;

View File

@ -1,15 +1,6 @@
/* vere/term.c /* vere/term.c
** **
*/ */
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <uv.h>
#include <errno.h>
#include <termios.h>
#include "all.h" #include "all.h"
#include "vere/vere.h" #include "vere/vere.h"
@ -25,12 +16,11 @@ static u3_utty* _term_main();
static void _term_read_cb(uv_stream_t* tcp_u, static void _term_read_cb(uv_stream_t* tcp_u,
ssize_t siz_i, ssize_t siz_i,
const uv_buf_t* buf_u); const uv_buf_t* buf_u);
static c3_i _term_tcsetattr(c3_i, c3_i, const struct termios*);
/* _write(): retry interrupts, continue partial writes, assert errors. /* u3_write_fd(): retry interrupts, continue partial writes, assert errors.
*/ */
static void void
_write(c3_i fid_i, const void* buf_v, size_t len_i) u3_write_fd(c3_i fid_i, const void* buf_v, size_t len_i)
{ {
ssize_t ret_i; ssize_t ret_i;
@ -54,7 +44,7 @@ _write(c3_i fid_i, const void* buf_v, size_t len_i)
// assert on true errors // assert on true errors
// //
// NB: can't call u3l_log here or we would re-enter _write() // NB: can't call u3l_log here or we would re-enter u3_write_fd()
// //
if ( ret_i < 0 ) { if ( ret_i < 0 ) {
fprintf(stderr, "term: write failed %s\r\n", strerror(errno)); fprintf(stderr, "term: write failed %s\r\n", strerror(errno));
@ -133,30 +123,26 @@ _term_close_cb(uv_handle_t* han_t)
void void
u3_term_log_init(void) u3_term_log_init(void)
{ {
u3_utty* uty_u = c3_calloc(sizeof(u3_utty)); u3_utty* uty_u;
if ( c3y == u3_Host.ops_u.tem ) { if ( c3y == u3_Host.ops_u.tem ) {
uty_u = c3_calloc(sizeof(u3_utty));
uty_u->fid_i = 1; uty_u->fid_i = 1;
uv_pipe_init(u3L, &(uty_u->pop_u), 0); uv_pipe_init(u3L, &(uty_u->pin_u.pop_u), 0);
uv_pipe_open(&(uty_u->pop_u), uty_u->fid_i); uv_pipe_init(u3L, &(uty_u->pop_u.pop_u), 0);
uv_pipe_open(&(uty_u->pop_u.pop_u), uty_u->fid_i);
} }
else { else {
// Initialize event processing. Rawdog it. // Initialize event processing. Rawdog it.
// //
{ const c3_c* err_c;
uty_u->fid_i = 0; // stdin, yes we write to it... if ( NULL == (uty_u = u3_ptty_init(u3L, &err_c)) ) {
fprintf(stderr, "vere: unable to initialize terminal (%s)\r\n"
if ( !isatty(uty_u->fid_i) ) { " use -t to disable interactivity\r\n", err_c);
fprintf(stderr, "vere: unable to initialize terminal (not a tty)\r\n"
" use -t to disable interactivity\r\n");
u3_king_bail(); u3_king_bail();
} }
uv_pipe_init(u3L, &(uty_u->pop_u), 0);
uv_pipe_open(&(uty_u->pop_u), uty_u->fid_i);
}
// configure output escape sequences // configure output escape sequences
// //
// our requirements are minimal here, so we bypass terminfo // our requirements are minimal here, so we bypass terminfo
@ -187,33 +173,6 @@ u3_term_log_init(void)
// uty_u->ufo_u.inn.kcub1_u = TERM_LIT_BUF("\033[D"); // terminfo reports "\033OD" // uty_u->ufo_u.inn.kcub1_u = TERM_LIT_BUF("\033[D"); // terminfo reports "\033OD"
// } // }
// Load old terminal state to restore.
//
{
if ( 0 != tcgetattr(uty_u->fid_i, &uty_u->bak_u) ) {
c3_assert(!"init-tcgetattr");
}
if ( -1 == fcntl(uty_u->fid_i, F_GETFL, &uty_u->cug_i) ) {
c3_assert(!"init-fcntl");
}
uty_u->cug_i &= ~O_NONBLOCK; // could fix?
uty_u->nob_i = uty_u->cug_i | O_NONBLOCK; // O_NDELAY on older unix
}
// Construct raw termios configuration.
//
{
uty_u->raw_u = uty_u->bak_u;
uty_u->raw_u.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN);
uty_u->raw_u.c_iflag &= ~(ICRNL | INPCK | ISTRIP);
uty_u->raw_u.c_cflag &= ~(CSIZE | PARENB);
uty_u->raw_u.c_cflag |= CS8;
uty_u->raw_u.c_oflag &= ~(OPOST);
uty_u->raw_u.c_cc[VMIN] = 0;
uty_u->raw_u.c_cc[VTIME] = 0;
}
// Initialize mirror and accumulator state. // Initialize mirror and accumulator state.
// //
{ {
@ -254,19 +213,25 @@ u3_term_log_init(void)
u3_Host.uty_u = uty_u; u3_Host.uty_u = uty_u;
} }
// Disable I/O buffering on terminal streams.
// This is not necessary if output is a tty,
// but helps when output is redirected.
//
{
fflush(stdout);
fflush(stderr);
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
}
// if terminal/tty is enabled // if terminal/tty is enabled
// //
if ( c3n == u3_Host.ops_u.tem ) { if ( c3n == u3_Host.ops_u.tem ) {
// Start raw input. // Start raw input.
// //
{ if ( c3n == uty_u->sta_f(uty_u) ) {
if ( 0 != _term_tcsetattr(uty_u->fid_i, TCSADRAIN, &uty_u->raw_u) ) {
c3_assert(!"init-tcsetattr"); c3_assert(!"init-tcsetattr");
} }
if ( -1 == fcntl(uty_u->fid_i, F_SETFL, uty_u->nob_i) ) {
c3_assert(!"init-fcntl");
}
}
// initialize spinner timeout // initialize spinner timeout
// //
@ -287,42 +252,19 @@ u3_term_log_exit(void)
for ( uty_u = u3_Host.uty_u; uty_u; uty_u = uty_u->nex_u ) { for ( uty_u = u3_Host.uty_u; uty_u; uty_u = uty_u->nex_u ) {
if ( uty_u->fid_i == -1 ) { continue; } if ( uty_u->fid_i == -1 ) { continue; }
if ( 0 != _term_tcsetattr(uty_u->fid_i, TCSADRAIN, &uty_u->bak_u) ) { if ( c3n == uty_u->sto_f(uty_u) ) {
c3_assert(!"exit-tcsetattr"); c3_assert(!"exit-tcsetattr");
} }
if ( -1 == fcntl(uty_u->fid_i, F_SETFL, uty_u->cug_i) ) { u3_write_fd(uty_u->fid_i, "\r\n", 2);
c3_assert(!"exit-fcntl");
}
_write(uty_u->fid_i, "\r\n", 2);
} }
} }
if ( u3_Host.uty_u ) { if ( u3_Host.uty_u ) {
uv_close((uv_handle_t*)&u3_Host.uty_u->pin_u, 0);
uv_close((uv_handle_t*)&u3_Host.uty_u->pop_u, 0); uv_close((uv_handle_t*)&u3_Host.uty_u->pop_u, 0);
} }
} }
/* _term_tcsetattr(): tcsetattr w/retry on EINTR.
*/
static c3_i
_term_tcsetattr(c3_i fil_i, c3_i act_i, const struct termios* tms_u)
{
c3_i ret_i = 0;
c3_w len_w = 0;
do {
// abort pathological retry loop
//
if ( 100 == ++len_w ) {
fprintf(stderr, "term: tcsetattr loop: %s\r\n", strerror(errno));
return -1;
}
ret_i = tcsetattr(fil_i, act_i, tms_u);
} while ( (-1 == ret_i) && (EINTR == errno) );
return ret_i;
}
/* _term_it_write_cb(): general write callback. /* _term_it_write_cb(): general write callback.
*/ */
static void static void
@ -780,7 +722,7 @@ _term_io_suck_char(u3_utty* uty_u, c3_y cay_y)
else if ( 8 == cay_y || 127 == cay_y ) { else if ( 8 == cay_y || 127 == cay_y ) {
_term_io_belt(uty_u, u3nc(c3__bac, u3_nul)); _term_io_belt(uty_u, u3nc(c3__bac, u3_nul));
} }
else if ( 13 == cay_y ) { else if ( 13 == cay_y || 10 == cay_y ) {
_term_io_belt(uty_u, u3nc(c3__ret, u3_nul)); _term_io_belt(uty_u, u3nc(c3__ret, u3_nul));
} }
#if 0 #if 0
@ -926,11 +868,7 @@ _term_spin_step(u3_utty* uty_u)
// //
{ {
uv_buf_t lef_u = uty_u->ufo_u.out.cub1_u; uv_buf_t lef_u = uty_u->ufo_u.out.cub1_u;
c3_i fid_i; c3_i fid_i = uty_u->fid_i;
if ( uv_fileno((uv_handle_t*)&uty_u->pop_u, &fid_i) ) {
return;
}
// One-time cursor backoff. // One-time cursor backoff.
// //
@ -1071,14 +1009,9 @@ u3_term_get_blew(c3_l tid_l)
u3_utty* uty_u = _term_ef_get(tid_l); u3_utty* uty_u = _term_ef_get(tid_l);
c3_l col_l, row_l; c3_l col_l, row_l;
struct winsize siz_u; if ( (c3y == u3_Host.ops_u.tem) || !uty_u ||
if ( (c3n == u3_Host.ops_u.tem) && (c3y != uty_u->wsz_f(uty_u, &col_l, &row_l)) )
uty_u && (0 == ioctl(uty_u->fid_i, TIOCGWINSZ, &siz_u)) )
{ {
col_l = siz_u.ws_col;
row_l = siz_u.ws_row;
}
else {
col_l = 80; col_l = 80;
row_l = 24; row_l = 24;
} }
@ -1460,33 +1393,19 @@ u3_term_io_hija(void)
} }
else { else {
if ( c3n == u3_Host.ops_u.tem ) { if ( c3n == u3_Host.ops_u.tem ) {
if ( 0 != _term_tcsetattr(1, TCSADRAIN, &uty_u->bak_u) ) { if ( c3y != uty_u->hij_f(uty_u) ) {
perror("hija-tcsetattr-1");
c3_assert(!"hija-tcsetattr"); c3_assert(!"hija-tcsetattr");
} }
if ( -1 == fcntl(1, F_SETFL, uty_u->cug_i) ) { u3_write_fd(uty_u->fid_i, "\r", 1);
perror("hija-fcntl-1");
c3_assert(!"hija-fcntl");
}
if ( 0 != _term_tcsetattr(0, TCSADRAIN, &uty_u->bak_u) ) {
perror("hija-tcsetattr-0");
c3_assert(!"hija-tcsetattr");
}
if ( -1 == fcntl(0, F_SETFL, uty_u->cug_i) ) {
perror("hija-fcntl-0");
c3_assert(!"hija-fcntl");
}
_write(uty_u->fid_i, "\r", 1);
{ {
uv_buf_t* buf_u = &uty_u->ufo_u.out.el_u; uv_buf_t* buf_u = &uty_u->ufo_u.out.el_u;
_write(uty_u->fid_i, buf_u->base, buf_u->len); u3_write_fd(uty_u->fid_i, buf_u->base, buf_u->len);
}
}
} }
} }
return stdout; return stdout;
} }
}
else return stdout;
}
/* u3_term_io_loja(): release console from fprintf. /* u3_term_io_loja(): release console from fprintf.
*/ */
@ -1505,24 +1424,10 @@ u3_term_io_loja(int x)
else { else {
if ( c3y == u3_Host.ops_u.tem ) { if ( c3y == u3_Host.ops_u.tem ) {
fflush(stdout); fflush(stdout);
} } else {
else { if ( c3y != uty_u->loj_f(uty_u) ) {
if ( 0 != _term_tcsetattr(1, TCSADRAIN, &uty_u->raw_u) ) {
perror("loja-tcsetattr-1");
c3_assert(!"loja-tcsetattr"); c3_assert(!"loja-tcsetattr");
} }
if ( -1 == fcntl(1, F_SETFL, uty_u->nob_i) ) {
perror("hija-fcntl-1");
c3_assert(!"loja-fcntl");
}
if ( 0 != _term_tcsetattr(0, TCSADRAIN, &uty_u->raw_u) ) {
perror("loja-tcsetattr-0");
c3_assert(!"loja-tcsetattr");
}
if ( -1 == fcntl(0, F_SETFL, uty_u->nob_i) ) {
perror("hija-fcntl-0");
c3_assert(!"loja-fcntl");
}
_term_it_refresh_line(uty_u); _term_it_refresh_line(uty_u);
} }
} }
@ -1599,7 +1504,7 @@ _term_io_talk(u3_auto* car_u)
if ( c3n == u3_Host.ops_u.tem ) { if ( c3n == u3_Host.ops_u.tem ) {
u3_utty* uty_u = _term_main(); u3_utty* uty_u = _term_main();
uv_read_start((uv_stream_t*)&(uty_u->pop_u), uv_read_start((uv_stream_t*)&(uty_u->pin_u),
_term_alloc, _term_alloc,
_term_read_cb); _term_read_cb);
} }
@ -1760,11 +1665,11 @@ _term_io_exit(u3_auto* car_u)
{ {
u3_utty* uty_u = _term_main(); u3_utty* uty_u = _term_main();
if ( c3n == u3_Host.ops_u.tem ) {
// NB, closed in u3_term_log_exit() // NB, closed in u3_term_log_exit()
// //
uv_read_stop((uv_stream_t*)&(uty_u->pop_u)); uv_read_stop((uv_stream_t*)&(uty_u->pin_u));
if ( c3n == u3_Host.ops_u.tem ) {
uv_timer_t* han_u = &(uty_u->tat_u.sun_u.tim_u); uv_timer_t* han_u = &(uty_u->tat_u.sun_u.tim_u);
han_u->data = car_u; han_u->data = car_u;

View File

@ -2,15 +2,7 @@
** **
*/ */
#include "all.h" #include "all.h"
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <dirent.h>
#include <uv.h>
#include <errno.h>
#include <libgen.h>
#include <ftw.h> #include <ftw.h>
#include "vere/vere.h" #include "vere/vere.h"
struct _u3_umon; struct _u3_umon;

View File

@ -2,13 +2,11 @@
** **
** the main loop of the daemon process ** the main loop of the daemon process
*/ */
#include <curl/curl.h>
#include <unistd.h>
#include <uv.h>
#include "all.h" #include "all.h"
#include "vere/vere.h" #include "vere/vere.h"
#include "ur/ur.h" #include "ur/ur.h"
#include <curl/curl.h>
#include <uv.h>
#include "ivory.h" #include "ivory.h"
@ -217,8 +215,10 @@ _king_pier(u3_noun pier)
** XX deduplicate with dawn.c ** XX deduplicate with dawn.c
*/ */
static size_t static size_t
_king_curl_alloc(void* dat_v, size_t uni_t, size_t mem_t, uv_buf_t* buf_u) _king_curl_alloc(void* dat_v, size_t uni_t, size_t mem_t, void* buf_v)
{ {
uv_buf_t* buf_u = buf_v;
size_t siz_t = uni_t * mem_t; size_t siz_t = uni_t * mem_t;
buf_u->base = c3_realloc(buf_u->base, 1 + siz_t + buf_u->len); buf_u->base = c3_realloc(buf_u->base, 1 + siz_t + buf_u->len);
@ -246,7 +246,7 @@ _king_get_atom(c3_c* url_c)
exit(1); exit(1);
} }
curl_easy_setopt(curl, CURLOPT_CAINFO, u3K.certs_c); u3K.ssl_curl_f(curl);
curl_easy_setopt(curl, CURLOPT_URL, url_c); curl_easy_setopt(curl, CURLOPT_URL, url_c);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _king_curl_alloc); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _king_curl_alloc);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&buf_u); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&buf_u);
@ -546,7 +546,7 @@ _king_sign_init(void)
// handle SIGINFO (if available) // handle SIGINFO (if available)
// //
#ifndef U3_OS_linux #ifdef SIGINFO
{ {
u3_usig* sig_u; u3_usig* sig_u;
@ -592,6 +592,10 @@ _king_sign_cb(uv_signal_t* sil_u, c3_i num_i)
case SIGINT: { case SIGINT: {
u3l_log("\r\ninterrupt\r\n"); u3l_log("\r\ninterrupt\r\n");
u3_term_ef_ctlc(); u3_term_ef_ctlc();
#if defined(U3_OS_mingw)
PulseEvent(u3_Host.cev_u);
#endif
break; break;
} }
@ -602,7 +606,7 @@ _king_sign_cb(uv_signal_t* sil_u, c3_i num_i)
// fallthru if defined // fallthru if defined
// //
#ifndef U3_OS_linux #ifdef SIGINFO
case SIGINFO: case SIGINFO:
#endif #endif
case SIGUSR1: { case SIGUSR1: {
@ -679,7 +683,6 @@ _king_loop_init()
void void
_king_loop_exit() _king_loop_exit()
{ {
unlink(u3K.certs_c);
} }
static void static void
@ -752,12 +755,14 @@ u3_king_commence()
u3C.sign_move_f = _king_sign_move; u3C.sign_move_f = _king_sign_move;
// Ignore SIGPIPE signals. // Ignore SIGPIPE signals.
#ifndef U3_OS_mingw
{ {
struct sigaction sig_s = {{0}}; struct sigaction sig_s = {{0}};
sigemptyset(&(sig_s.sa_mask)); sigemptyset(&(sig_s.sa_mask));
sig_s.sa_handler = SIG_IGN; sig_s.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &sig_s, 0); sigaction(SIGPIPE, &sig_s, 0);
} }
#endif
// boot the ivory pill // boot the ivory pill
// //
@ -765,6 +770,7 @@ u3_king_commence()
// disable core dumps (due to lmdb size) // disable core dumps (due to lmdb size)
// //
#ifndef U3_OS_mingw
{ {
struct rlimit rlm; struct rlimit rlm;
@ -776,6 +782,7 @@ u3_king_commence()
exit(1); exit(1);
} }
} }
#endif
// run the loop // run the loop
// //

View File

@ -1,21 +1,5 @@
/* vere/lord.c /* vere/lord.c
*/ */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <setjmp.h>
#include <gmp.h>
#include <sigsegv.h>
#include <stdint.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <uv.h>
#include <errno.h>
#include "all.h" #include "all.h"
#include "vere/vere.h" #include "vere/vere.h"
#include "ur/hashcons.h" #include "ur/hashcons.h"
@ -157,6 +141,8 @@ _lord_stop(u3_lord* god_u)
u3_newt_moat_stop(&god_u->out_u, _lord_stop_cb); u3_newt_moat_stop(&god_u->out_u, _lord_stop_cb);
u3_newt_mojo_stop(&god_u->inn_u, _lord_bail_noop); u3_newt_mojo_stop(&god_u->inn_u, _lord_bail_noop);
uv_read_stop((uv_stream_t*)&(god_u->err_u));
uv_close((uv_handle_t*)&god_u->cub_u, 0); uv_close((uv_handle_t*)&god_u->cub_u, 0);
#if defined(LORD_TRACE_JAM) || defined(LORD_TRACE_CUE) #if defined(LORD_TRACE_JAM) || defined(LORD_TRACE_CUE)
@ -1044,6 +1030,42 @@ u3_lord_halt(u3_lord* god_u)
_lord_stop(god_u); _lord_stop(god_u);
} }
/* _lord_serf_err_alloc(): libuv buffer allocator.
*/
static void
_lord_serf_err_alloc(uv_handle_t* had_u, size_t len_i, uv_buf_t* buf)
{
// error/info messages as a rule don't exceed one line
//
*buf = uv_buf_init(c3_malloc(80), 80);
}
/* _lord_on_serf_err_cb(): subprocess stderr callback.
*/
static void
_lord_on_serf_err_cb(uv_stream_t* pyp_u,
ssize_t siz_i,
const uv_buf_t* buf_u)
{
if ( siz_i >= 0 ) {
// serf used to write to 2 directly
// this can't be any worse than that
//
u3_write_fd(2, buf_u->base, siz_i);
} else {
uv_read_stop(pyp_u);
if ( siz_i != UV_EOF ) {
u3l_log("lord: serf stderr: %s\r\n", uv_strerror(siz_i));
}
}
if ( buf_u->base != NULL ) {
c3_free(buf_u->base);
}
}
/* _lord_on_serf_exit(): handle subprocess exit. /* _lord_on_serf_exit(): handle subprocess exit.
*/ */
static void static void
@ -1123,6 +1145,7 @@ u3_lord_init(c3_c* pax_c, c3_w wag_w, c3_d key_d[4], u3_lord_cb cb_u)
c3_c key_c[256]; c3_c key_c[256];
c3_c wag_c[11]; c3_c wag_c[11];
c3_c hap_c[11]; c3_c hap_c[11];
c3_c cev_c[11];
c3_i err_i; c3_i err_i;
sprintf(key_c, "%" PRIx64 ":%" PRIx64 ":%" PRIx64 ":%" PRIx64 "", sprintf(key_c, "%" PRIx64 ":%" PRIx64 ":%" PRIx64 ":%" PRIx64 "",
@ -1151,11 +1174,18 @@ u3_lord_init(c3_c* pax_c, c3_w wag_w, c3_d key_d[4], u3_lord_cb cb_u)
arg_c[6] = "0"; arg_c[6] = "0";
} }
#if defined(U3_OS_mingw)
sprintf(cev_c, "%u", u3_Host.cev_u);
arg_c[7] = cev_c;
arg_c[8] = 0;
#else
arg_c[7] = 0; arg_c[7] = 0;
#endif
uv_pipe_init(u3L, &god_u->inn_u.pyp_u, 0); uv_pipe_init(u3L, &god_u->inn_u.pyp_u, 0);
uv_timer_init(u3L, &god_u->out_u.tim_u); uv_timer_init(u3L, &god_u->out_u.tim_u);
uv_pipe_init(u3L, &god_u->out_u.pyp_u, 0); uv_pipe_init(u3L, &god_u->out_u.pyp_u, 0);
uv_pipe_init(u3L, &god_u->err_u, 0);
god_u->cod_u[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE; god_u->cod_u[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
god_u->cod_u[0].data.stream = (uv_stream_t *)&god_u->inn_u; god_u->cod_u[0].data.stream = (uv_stream_t *)&god_u->inn_u;
@ -1163,12 +1193,14 @@ u3_lord_init(c3_c* pax_c, c3_w wag_w, c3_d key_d[4], u3_lord_cb cb_u)
god_u->cod_u[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; god_u->cod_u[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
god_u->cod_u[1].data.stream = (uv_stream_t *)&god_u->out_u; god_u->cod_u[1].data.stream = (uv_stream_t *)&god_u->out_u;
god_u->cod_u[2].flags = UV_INHERIT_FD; god_u->cod_u[2].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
god_u->cod_u[2].data.fd = 2; god_u->cod_u[2].data.stream = (uv_stream_t *)&god_u->err_u;
god_u->ops_u.stdio = god_u->cod_u; god_u->ops_u.stdio = god_u->cod_u;
god_u->ops_u.stdio_count = 3; god_u->ops_u.stdio_count = 3;
// if any fds are inherited, libuv ignores UV_PROCESS_WINDOWS_HIDE*
god_u->ops_u.flags = UV_PROCESS_WINDOWS_HIDE;
god_u->ops_u.exit_cb = _lord_on_serf_exit; god_u->ops_u.exit_cb = _lord_on_serf_exit;
god_u->ops_u.file = arg_c[0]; god_u->ops_u.file = arg_c[0];
god_u->ops_u.args = arg_c; god_u->ops_u.args = arg_c;
@ -1178,6 +1210,8 @@ u3_lord_init(c3_c* pax_c, c3_w wag_w, c3_d key_d[4], u3_lord_cb cb_u)
return 0; return 0;
} }
uv_read_start((uv_stream_t *)&god_u->err_u, _lord_serf_err_alloc, _lord_on_serf_err_cb);
} }
#if defined(LORD_TRACE_JAM) || defined(LORD_TRACE_CUE) #if defined(LORD_TRACE_JAM) || defined(LORD_TRACE_CUE)

View File

@ -9,22 +9,6 @@
** the implementation is relatively inefficient and could ** the implementation is relatively inefficient and could
** lose a few copies, mallocs, etc. ** lose a few copies, mallocs, etc.
*/ */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <setjmp.h>
#include <gmp.h>
#include <sigsegv.h>
#include <stdint.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <uv.h>
#include <errno.h>
#include "all.h" #include "all.h"
#include "vere/vere.h" #include "vere/vere.h"

View File

@ -1,26 +1,9 @@
/* vere/pier.c /* vere/pier.c
*/ */
#include <ent.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <setjmp.h>
#include <gmp.h>
#include <sigsegv.h>
#include <stdint.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <uv.h>
#include <errno.h>
#include "all.h" #include "all.h"
#include "vere/vere.h" #include "vere/vere.h"
#include "vere/db/lmdb.h"
#include <vere/db/lmdb.h> #include <ent.h>
#define PIER_READ_BATCH 1000ULL #define PIER_READ_BATCH 1000ULL
#define PIER_PLAY_BATCH 500ULL #define PIER_PLAY_BATCH 500ULL

View File

@ -1,13 +1,6 @@
/* vere/save.c /* vere/save.c
** **
*/ */
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <termios.h>
#include <uv.h>
#include "all.h" #include "all.h"
#include "vere/vere.h" #include "vere/vere.h"
@ -20,6 +13,7 @@ _save_time_cb(uv_timer_t* tim_u)
u3_pier_save(pir_u); u3_pier_save(pir_u);
} }
#if 0
/* u3_save_ef_chld(): report save termination. /* u3_save_ef_chld(): report save termination.
*/ */
void void
@ -41,6 +35,7 @@ u3_save_ef_chld(u3_pier *pir_u)
} }
sav_u->pid_w = 0; sav_u->pid_w = 0;
} }
#endif
/* u3_save_io_init(): initialize autosave. /* u3_save_io_init(): initialize autosave.
*/ */

View File

@ -1,12 +1,6 @@
/* vere/time.c /* vere/time.c
** **
*/ */
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <dirent.h>
#include <uv.h>
#include "all.h" #include "all.h"
#include "vere/vere.h" #include "vere/vere.h"
@ -104,7 +98,7 @@ u3_time_in_ts(struct timespec* tim_ts)
return u3_time_in_tv(&tim_tv); return u3_time_in_tv(&tim_tv);
} }
#if defined(U3_OS_linux) #if defined(U3_OS_linux) || defined(U3_OS_mingw)
/* u3_time_t_in_ts(): urbit time from time_t. /* u3_time_t_in_ts(): urbit time from time_t.
*/ */
u3_atom u3_atom
@ -117,7 +111,7 @@ u3_time_t_in_ts(time_t tim)
return u3_time_in_tv(&tim_tv); return u3_time_in_tv(&tim_tv);
} }
#endif // defined(U3_OS_linux) #endif // defined(U3_OS_linux) || defined(U3_OS_mingw)
/* u3_time_out_ts(): struct timespec from urbit time. /* u3_time_out_ts(): struct timespec from urbit time.
*/ */

View File

@ -1,13 +1,6 @@
/* vere/walk.c /* vere/walk.c
** **
*/ */
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <dirent.h>
#include <uv.h>
#include <errno.h>
#include "all.h" #include "all.h"
#include "vere/vere.h" #include "vere/vere.h"

View File

@ -1,21 +1,5 @@
/* vere/ward.c /* vere/ward.c
*/ */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <setjmp.h>
#include <gmp.h>
#include <sigsegv.h>
#include <stdint.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <uv.h>
#include <errno.h>
#include "all.h" #include "all.h"
#include "vere/vere.h" #include "vere/vere.h"

Some files were not shown because too many files have changed in this diff Show More