mirror of
https://github.com/urbit/shrub.git
synced 2024-12-20 09:21:42 +03:00
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:
commit
07e2a6ba0d
21
.github/workflows/build.yml
vendored
21
.github/workflows/build.yml
vendored
@ -116,3 +116,24 @@ jobs:
|
||||
- run: nix-build -A hs.urbit-king.components.exes.urbit-king --arg enableStatic true
|
||||
- run: nix-build -A hs-checks
|
||||
- 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
1
.gitignore
vendored
@ -54,6 +54,7 @@ release/
|
||||
dist/
|
||||
out/
|
||||
work/
|
||||
pkg/*/*.a
|
||||
*.o
|
||||
|
||||
# Landscape Dev
|
||||
|
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d7b7cf24e56ab078cf1dcb82e4e7744f188c5221c08772d6cfb15f59ce81aaa5
|
||||
size 11198219
|
||||
oid sha256:88acd8aa1aae3d11579ada954b6e0b06c940de7856d22017cc1a1442de97fcf3
|
||||
size 13650762
|
||||
|
90
nix/sources-pmnsh.json
Normal file
90
nix/sources-pmnsh.json
Normal 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)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -3,18 +3,26 @@
|
||||
"branch": "master",
|
||||
"description": "With argon2u. Based off https://github.com/P-H-C/phc-winner-argon2",
|
||||
"homepage": "",
|
||||
"pmnsh": {
|
||||
"include": ["include", "src/blake2"],
|
||||
"make": "libargon2.a"
|
||||
},
|
||||
"owner": "urbit",
|
||||
"repo": "argon2",
|
||||
"rev": "4da94a611ee62bad87ab2b131ffda3bcc0723d9c",
|
||||
"sha256": "0bqq1hg367l4jkb6cqhxlblpvdbwz3l586qsfakwzfd9wdvnm3yc",
|
||||
"rev": "a4c1e3f7138c2e577376beb99f964cf71e1c8b1b",
|
||||
"sha256": "1j8a15fx2kn5aa3scmb5qnsfk627kfvsq5ppz9j0pv2d1xck527x",
|
||||
"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"
|
||||
},
|
||||
"ed25519": {
|
||||
"branch": "master",
|
||||
"description": "Submodule included by Urbit",
|
||||
"homepage": null,
|
||||
"pmnsh": {
|
||||
"strip": 1,
|
||||
"make": "all"
|
||||
},
|
||||
"owner": "urbit",
|
||||
"repo": "ed25519",
|
||||
"rev": "76385f2ebbbc9580a9c236952d68d11d73a6135c",
|
||||
@ -24,15 +32,25 @@
|
||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||
},
|
||||
"h2o": {
|
||||
"branch": "v2.2.x",
|
||||
"branch": "master",
|
||||
"description": "H2O - the optimized HTTP/1, HTTP/2, HTTP/3 server",
|
||||
"homepage": "https://h2o.examp1e.net",
|
||||
"pmnsh": {
|
||||
"include": "include",
|
||||
"prepare": "cmake .",
|
||||
"make": "libh2o",
|
||||
"compat": {
|
||||
"mingw": {
|
||||
"prepare": "cmake -G\"MSYS Makefiles\" ."
|
||||
}
|
||||
}
|
||||
},
|
||||
"owner": "h2o",
|
||||
"repo": "h2o",
|
||||
"rev": "7359e98d78d018a35f5da7523feac69f64eddb4b",
|
||||
"rev": "v2.2.6",
|
||||
"sha256": "0qni676wqvxx0sl0pw9j0ph7zf2krrzqc1zwj73mgpdnsr8rsib7",
|
||||
"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"
|
||||
},
|
||||
"hackage.nix": {
|
||||
@ -63,6 +81,9 @@
|
||||
"branch": "master",
|
||||
"description": null,
|
||||
"homepage": null,
|
||||
"pmnsh": {
|
||||
"make": "libscrypt.a CFLAGS_EXTRA=-ffast-math"
|
||||
},
|
||||
"owner": "urbit",
|
||||
"repo": "libscrypt",
|
||||
"rev": "029693ff1cbe4f69d3a2da87d0f4f034f92cc0c2",
|
||||
@ -75,6 +96,9 @@
|
||||
"branch": "master",
|
||||
"description": null,
|
||||
"homepage": null,
|
||||
"pmnsh": {
|
||||
"make": "static"
|
||||
},
|
||||
"owner": "urbit",
|
||||
"repo": "murmur3",
|
||||
"rev": "71a75d57ca4e7ca0f7fc2fd84abd93595b0624ca",
|
||||
@ -111,6 +135,19 @@
|
||||
"branch": "master",
|
||||
"description": 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",
|
||||
"repo": "berkeley-softfloat-3",
|
||||
"rev": "ec4c7e31b32e07aad80e52f65ff46ac6d6aad986",
|
||||
|
@ -875,7 +875,7 @@
|
||||
%ge (dy-run-generator (dy-cage p.p.p.bil) q.p.bil)
|
||||
%sa
|
||||
=+ .^(=dais:clay cb+(en-beam he-beak /[p.bil]))
|
||||
(dy-hand p.bil bunt:dais)
|
||||
(dy-hand p.bil *vale:dais)
|
||||
::
|
||||
%as
|
||||
=/ cag=cage (dy-cage p.q.bil)
|
||||
|
@ -1,6 +1,5 @@
|
||||
:: graph-store [landscape]
|
||||
::
|
||||
::
|
||||
/+ store=graph-store, sigs=signatures, res=resource, default-agent, dbug, verb
|
||||
~% %graph-store-top ..part ~
|
||||
|%
|
||||
@ -724,7 +723,7 @@
|
||||
:+ %add-nodes
|
||||
[ship term]
|
||||
%- ~(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]
|
||||
^- [index:store node:store]
|
||||
[~[atom] node]
|
||||
@ -775,7 +774,7 @@
|
||||
%+ turn
|
||||
=- ?.(older (slag (safe-sub (lent -) count) -) (scag count -))
|
||||
%- tap:orm
|
||||
%+ subset:orm u.graph
|
||||
%+ lot:orm u.graph
|
||||
=/ idx
|
||||
(snag (dec (lent index)) index)
|
||||
?:(older [`idx ~] [~ `idx])
|
||||
@ -826,7 +825,7 @@
|
||||
:+ %add-nodes
|
||||
[ship term]
|
||||
%- ~(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]
|
||||
^- [index:store node:store]
|
||||
[(snoc index atom) node]
|
||||
@ -840,7 +839,7 @@
|
||||
=/ update-log=(unit update-log:store) (~(get by update-logs) [ship term])
|
||||
?~ update-log [~ ~]
|
||||
:: 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 @ @ ~]
|
||||
=/ =ship (slav %p i.t.t.path)
|
||||
@ -858,7 +857,7 @@
|
||||
%+ biff m-update-log
|
||||
|= =update-log:store
|
||||
=/ result=(unit [=time =update:store])
|
||||
(peek:orm-log:store update-log)
|
||||
(pry:orm-log:store update-log)
|
||||
(bind result |=([=time update:store] time))
|
||||
==
|
||||
::
|
||||
|
@ -256,7 +256,7 @@
|
||||
=/ graph=graph:graph-store :: graph in subscription is bunted
|
||||
(get-graph-mop:gra rid)
|
||||
=/ 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)
|
||||
(peek-association:met %graph rid)
|
||||
=^ cards state
|
||||
|
15
pkg/arvo/gen/hood/fuse.hoon
Normal file
15
pkg/arvo/gen/hood/fuse.hoon
Normal 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
|
8
pkg/arvo/gen/hood/fuse/help.txt
Normal file
8
pkg/arvo/gen/hood/fuse/help.txt
Normal 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.
|
@ -1,5 +1,5 @@
|
||||
/- gr=group, md=metadata-store, ga=graph-store
|
||||
/+ re=resource
|
||||
/+ re=resource, graph=graph-store
|
||||
!:
|
||||
:- %say
|
||||
|= $: [now=@da eny=@uvJ =beak]
|
||||
@ -86,9 +86,9 @@
|
||||
%+ scry update:ga
|
||||
[%x %graph-store /graph/(scot %p entity.r)/[name.r]/noun]
|
||||
?> ?=(%add-graph -.q.upd)
|
||||
=/ mo ((ordered-map atom node:ga) gth)
|
||||
=* mo orm:graph
|
||||
=/ 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)
|
||||
%~ wyt in
|
||||
%+ roll week
|
||||
|
@ -55,6 +55,12 @@
|
||||
cas=case ::
|
||||
gim=?(%auto germ) ::
|
||||
==
|
||||
+$ kiln-fuse
|
||||
$@ ~
|
||||
$: syd=desk
|
||||
bas=beak
|
||||
con=(list [beak germ])
|
||||
==
|
||||
--
|
||||
|= [bowl:gall state]
|
||||
?> =(src our)
|
||||
@ -381,6 +387,11 @@
|
||||
?~ +< abet
|
||||
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
|
||||
|= a=@tas
|
||||
abet:(emit %pass /cancel %arvo %c [%drop a])
|
||||
@ -430,6 +441,7 @@
|
||||
%kiln-info =;(f (f !<(_+<.f vase)) poke-info)
|
||||
%kiln-label =;(f (f !<(_+<.f vase)) poke-label)
|
||||
%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-ota =;(f (f !<(_+<.f vase)) poke:update)
|
||||
%kiln-ota-info =;(f (f !<(_+<.f vase)) poke-ota-info)
|
||||
@ -489,6 +501,8 @@
|
||||
++ take |=(way=wire ?>(?=([@ ~] way) (work i.way))) :: general handler
|
||||
++ take-mere ::
|
||||
|= [way=wire are=(each (set path) (pair term tang))]
|
||||
?. ?=([@ ~] way)
|
||||
abet
|
||||
abet:abet:(mere:(take way) are)
|
||||
::
|
||||
++ take-coup-fancy ::
|
||||
|
@ -21,7 +21,10 @@
|
||||
(most ;~(plug com gaw) taut-rule)
|
||||
::
|
||||
%+ 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
|
||||
;~(plug sym ;~(pfix gap ;~(pfix cen sym)))
|
||||
@ -37,7 +40,7 @@
|
||||
;~ (glue gap)
|
||||
sym
|
||||
;~(pfix cen sym)
|
||||
;~(pfix fas (more fas urs:ab))
|
||||
stap
|
||||
==
|
||||
::
|
||||
%+ stag %tssg
|
||||
|
@ -490,7 +490,7 @@
|
||||
=/ m (strand ,vase)
|
||||
^- form:m
|
||||
;< =riot:clay bind:m
|
||||
(warp ship desk ~ %sing %b case /[mak])
|
||||
(warp ship desk ~ %sing %e case /[mak])
|
||||
?~ riot
|
||||
(strand-fail %build-nave >arg< ~)
|
||||
?> =(%nave p.r.u.riot)
|
||||
|
@ -33,7 +33,7 @@
|
||||
++ grab
|
||||
|%
|
||||
++ noun
|
||||
|= p=*
|
||||
|: p=`*`%*(. *indexed-post index.p [0 ~])
|
||||
=/ ip ;;(indexed-post p)
|
||||
?> ?=([@ ~] index.p.ip)
|
||||
ip
|
||||
|
@ -49,7 +49,7 @@
|
||||
++ grab
|
||||
|%
|
||||
++ noun
|
||||
|= p=*
|
||||
|: p=`*`%*(. *indexed-post index.p [0 0 ~])
|
||||
=/ ip ;;(indexed-post p)
|
||||
?+ index.p.ip ~|(index+index.p.ip !!)
|
||||
:: top-level link post; title and url
|
||||
|
@ -43,7 +43,7 @@
|
||||
:: +noun: validate post
|
||||
::
|
||||
++ noun
|
||||
|= p=*
|
||||
|: p=`*`%*(. *indexed-post contents.p [%text '']~)
|
||||
=/ ip ;;(indexed-post p)
|
||||
?> ?=(^ contents.p.ip)
|
||||
ip
|
||||
|
@ -58,7 +58,7 @@
|
||||
:: +noun: validate publish note
|
||||
::
|
||||
++ noun
|
||||
|= p=*
|
||||
|: p=`*`%*(. *indexed-post index.p [0 ~])
|
||||
=/ ip ;;(indexed-post p)
|
||||
?+ index.p.ip !!
|
||||
:: top level post must have no content
|
||||
|
@ -5452,12 +5452,14 @@
|
||||
:::: 4k: atom printing
|
||||
::
|
||||
++ co
|
||||
!:
|
||||
~% %co ..co ~
|
||||
=< |_ lot=coin
|
||||
++ rear |=(rom=tape rend(rep rom))
|
||||
++ rent `@ta`(rap 3 rend)
|
||||
++ rent ~+ `@ta`(rap 3 rend)
|
||||
++ rend
|
||||
^- tape
|
||||
~+
|
||||
?: ?=(%blob -.lot)
|
||||
['~' '0' ((v-co 1) (jam p.lot))]
|
||||
?: ?=(%many -.lot)
|
||||
@ -5602,18 +5604,17 @@
|
||||
|= a=dn
|
||||
?: ?=([%i *] a) (weld ?:(s.a "inf" "-inf") rep)
|
||||
?: ?=([%n *] a) (weld "nan" rep)
|
||||
=/ f=(pair tape @)
|
||||
%. a.a
|
||||
%+ ed-co(rep ~) [10 1]
|
||||
|=([a=? b=@ c=tape] [~(d ne b) ?.(a c ['.' c])])
|
||||
=. e.a (sum:si e.a (sun:si (dec q.f)))
|
||||
=/ res
|
||||
%+ weld p.f
|
||||
?~ e.a
|
||||
rep
|
||||
%+ weld ?:((syn:si e.a) "e" "e-")
|
||||
((d-co 1) (abs:si e.a))
|
||||
?:(s.a res ['-' res])
|
||||
=; rep ?:(s.a rep ['-' rep])
|
||||
=/ f ((d-co 1) a.a)
|
||||
=^ e e.a
|
||||
=/ e=@s (sun:si (lent f))
|
||||
=/ sci :(sum:si e.a e -1)
|
||||
?: (syn:si (dif:si e.a --3)) [--1 sci] :: 12000 -> 12e3 e>+2
|
||||
?: !(syn:si (dif:si sci -2)) [--1 sci] :: 0.001 -> 1e-3 e<-2
|
||||
[(sum:si sci --1) --0] :: 1.234e2 -> '.'@3 -> 123 .4
|
||||
=? rep !=(--0 e.a)
|
||||
:(weld ?:((syn:si e.a) "e" "e-") ((d-co 1) (abs:si e.a)))
|
||||
(weld (ed-co e f) rep)
|
||||
::
|
||||
++ s-co
|
||||
|= esc=(list @) ^- tape
|
||||
@ -5659,20 +5660,13 @@
|
||||
:: - used only for @r* floats
|
||||
::
|
||||
++ ed-co
|
||||
|= [[bas=@ min=@] par=$-([? @ tape] tape)]
|
||||
=| [fir=? cou=@ud]
|
||||
|= hol=@
|
||||
^- [tape @]
|
||||
?: &(=(0 hol) =(0 min))
|
||||
[rep cou]
|
||||
=/ [dar=@ rad=@] (dvr hol bas)
|
||||
%= $
|
||||
min ?:(=(0 min) 0 (dec min))
|
||||
hol dar
|
||||
rep (par &(=(0 dar) !fir) rad rep)
|
||||
fir |
|
||||
cou +(cou)
|
||||
==
|
||||
|= [exp=@s int=tape] ^- tape
|
||||
=/ [pos=? dig=@u] [=(--1 (cmp:si exp --0)) (abs:si exp)]
|
||||
?. pos
|
||||
(into (weld (reap +(dig) '0') int) 1 '.')
|
||||
=/ len (lent int)
|
||||
?: (lth dig len) (into int dig '.')
|
||||
(weld int (reap (sub dig len) '0'))
|
||||
::
|
||||
:: +ox-co: format '.'-separated digit sequences in numeric base
|
||||
::
|
||||
@ -5965,9 +5959,8 @@
|
||||
::
|
||||
++ spat |=(pax=path (crip (spud pax))) :: render path to cord
|
||||
++ spud |=(pax=path ~(ram re (smyt pax))) :: render path to tape
|
||||
++ stab :: parse cord to path
|
||||
=+ fel=;~(pfix fas (more fas urs:ab))
|
||||
|=(zep=@t `path`(rash zep fel))
|
||||
++ stab |=(zep=@t `path`(rash zep stap)) :: parse cord to path
|
||||
++ stap ;~(pfix fas (more fas urs:ab)) :: path parser
|
||||
::
|
||||
:::: 4n: virtualization
|
||||
::
|
||||
@ -6627,7 +6620,7 @@
|
||||
+$ seminoun
|
||||
:: partial noun; blocked subtrees are ~
|
||||
::
|
||||
$~ [[%full ~] ~]
|
||||
$~ [[%full / ~ ~] ~]
|
||||
[mask=stencil data=noun]
|
||||
::
|
||||
:: +stencil: noun knowledge map
|
||||
|
@ -762,6 +762,11 @@
|
||||
her=@p dem=desk cas=case :: source
|
||||
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
|
||||
[%dirk des=desk] :: mark mount dirty
|
||||
[%ogre pot=$@(desk beam)] :: delete mount point
|
||||
@ -928,6 +933,7 @@
|
||||
:: /- sur-file :: surface imports from /sur
|
||||
:: /+ lib-file :: library imports from /lib
|
||||
:: /= 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 %from %to :: imports mark converter from /mar
|
||||
:: /* face %mark /path :: unbuilt file imports, as mark
|
||||
@ -936,6 +942,7 @@
|
||||
$: sur=(list taut)
|
||||
lib=(list taut)
|
||||
raw=(list [face=term =path])
|
||||
raz=(list [face=term =spec =path])
|
||||
maz=(list [face=term =mark])
|
||||
caz=(list [face=term =mars])
|
||||
bar=(list [face=term =mark =path])
|
||||
@ -955,7 +962,6 @@
|
||||
$_
|
||||
^?
|
||||
|%
|
||||
++ bunt *typ
|
||||
++ diff |~([old=typ new=typ] *dif)
|
||||
++ form *mark
|
||||
++ join |~([a=dif b=dif] *(unit (unit dif)))
|
||||
@ -970,7 +976,6 @@
|
||||
+$ dais
|
||||
$_ ^|
|
||||
|_ sam=vase
|
||||
++ bunt sam
|
||||
++ diff |~(new=_sam *vase)
|
||||
++ form *mark
|
||||
++ join |~([a=vase b=vase] *(unit (unit vase)))
|
||||
|
@ -1944,11 +1944,11 @@
|
||||
=/ =bone bone.shut-packet
|
||||
::
|
||||
?: ?=(%& -.meat.shut-packet)
|
||||
=+ ?~ dud ~
|
||||
=+ ?. &(?=(^ dud) msg.veb) ~
|
||||
%. ~
|
||||
%+ slog
|
||||
leaf+"ames: {<her.channel>} fragment crashed {<mote.u.dud>}"
|
||||
?.(msg.veb ~ tang.u.dud)
|
||||
%- slog
|
||||
:_ tang.u.dud
|
||||
leaf+"ames: {<her.channel>} fragment crashed {<mote.u.dud>}"
|
||||
(run-message-sink bone %hear lane shut-packet ?=(~ dud))
|
||||
:: Just try again on error, printing trace
|
||||
::
|
||||
@ -1967,20 +1967,12 @@
|
||||
++ on-memo
|
||||
|= [=bone payload=* valence=?(%plea %boon)]
|
||||
^+ 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))
|
||||
=. 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
|
||||
peer-core
|
||||
:: +dedup-message: replace with any existing copy of this message
|
||||
@ -2535,7 +2527,7 @@
|
||||
++ assert
|
||||
^+ message-pump
|
||||
=/ 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))
|
||||
~| [%strange-current current=current.state key.u.top-live]
|
||||
!!
|
||||
@ -2603,7 +2595,7 @@
|
||||
=| acc=(unit static-fragment)
|
||||
^+ [static-fragment=acc live=live.state]
|
||||
::
|
||||
%^ (traverse:packet-queue _acc) live.state acc
|
||||
%^ (dip:packet-queue _acc) live.state acc
|
||||
|= $: acc=_acc
|
||||
key=live-packet-key
|
||||
val=live-packet-val
|
||||
@ -2681,7 +2673,7 @@
|
||||
=/ acc
|
||||
resends=*(list static-fragment)
|
||||
::
|
||||
%^ (traverse:packet-queue _acc) live.state acc
|
||||
%^ (dip:packet-queue _acc) live.state acc
|
||||
|= $: acc=_acc
|
||||
key=live-packet-key
|
||||
val=live-packet-val
|
||||
@ -2734,7 +2726,7 @@
|
||||
::
|
||||
^+ [acc live=live.state]
|
||||
::
|
||||
%^ (traverse:packet-queue _acc) live.state acc
|
||||
%^ (dip:packet-queue _acc) live.state acc
|
||||
|= $: acc=_acc
|
||||
key=live-packet-key
|
||||
val=live-packet-val
|
||||
@ -2781,7 +2773,7 @@
|
||||
::
|
||||
^+ [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
|
||||
key=live-packet-key
|
||||
val=live-packet-val
|
||||
@ -2804,10 +2796,10 @@
|
||||
::
|
||||
++ set-wake
|
||||
^+ 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)
|
||||
?~ head=(peek:packet-queue live.state)
|
||||
?~ head=(pry:packet-queue live.state)
|
||||
~
|
||||
`(next-expiry:gauge u.head)
|
||||
:: no-op if no change
|
||||
|
@ -186,7 +186,7 @@
|
||||
=* timers timers.state
|
||||
:: 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
|
||||
?~ next-wake
|
||||
event-core
|
||||
@ -351,7 +351,7 @@
|
||||
[%timers %next ~]
|
||||
:^ ~ ~ %noun
|
||||
!> ^- (unit @da)
|
||||
(bind (peek:timer-map timers) head)
|
||||
(bind (pry:timer-map timers) head)
|
||||
::
|
||||
[%timers @ ~]
|
||||
?~ til=(slaw %da i.t.tyl)
|
||||
|
@ -59,6 +59,12 @@
|
||||
::
|
||||
+$ 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.
|
||||
::
|
||||
:: Includes subscriber list, dome (desk content), possible commit state (for
|
||||
@ -69,6 +75,7 @@
|
||||
dom=dome :: desk state
|
||||
per=regs :: read perms per path
|
||||
pew=regs :: write perms per path
|
||||
fiz=melt :: state for mega merges
|
||||
==
|
||||
::
|
||||
:: Desk state.
|
||||
@ -118,11 +125,11 @@
|
||||
:: Ford cache
|
||||
::
|
||||
+$ ford-cache
|
||||
$: files=(map path [res=vase dez=(set path)])
|
||||
naves=(map mark [res=vase dez=(set path)])
|
||||
marks=(map mark [res=dais dez=(set path)])
|
||||
casts=(map mars [res=vase dez=(set path)])
|
||||
tubes=(map mars [res=tube dez=(set path)])
|
||||
$: files=(map path [res=vase dez=(set [dir=? =path])])
|
||||
naves=(map mark [res=vase dez=(set [dir=? =path])])
|
||||
marks=(map mark [res=dais dez=(set [dir=? =path])])
|
||||
casts=(map mars [res=vase dez=(set [dir=? =path])])
|
||||
tubes=(map mars [res=tube dez=(set [dir=? =path])])
|
||||
==
|
||||
:: $reef-cache: built system files
|
||||
::
|
||||
@ -212,6 +219,7 @@
|
||||
dom=dome :: revision state
|
||||
per=regs :: read perms per path
|
||||
pew=regs :: write perms per path
|
||||
fiz=melt :: domestic mega merges
|
||||
== ::
|
||||
::
|
||||
:: Foreign request manager.
|
||||
@ -303,6 +311,7 @@
|
||||
$: %c :: to %clay
|
||||
$> $? %info :: internal edit
|
||||
%merg :: merge desks
|
||||
%fuse :: merge many
|
||||
%pork ::
|
||||
%warp ::
|
||||
%werp ::
|
||||
@ -428,18 +437,23 @@
|
||||
::
|
||||
++ an
|
||||
|_ 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
|
||||
|= =path
|
||||
^- (unit cage)
|
||||
?~ path
|
||||
?~ fil.nak
|
||||
~
|
||||
`q.u.fil.nak
|
||||
?~ kid=(~(get by dir.nak) i.path)
|
||||
~
|
||||
$(nak u.kid, path t.path)
|
||||
?~ nik=(dug path) ~
|
||||
?~ fil.u.nik ~
|
||||
`q.u.fil.u.nik
|
||||
--
|
||||
++ with-face |=([face=@tas =vase] vase(p [%face face p.vase]))
|
||||
++ with-faces
|
||||
@ -472,7 +486,7 @@
|
||||
+$ state
|
||||
$: baked=(map path cage)
|
||||
cache=ford-cache
|
||||
stack=(list (set path))
|
||||
stack=(list (set [dir=? =path]))
|
||||
cycle=(set build)
|
||||
==
|
||||
+$ args
|
||||
@ -493,8 +507,8 @@
|
||||
:: +pop-stack: pop build stack, copying deps downward
|
||||
::
|
||||
++ pop-stack
|
||||
^- [(set path) _stack.nub]
|
||||
=^ top=(set path) stack.nub stack.nub
|
||||
^- [(set [dir=? =path]) _stack.nub]
|
||||
=^ top=(set [dir=? =path]) stack.nub stack.nub
|
||||
=? stack.nub ?=(^ stack.nub)
|
||||
stack.nub(i (~(uni in i.stack.nub) top))
|
||||
[top stack.nub]
|
||||
@ -559,7 +573,6 @@
|
||||
=/ dif diff:deg
|
||||
^- (nave typ dif)
|
||||
|%
|
||||
++ bunt +<.cor
|
||||
++ diff
|
||||
|= [old=typ new=typ]
|
||||
^- dif
|
||||
@ -581,7 +594,6 @@
|
||||
=/ dif _*diff:grad:cor
|
||||
^- (nave:clay typ dif)
|
||||
|%
|
||||
++ bunt +<.cor
|
||||
++ diff |=([old=typ new=typ] (diff:~(grad cor old) new))
|
||||
++ form form:grad:cor
|
||||
++ join
|
||||
@ -622,7 +634,6 @@
|
||||
:_ nub
|
||||
^- dais
|
||||
|_ sam=vase
|
||||
++ bunt (slap nav limb/%bunt)
|
||||
++ diff
|
||||
|= new=vase
|
||||
(slam (slap nav limb/%diff) (slop sam new))
|
||||
@ -649,7 +660,7 @@
|
||||
|= diff=vase
|
||||
(slam (slap nav limb/%pact) (slop sam diff))
|
||||
++ vale
|
||||
|= =noun
|
||||
|: noun=q:(slap nav !,(*hoon *vale))
|
||||
(slam (slap nav limb/%vale) noun/noun)
|
||||
--
|
||||
:: +build-cast: produce gate to convert mark .a to, statically typed
|
||||
@ -805,9 +816,11 @@
|
||||
=^ res=vase nub (run-pile pile)
|
||||
res
|
||||
::
|
||||
++ build-file
|
||||
|= =path
|
||||
++ build-dependency
|
||||
|= dep=(each [dir=path fil=path] path)
|
||||
^- [vase state]
|
||||
=/ =path
|
||||
?:(?=(%| -.dep) p.dep fil.p.dep)
|
||||
~| %error-building^path
|
||||
?^ got=(~(get by files.cache.nub) path)
|
||||
=? stack.nub ?=(^ stack.nub)
|
||||
@ -816,7 +829,9 @@
|
||||
?: (~(has in cycle.nub) file+path)
|
||||
~|(cycle+file+path^stack.nub !!)
|
||||
=. 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)
|
||||
?> =(%hoon p.cag)
|
||||
=/ tex=tape (trip !<(@t q.cag))
|
||||
@ -826,11 +841,42 @@
|
||||
=. files.cache.nub (~(put by files.cache.nub) path [res top])
|
||||
[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
|
||||
|= =pile
|
||||
=^ sut=vase nub (run-tauts bud %sur sur.pile)
|
||||
=^ sut=vase nub (run-tauts sut %lib lib.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-caz sut caz.pile)
|
||||
=^ sut=vase nub (run-bar sut bar.pile)
|
||||
@ -869,7 +915,10 @@
|
||||
(most ;~(plug com gaw) taut-rule)
|
||||
::
|
||||
%+ 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
|
||||
;~(plug sym ;~(pfix gap ;~(pfix cen sym)))
|
||||
@ -885,7 +934,7 @@
|
||||
;~ (glue gap)
|
||||
sym
|
||||
;~(pfix cen sym)
|
||||
;~(pfix fas (more fas urs:ab))
|
||||
;~(pfix stap)
|
||||
==
|
||||
::
|
||||
%+ stag %tssg
|
||||
@ -931,6 +980,30 @@
|
||||
=. p.pin [%face face.i.raw p.pin]
|
||||
$(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
|
||||
|= [sut=vase maz=(list [face=term =mark])]
|
||||
^- [vase state]
|
||||
@ -1043,12 +1116,12 @@
|
||||
~
|
||||
=/ rus rus:(~(gut by hoy.ruf) her *rung)
|
||||
%+ ~(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
|
||||
::
|
||||
:+ ~ `hun.rom.ruf
|
||||
=/ 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 ->+
|
||||
|%
|
||||
@ -1065,7 +1138,7 @@
|
||||
::
|
||||
%= ruf
|
||||
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
|
||||
@ -1256,6 +1329,24 @@
|
||||
=/ =path [%question desk (scot %ud index) ~]
|
||||
(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.
|
||||
::
|
||||
:: If it's a local request, we just put in in `qyx`, setting a timer if it's
|
||||
@ -1275,6 +1366,10 @@
|
||||
=. rave
|
||||
?. ?=([%sing %v *] rave) rave
|
||||
[%many %| [%ud let.dom] case.mood.rave path.mood.rave]
|
||||
::
|
||||
?. (foreign-capable rave)
|
||||
~|([%clay-bad-foreign-request-care rave] !!)
|
||||
::
|
||||
=+ inx=nix.u.ref
|
||||
=. +>+.$
|
||||
=< ?>(?=(^ ref) .)
|
||||
@ -1582,12 +1677,19 @@
|
||||
::
|
||||
++ invalidate
|
||||
|* [key=mold value=mold]
|
||||
|= [cache=(map key [value dez=(set path)]) invalid=(set path)]
|
||||
=/ builds=(list [key value dez=(set path)]) ~(tap by cache)
|
||||
|= [cache=(map key [value dez=(set [dir=? =path])]) invalid=(set path)]
|
||||
=/ builds=(list [key value dez=(set [dir=? =path])])
|
||||
~(tap by cache)
|
||||
|- ^+ cache
|
||||
?~ 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)
|
||||
(~(put by $(builds t.builds)) i.builds)
|
||||
::
|
||||
@ -1962,32 +2064,178 @@
|
||||
=/ =wire /merge/[syd]/(scot %p ali-ship)/[ali-desk]/[germ]
|
||||
(emit hen %pass wire %c %warp ali-ship ali-desk `[%sing %v case /])
|
||||
::
|
||||
++ make-melt
|
||||
|= [bas=beak con=(list [beak germ])]
|
||||
^- melt
|
||||
:+ bas con
|
||||
%- ~(gas by *(map beak (unit dome:clay)))
|
||||
:- [bas *(unit dome:clay)]
|
||||
(turn con |=(a=[beak germ] [-.a *(unit dome:clay)]))
|
||||
::
|
||||
++ start-fuse
|
||||
|= [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
|
||||
~
|
||||
=/ discarded=tang
|
||||
%+ turn
|
||||
~(tap in sto.fiz)
|
||||
|= [k=beak v=(unit dome:clay)]
|
||||
^- tank
|
||||
=/ received=tape ?~(v "missing" "received")
|
||||
leaf+"{<k>} {received}"
|
||||
:_ 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
|
||||
|= result=(each (set path) (pair term tang))
|
||||
^+ ..merge
|
||||
(emit hen %give %mere result)
|
||||
::
|
||||
++ merge
|
||||
|= [=ali=ship =ali=desk =germ =riot]
|
||||
^+ ..merge
|
||||
|^
|
||||
?~ riot
|
||||
(done %| %ali-unavailable >[ali-ship ali-desk germ]< ~)
|
||||
(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-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)
|
||||
?~ let.dom
|
||||
~
|
||||
(~(get by hut.ran) (~(got by hit.dom) let.dom))
|
||||
=/ merge-result (merge-by-germ ali-yaki bob-yaki)
|
||||
?: ?=(%| -.merge-result)
|
||||
(done %| p.merge-result)
|
||||
?~ p.merge-result
|
||||
(done %& ~)
|
||||
=. ..merge (done %& conflicts.u.p.merge-result)
|
||||
(park | new.u.p.merge-result ~ lat.u.p.merge-result)
|
||||
?~ continuation-yaki
|
||||
?~ let.dom
|
||||
~
|
||||
(~(get by hut.ran) (~(got by hit.dom) let.dom))
|
||||
continuation-yaki
|
||||
(merge-by-germ ali-yaki bob-yaki)
|
||||
::
|
||||
++ done
|
||||
|= result=(each (set path) (pair term tang))
|
||||
^+ ..merge
|
||||
(emit hen %give %mere result)
|
||||
::
|
||||
+$ merge-result [conflicts=(set path) new=yoki lat=(map lobe blob)]
|
||||
++ merge-by-germ
|
||||
|= [=ali=yaki bob-yaki=(unit yaki)]
|
||||
^- (each (unit merge-result) [term tang])
|
||||
@ -2005,16 +2253,13 @@
|
||||
?- germ
|
||||
::
|
||||
:: 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
|
||||
:: check to see if ali's commit is in the ancestry of bob's, in
|
||||
:: which case we're done. Otherwise, we create a new commit with
|
||||
:: bob's data plus ali and bob as parents.
|
||||
:: commits are the same, in which case we're done.
|
||||
:: Otherwise, we create a new commit with bob's data plus ali and
|
||||
:: bob as parents.
|
||||
::
|
||||
%only-this
|
||||
?: =(r.ali-yaki r.bob-yaki)
|
||||
&+~
|
||||
?: (~(has in (reachable-takos:ze r.bob-yaki)) r.ali-yaki)
|
||||
&+~
|
||||
:* %& ~
|
||||
conflicts=~
|
||||
new=&+[[r.bob-yaki r.ali-yaki ~] (to-yuki q.bob-yaki)]
|
||||
@ -2042,8 +2287,6 @@
|
||||
%take-this
|
||||
?: =(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)
|
||||
:* %& ~
|
||||
conflicts=~
|
||||
@ -2313,7 +2556,7 @@
|
||||
=+ (slag (dec (lent path)) path)
|
||||
?~(- %$ i.-)
|
||||
=/ =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
|
||||
`[form:dais q.cob]
|
||||
?~ u.res
|
||||
@ -2665,6 +2908,9 @@
|
||||
++ start-request
|
||||
|= [for=(unit [ship @ud]) rav=rave]
|
||||
^+ ..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
|
||||
(try-fill-sub for (rave-to-rove rav))
|
||||
=. ..start-request (send-sub-results sub-results [hen ~ ~])
|
||||
@ -2721,14 +2967,23 @@
|
||||
%r ~| %no-cages-please-they-are-just-way-too-big !!
|
||||
%s ~| %please-dont-get-your-takos-over-a-network !!
|
||||
%t ~| %requesting-foreign-directory-is-vaporware !!
|
||||
%u ~| %prolly-poor-idea-to-get-rang-over-network !!
|
||||
%v ~| %weird-shouldnt-get-v-request-from-network !!
|
||||
%z `(validate-z r.rand)
|
||||
%u `(validate-u r.rand)
|
||||
%w `(validate-w r.rand)
|
||||
%x (validate-x [p.p q.p 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
|
||||
::
|
||||
++ validate-w
|
||||
@ -2749,7 +3004,11 @@
|
||||
=/ vale-result
|
||||
%- mule |.
|
||||
%- 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)
|
||||
%- (slog >%validate-x-failed< p.vale-result)
|
||||
~
|
||||
@ -2762,7 +3021,7 @@
|
||||
^- cage
|
||||
?> ?=(%uvi p.page)
|
||||
:- p.page
|
||||
!>(;;(@uvI q.page))
|
||||
!> ;;(@uvI q.page)
|
||||
--
|
||||
::
|
||||
:: Respond to backfill request
|
||||
@ -3391,12 +3650,29 @@
|
||||
|-
|
||||
?: =(b let.dom)
|
||||
hit.dom
|
||||
:: del everything after b
|
||||
$(hit.dom (~(del by hit.dom) let.dom), let.dom (dec let.dom))
|
||||
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
|
||||
::
|
||||
++ reachable-takos :: reachable
|
||||
@ -3415,30 +3691,6 @@
|
||||
=. s ^$(p i.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
|
||||
:: already in `b`.
|
||||
::
|
||||
@ -3528,11 +3780,11 @@
|
||||
[[~ ~] fod.dom]
|
||||
=/ cached=(unit [=vase *]) (~(get by naves.fod.dom) i.path)
|
||||
?^ cached
|
||||
:_(fod.dom [~ ~ %& %nave !>(vase.u.cached)])
|
||||
:_(fod.dom [~ ~ %& %nave vase.u.cached])
|
||||
=^ =vase fod.dom
|
||||
%- wrap:fusion
|
||||
(build-nave:(ford:fusion static-ford-args) i.path)
|
||||
:_(fod.dom [~ ~ %& %nave !>(vase)])
|
||||
:_(fod.dom [~ ~ %& %nave vase])
|
||||
::
|
||||
++ read-f
|
||||
!.
|
||||
@ -3958,12 +4210,14 @@
|
||||
::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
=| :: instrument state
|
||||
$: ver=%7 :: vane version
|
||||
$: ver=%8 :: vane version
|
||||
ruf=raft :: revision tree
|
||||
== ::
|
||||
|= [now=@da eny=@uvJ rof=roof] :: current invocation
|
||||
~% %clay-top ..part ~
|
||||
|% ::
|
||||
++ call :: handle request
|
||||
~/ %clay-call
|
||||
|= $: hen=duct
|
||||
dud=(unit goof)
|
||||
wrapped-task=(hobo task)
|
||||
@ -4074,6 +4328,14 @@
|
||||
=/ den ((de now rof hen ruf) our des.req)
|
||||
abet:(start-merge:den her.req dem.req cas.req how.req)
|
||||
[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
|
||||
=. hez.ruf ?^(hez.ruf hez.ruf `[[%$ %sync ~] ~])
|
||||
@ -4202,11 +4464,41 @@
|
||||
++ load
|
||||
=> |%
|
||||
+$ raft-any
|
||||
$% [%7 raft-7]
|
||||
$% [%8 raft-8]
|
||||
[%7 raft-7]
|
||||
[%6 raft-6]
|
||||
==
|
||||
+$ raft-7 raft
|
||||
+$ dojo-7 dojo
|
||||
+$ raft-8 raft
|
||||
+$ 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
|
||||
+$ raft-6
|
||||
$: rom=room-6 :: domestic
|
||||
@ -4249,7 +4541,8 @@
|
||||
|= old=raft-any
|
||||
|^
|
||||
=? old ?=(%6 -.old) 7+(raft-6-to-7 +.old)
|
||||
?> ?=(%7 -.old)
|
||||
=? old ?=(%7 -.old) 8+(raft-7-to-8 +.old)
|
||||
?> ?=(%8 -.old)
|
||||
..^^$(ruf +.old)
|
||||
:: +raft-6-to-7: delete stale ford caches (they could all be invalid)
|
||||
::
|
||||
@ -4270,9 +4563,30 @@
|
||||
|= =rede-6
|
||||
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
|
||||
~/ %clay-scry
|
||||
^- roon
|
||||
|= [lyc=gang car=term bem=beam]
|
||||
^- (unit (unit cage))
|
||||
@ -4334,6 +4648,7 @@
|
||||
==
|
||||
::
|
||||
++ take :: accept response
|
||||
~/ %clay-take
|
||||
|= [tea=wire hen=duct dud=(unit goof) hin=sign]
|
||||
^+ [*(list move) ..^$]
|
||||
?^ dud
|
||||
@ -4350,6 +4665,18 @@
|
||||
abet:(merge:den ali-ship ali-desk germ p.hin)
|
||||
[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)
|
||||
?> ?=(%writ +<.hin)
|
||||
:_ ..^$
|
||||
|
@ -215,7 +215,7 @@
|
||||
?: =('subscribe' u.maybe-key)
|
||||
%. item
|
||||
%+ 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)
|
||||
%. item
|
||||
%+ pe %unsubscribe
|
||||
@ -426,10 +426,12 @@
|
||||
:- ~
|
||||
%- as-octs:mimes:html
|
||||
%- crip
|
||||
%- zing
|
||||
%- zing ^- ^wall
|
||||
%- zing ^- (list ^wall)
|
||||
%+ turn wall
|
||||
|= t=tape
|
||||
"{t}\0a"
|
||||
^- ^wall
|
||||
~[t "\0a"]
|
||||
:: +internal-server-error: 500 page, with a tang
|
||||
::
|
||||
++ internal-server-error
|
||||
@ -1598,6 +1600,7 @@
|
||||
:: +channel-event-to-sign: attempt to recover a sign from a channel-event
|
||||
::
|
||||
++ channel-event-to-sign
|
||||
~% %eyre-channel-event-to-sign ..part ~
|
||||
|= event=channel-event
|
||||
^- (unit sign:agent:gall)
|
||||
?. ?=(%fact -.event) `event
|
||||
@ -1678,6 +1681,7 @@
|
||||
==
|
||||
::
|
||||
++ event-json-to-wall
|
||||
~% %eyre-json-to-wall ..part ~
|
||||
|= [event-id=@ud =json]
|
||||
^- wall
|
||||
:~ (weld "id: " (format-ud-as-integer event-id))
|
||||
@ -2095,6 +2099,7 @@
|
||||
~% %http-server ..part ~
|
||||
|%
|
||||
++ call
|
||||
~/ %eyre-call
|
||||
|= [=duct dud=(unit goof) wrapped-task=(hobo task)]
|
||||
^- [(list move) _http-server-gate]
|
||||
::
|
||||
@ -2297,6 +2302,7 @@
|
||||
==
|
||||
::
|
||||
++ take
|
||||
~/ %eyre-take
|
||||
|= [=wire =duct dud=(unit goof) =sign]
|
||||
^- [(list move) _http-server-gate]
|
||||
?^ dud
|
||||
@ -2484,6 +2490,7 @@
|
||||
:: +scry: request a path in the urbit namespace
|
||||
::
|
||||
++ scry
|
||||
~/ %eyre-scry
|
||||
^- roon
|
||||
|= [lyc=gang car=term bem=beam]
|
||||
^- (unit (unit cage))
|
||||
|
@ -646,6 +646,7 @@
|
||||
:: cleared queue in +load 3-to-4 or +load-4-to-5
|
||||
::
|
||||
=? stand ?=(~ stand)
|
||||
~& [%gall-missing wire hen]
|
||||
(~(put to *(qeu remote-request)) %missing)
|
||||
~| [full-wire=full-wire hen=hen stand=stand]
|
||||
=^ rr stand ~(get to stand)
|
||||
|
@ -3286,7 +3286,7 @@
|
||||
++ ship :: string from ship
|
||||
|= a=^ship
|
||||
^- json
|
||||
(tape (slag 1 (scow %p a)))
|
||||
[%n (rap 3 '"' (rsh [3 1] (scot %p a)) '"' ~)]
|
||||
:: :: ++numb:enjs:format
|
||||
++ numb :: number from unsigned
|
||||
|= a=@u
|
||||
@ -3458,7 +3458,7 @@
|
||||
[(rash a fel) b]
|
||||
:: :: ++pa:dejs:format
|
||||
++ pa :: string as path
|
||||
(su ;~(pfix fas (more fas urs:ab)))
|
||||
(su stap)
|
||||
:: :: ++pe:dejs:format
|
||||
++ pe :: prefix
|
||||
|* [pre=* wit=fist]
|
||||
@ -5070,36 +5070,54 @@
|
||||
|= ord=$-([key key] ?)
|
||||
|= a=*
|
||||
=/ b ;;((tree [key=key val=value]) a)
|
||||
?> (check-balance:((ordered-map key value) ord) b)
|
||||
?> (apt:((on key value) ord) b)
|
||||
b
|
||||
::
|
||||
:: $mk-item: constructor for +ordered-map item type
|
||||
::
|
||||
++ mk-item |$ [key val] [key=key val=val]
|
||||
:: +ordered-map: treap with user-specified horizontal order
|
||||
::
|
||||
:: 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.
|
||||
++ ordered-map on
|
||||
:: +on: treap with user-specified horizontal order, ordered-map
|
||||
::
|
||||
:: WARNING: ordered-map will not work properly if two keys can be
|
||||
:: unequal under noun equality but equal via the compare gate
|
||||
::
|
||||
++ ordered-map
|
||||
++ on
|
||||
~/ %on
|
||||
|* [key=mold val=mold]
|
||||
=> |%
|
||||
+$ item (mk-item key val)
|
||||
+$ item [key=key val=val]
|
||||
--
|
||||
:: +compare: item comparator for horizontal order
|
||||
::
|
||||
~% %comp +>+ ~
|
||||
|= compare=$-([key key] ?)
|
||||
~% %core + ~
|
||||
|%
|
||||
:: +check-balance: verify horizontal and vertical orderings
|
||||
:: +all: apply logical AND boolean test on all values
|
||||
::
|
||||
++ check-balance
|
||||
=| [l=(unit key) r=(unit key)]
|
||||
|= a=(tree item)
|
||||
++ all
|
||||
~/ %all
|
||||
|= [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
|
||||
::
|
||||
?~ a %.y
|
||||
@ -5122,64 +5140,22 @@
|
||||
::
|
||||
?~(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
|
||||
|= [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))
|
||||
:: +peek: produce head (smallest item) or null
|
||||
::
|
||||
++ peek
|
||||
++ bap
|
||||
~/ %bap
|
||||
|= a=(tree item)
|
||||
^- (unit item)
|
||||
::
|
||||
?~ a ~
|
||||
?~ l.a `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))
|
||||
^- (list item)
|
||||
=| b=(list item)
|
||||
|- ^+ b
|
||||
?~ a b
|
||||
$(a r.a, b [n.a $(a l.a)])
|
||||
:: +del: delete .key from .a if it exists, producing value iff deleted
|
||||
::
|
||||
++ del
|
||||
~/ %del
|
||||
|= [a=(tree item) =key]
|
||||
^- [(unit val) (tree item)]
|
||||
::
|
||||
?~ a [~ ~]
|
||||
:: we found .key at the root; delete and rebalance
|
||||
::
|
||||
@ -5192,30 +5168,15 @@
|
||||
[found a(l lef)]
|
||||
=+ [found rig]=$(a r.a)
|
||||
[found a(r rig)]
|
||||
:: +nip: remove root; for internal use
|
||||
::
|
||||
++ 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
|
||||
:: +dip: stateful partial inorder traversal
|
||||
::
|
||||
:: Mutates .state on each run of .f. Starts at .start key, or if
|
||||
:: .start is ~, starts at the head (item with smallest key). Stops
|
||||
:: when .f produces .stop=%.y. Traverses from smaller to larger
|
||||
:: keys. Each run of .f can replace an item's value or delete the
|
||||
:: item.
|
||||
:: .start is ~, starts at the head. Stops when .f produces .stop=%.y.
|
||||
:: Traverses from left to right keys.
|
||||
:: Each run of .f can replace an item's value or delete the item.
|
||||
::
|
||||
++ traverse
|
||||
++ dip
|
||||
~/ %dip
|
||||
|* state=mold
|
||||
|= $: a=(tree item)
|
||||
=state
|
||||
@ -5274,63 +5235,18 @@
|
||||
=/ rig main(a r.a)
|
||||
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
|
||||
~/ %gas
|
||||
|= [a=(tree item) b=(list item)]
|
||||
^- (tree item)
|
||||
::
|
||||
?~ b a
|
||||
$(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
|
||||
|= [a=(tree item) b=key]
|
||||
^- (unit val)
|
||||
?~ a ~
|
||||
@ -5339,11 +5255,24 @@
|
||||
?: (compare b key.n.a)
|
||||
$(a l.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
|
||||
::
|
||||
++ subset
|
||||
++ lot
|
||||
~/ %lot
|
||||
|= $: tre=(tree item)
|
||||
start=(unit key)
|
||||
end=(unit key)
|
||||
@ -5389,6 +5318,154 @@
|
||||
$(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
|
||||
@ -5535,7 +5612,8 @@
|
||||
:: :: ++unm:chrono:userlib
|
||||
++ unm :: Urbit to Unix ms
|
||||
|= 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 :: Urbit to Unix time
|
||||
|= a=@da
|
||||
|
@ -23,7 +23,7 @@
|
||||
=/ src "."
|
||||
%+ expect-eq
|
||||
!> ^- pile:fusion
|
||||
:* ~ ~ ~ ~ ~ ~
|
||||
:* ~ ~ ~ ~ ~ ~ ~
|
||||
tssg+[%dbug [/sur/foo/hoon [[1 1] [1 2]]] [%cnts ~[[%.y 1]] ~]]~
|
||||
==
|
||||
!> (parse-pile:(ford):fusion /sur/foo/hoon src)
|
||||
@ -32,7 +32,7 @@
|
||||
=/ src "/% moo %mime\0a."
|
||||
%+ expect-eq
|
||||
!> ^- pile:fusion
|
||||
:* sur=~ lib=~ raw=~
|
||||
:* sur=~ lib=~ raw=~ raz=~
|
||||
maz=[face=%moo mark=%mime]~
|
||||
caz=~ bar=~
|
||||
tssg+[%dbug [/sur/foo/hoon [[2 1] [2 2]]] [%cnts ~[[%.y 1]] ~]]~
|
||||
@ -43,7 +43,7 @@
|
||||
=/ src "/$ goo %mime %txt\0a."
|
||||
%+ expect-eq
|
||||
!> ^- pile:fusion
|
||||
:* sur=~ lib=~ raw=~ maz=~
|
||||
:* sur=~ lib=~ raw=~ raz=~ maz=~
|
||||
caz=[face=%goo from=%mime to=%txt]~
|
||||
bar=~
|
||||
tssg+[%dbug [/sur/foo/hoon [[2 1] [2 2]]] [%cnts ~[[%.y 1]] ~]]~
|
||||
@ -74,7 +74,7 @@
|
||||
[`%hood-drum %hood-drum]
|
||||
[`%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]] ~]]~
|
||||
==
|
||||
!> (parse-pile:(ford):fusion /sur/foo/hoon src)
|
||||
@ -112,10 +112,10 @@
|
||||
;: weld
|
||||
%+ expect-eq
|
||||
!>(*mime)
|
||||
(slap res limb/%bunt)
|
||||
(slap res !,(*hoon *vale))
|
||||
::
|
||||
%+ 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)
|
||||
==
|
||||
::
|
||||
@ -139,10 +139,10 @@
|
||||
;: weld
|
||||
%+ expect-eq
|
||||
!>(*@t)
|
||||
(slap res limb/%bunt)
|
||||
(slap res !,(*hoon *vale))
|
||||
::
|
||||
%+ 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)
|
||||
==
|
||||
::
|
||||
@ -170,7 +170,7 @@
|
||||
=/ changes
|
||||
%- my
|
||||
:~ [/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:fusion
|
||||
@ -224,7 +224,7 @@
|
||||
(slap res (ream '(+ [*^ [%bob ~] ~])'))
|
||||
::
|
||||
%+ 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)
|
||||
==
|
||||
::
|
||||
@ -249,10 +249,10 @@
|
||||
!>((slab %read %get-our -.res))
|
||||
::
|
||||
%+ expect-eq
|
||||
!> %- ~(gas in *(set path))
|
||||
:~ /lib/strandio/hoon
|
||||
/lib/strand/hoon
|
||||
/sur/spider/hoon
|
||||
!> %- ~(gas in *(set [? path]))
|
||||
:~ [| /lib/strandio/hoon]
|
||||
[| /lib/strand/hoon]
|
||||
[| /sur/spider/hoon]
|
||||
==
|
||||
!> dez:(~(got by files.cache.nub) /lib/strandio/hoon)
|
||||
==
|
||||
|
@ -2353,7 +2353,6 @@
|
||||
:^ ~ ~ %dais
|
||||
!> ^- dais:clay
|
||||
|_ sam=vase
|
||||
++ bunt !!
|
||||
++ diff !!
|
||||
++ form !!
|
||||
++ join !!
|
||||
|
@ -179,10 +179,15 @@
|
||||
%+ expect-eq
|
||||
!> [%n '1000']
|
||||
!> (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
|
||||
::
|
||||
%+ expect-eq
|
||||
!> [%s 'zod']
|
||||
!> [%n '"zod"']
|
||||
!> (ship ~zod)
|
||||
==
|
||||
:: dejs - recursive processing of `json` values
|
||||
|
@ -9,6 +9,7 @@
|
||||
(items-from-keys (gulf 0 6))
|
||||
::
|
||||
=/ atom-map ((ordered-map @ud @tas) lte)
|
||||
=/ gte-atom-map ((ordered-map @ud @tas) gte)
|
||||
::
|
||||
|%
|
||||
++ test-ordered-map-gas ^- tang
|
||||
@ -17,7 +18,7 @@
|
||||
::
|
||||
%+ expect-eq
|
||||
!> %.y
|
||||
!> (check-balance:atom-map a)
|
||||
!> (apt:atom-map a)
|
||||
::
|
||||
++ test-ordered-map-tap ^- tang
|
||||
::
|
||||
@ -27,6 +28,72 @@
|
||||
!> test-items
|
||||
!> (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
|
||||
::
|
||||
=/ a=(tree [@ud @tas]) (gas:atom-map ~ test-items)
|
||||
@ -35,13 +102,13 @@
|
||||
!> [[0 %a] (gas:atom-map ~ (items-from-keys (gulf 1 6)))]
|
||||
!> (pop:atom-map a)
|
||||
::
|
||||
++ test-ordered-map-peek ^- tang
|
||||
++ test-ordered-map-pry ^- tang
|
||||
::
|
||||
=/ a=(tree [@ud @tas]) (gas:atom-map ~ test-items)
|
||||
::
|
||||
%+ expect-eq
|
||||
!> `[0 %a]
|
||||
!> (peek:atom-map a)
|
||||
!> (pry:atom-map a)
|
||||
::
|
||||
++ test-ordered-map-nip ^- tang
|
||||
::
|
||||
@ -53,61 +120,61 @@
|
||||
!> (gas:atom-map ~ ~[[0^%a] [1^%b] [2^%c] [3^%d] [4^%e] [5^%f]])
|
||||
!> b
|
||||
::
|
||||
++ test-ordered-map-subset ^- tang
|
||||
++ test-ordered-map-lot ^- tang
|
||||
::
|
||||
=/ 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
|
||||
!> (gas:atom-map ~ ~[[1^%b] [2^%c] [3^%d]])
|
||||
!> b
|
||||
::
|
||||
++ test-ordered-map-null-start-subset ^- tang
|
||||
++ test-ordered-map-null-start-lot ^- tang
|
||||
::
|
||||
=/ a=(tree [@ud @tas]) (gas:atom-map ~ test-items)
|
||||
::
|
||||
=/ b (subset:atom-map a ~ `5)
|
||||
=/ b (lot:atom-map a ~ `5)
|
||||
::
|
||||
%+ expect-eq
|
||||
!> (gas:atom-map ~ ~[[0^%a] [1^%b] [2^%c] [3^%d] [4^%e]])
|
||||
!> b
|
||||
::
|
||||
++ test-ordered-map-null-end-subset ^- tang
|
||||
++ test-ordered-map-null-end-lot ^- tang
|
||||
::
|
||||
=/ a=(tree [@ud @tas]) (gas:atom-map ~ test-items)
|
||||
::
|
||||
=/ b (subset:atom-map a `1 ~)
|
||||
=/ b (lot:atom-map a `1 ~)
|
||||
::
|
||||
%+ expect-eq
|
||||
!> (gas:atom-map ~ ~[[2^%c] [3^%d] [4^%e] [5^%f] [6^%g]])
|
||||
!> b
|
||||
::
|
||||
++ test-ordered-map-double-null-subset ^- tang
|
||||
++ test-ordered-map-double-null-lot ^- tang
|
||||
::
|
||||
=/ a=(tree [@ud @tas]) (gas:atom-map ~ test-items)
|
||||
::
|
||||
=/ b (subset:atom-map a ~ ~)
|
||||
=/ b (lot:atom-map a ~ ~)
|
||||
::
|
||||
%+ expect-eq
|
||||
!> (gas:atom-map ~ ~[[0^%a] [1^%b] [2^%c] [3^%d] [4^%e] [5^%f] [6^%g]])
|
||||
!> 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]])
|
||||
::
|
||||
=/ b (subset:atom-map a `0 ~)
|
||||
=/ b (lot:atom-map a `0 ~)
|
||||
::
|
||||
%+ expect-eq
|
||||
!> (gas:atom-map ~ ~[[1^%b]])
|
||||
!> b
|
||||
::
|
||||
++ test-ordered-map-traverse ^- tang
|
||||
++ test-ordered-map-dip ^- tang
|
||||
::
|
||||
=/ a=(tree [@ud @tas]) (gas:atom-map ~ test-items)
|
||||
::
|
||||
=/ b %- (traverse:atom-map ,(list [@ud @tas]))
|
||||
=/ b %- (dip:atom-map ,(list [@ud @tas]))
|
||||
:* a
|
||||
state=~
|
||||
::
|
||||
@ -129,11 +196,11 @@
|
||||
!> -.b
|
||||
==
|
||||
::
|
||||
++ test-ordered-map-traverse-delete-all ^- tang
|
||||
++ test-ordered-map-dip-delete-all ^- tang
|
||||
;: weld
|
||||
=/ q ((ordered-map ,@ ,~) lte)
|
||||
=/ o (gas:q ~ ~[1/~ 2/~ 3/~])
|
||||
=/ b ((traverse:q ,~) o ~ |=([~ key=@ ~] [~ %| ~]))
|
||||
=/ b ((dip:q ,~) o ~ |=([~ key=@ ~] [~ %| ~]))
|
||||
%+ expect-eq
|
||||
!> [~ ~]
|
||||
!> b
|
||||
@ -147,7 +214,7 @@
|
||||
?:((lth aa ba) %.y ?:((gth aa ba) %.n (lte ab bb)))
|
||||
=/ q ((ordered-map ,[@ @] ,~) compare)
|
||||
=/ o (gas:q ~ c)
|
||||
=/ b ((traverse:q ,~) o ~ |=([~ key=[@ @] ~] [~ %| ~]))
|
||||
=/ b ((dip:q ,~) o ~ |=([~ key=[@ @] ~] [~ %| ~]))
|
||||
%+ expect-eq
|
||||
!> [~ ~]
|
||||
!> b
|
||||
|
1
pkg/ent/configure
vendored
1
pkg/ent/configure
vendored
@ -7,6 +7,7 @@ log () {
|
||||
for impl in ENT_GETENTROPY_UNISTD \
|
||||
ENT_GETENTROPY_SYSRANDOM \
|
||||
ENT_GETRANDOM_SYSCALL \
|
||||
ENT_GETENTROPY_BCRYPTGENRANDOM \
|
||||
ENT_DEV_URANDOM
|
||||
do
|
||||
export IMPL=$impl
|
||||
|
@ -57,6 +57,16 @@ int ent_getentropy(void* buf, size_t len) {
|
||||
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
|
||||
#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
|
||||
|
1
pkg/urbit/.gitattributes
vendored
1
pkg/urbit/.gitattributes
vendored
@ -3,3 +3,4 @@
|
||||
tests export-ignore
|
||||
hashtable_tests export-ignore
|
||||
shell.nix export-ignore
|
||||
*.patch -text
|
||||
|
2
pkg/urbit/.gitignore
vendored
2
pkg/urbit/.gitignore
vendored
@ -1,3 +1,5 @@
|
||||
# Configuration Result
|
||||
/config.mk
|
||||
/include/config.h
|
||||
/include/ca-bundle.h
|
||||
/include/ivory.h
|
||||
|
@ -1,4 +1,5 @@
|
||||
include config.mk
|
||||
include $(foreach dir,$(compat),$(wildcard compat/$(dir)/*.mk))
|
||||
|
||||
jets = jets/tree.c $(wildcard jets/*/*.c)
|
||||
noun = $(wildcard noun/*.c)
|
||||
@ -9,7 +10,9 @@ worker = $(wildcard worker/*.c)
|
||||
tests = $(wildcard tests/*.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)
|
||||
|
||||
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
|
||||
@$(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 $<
|
||||
@$(CC) -I./include $(CFLAGS) -c $< -o $@
|
||||
@$(CC) -I./include $(CFLAGS) $< $(CCEXTRA) -c -o $@
|
||||
|
||||
tags: $(all_srcs) $(headers)
|
||||
ctags $^
|
||||
|
22
pkg/urbit/compat/create-include-files.sh
Executable file
22
pkg/urbit/compat/create-include-files.sh
Executable 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
|
14
pkg/urbit/compat/m1brew/compat.mk
Normal file
14
pkg/urbit/compat/m1brew/compat.mk
Normal 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
|
13
pkg/urbit/compat/m1brew/ed25519.patch
Normal file
13
pkg/urbit/compat/m1brew/ed25519.patch
Normal 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
|
12
pkg/urbit/compat/m1brew/ent.patch
Normal file
12
pkg/urbit/compat/m1brew/ent.patch
Normal 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"
|
17
pkg/urbit/compat/m1brew/libscrypt.patch
Normal file
17
pkg/urbit/compat/m1brew/libscrypt.patch
Normal 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
|
13
pkg/urbit/compat/m1brew/murmur3.patch
Normal file
13
pkg/urbit/compat/m1brew/murmur3.patch
Normal 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
|
85
pkg/urbit/compat/m1brew/softfloat3.patch
Normal file
85
pkg/urbit/compat/m1brew/softfloat3.patch
Normal 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
|
||||
|
23
pkg/urbit/compat/m1brew/use-static-libs.sh
Executable file
23
pkg/urbit/compat/m1brew/use-static-libs.sh
Executable 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
|
355
pkg/urbit/compat/mingw/compat.c
Normal file
355
pkg/urbit/compat/mingw/compat.c
Normal 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);
|
||||
}
|
18
pkg/urbit/compat/mingw/compat.h
Normal file
18
pkg/urbit/compat/mingw/compat.h
Normal 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
|
15
pkg/urbit/compat/mingw/compat.mk
Normal file
15
pkg/urbit/compat/mingw/compat.mk
Normal 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
|
7
pkg/urbit/compat/mingw/ctrlc.c
Normal file
7
pkg/urbit/compat/mingw/ctrlc.c
Normal 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);
|
||||
}
|
116
pkg/urbit/compat/mingw/daemon.c
Normal file
116
pkg/urbit/compat/mingw/daemon.c
Normal 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);
|
||||
}
|
||||
}
|
13
pkg/urbit/compat/mingw/ed25519.patch
Normal file
13
pkg/urbit/compat/mingw/ed25519.patch
Normal 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
|
1834
pkg/urbit/compat/mingw/h2o.patch
Normal file
1834
pkg/urbit/compat/mingw/h2o.patch
Normal file
File diff suppressed because it is too large
Load Diff
17
pkg/urbit/compat/mingw/libscrypt.patch
Normal file
17
pkg/urbit/compat/mingw/libscrypt.patch
Normal 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
|
74
pkg/urbit/compat/mingw/lmdb.patch
Normal file
74
pkg/urbit/compat/mingw/lmdb.patch
Normal 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 */
|
26
pkg/urbit/compat/mingw/mman.h
Normal file
26
pkg/urbit/compat/mingw/mman.h
Normal 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
|
13
pkg/urbit/compat/mingw/murmur3.patch
Normal file
13
pkg/urbit/compat/mingw/murmur3.patch
Normal 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
|
152
pkg/urbit/compat/mingw/ptty.c
Normal file
152
pkg/urbit/compat/mingw/ptty.c
Normal 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;
|
||||
}
|
167
pkg/urbit/compat/mingw/rsignal.c
Normal file
167
pkg/urbit/compat/mingw/rsignal.c
Normal 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);
|
||||
}
|
24
pkg/urbit/compat/mingw/rsignal.h
Normal file
24
pkg/urbit/compat/mingw/rsignal.h
Normal 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
|
25
pkg/urbit/compat/mingw/seh_handler.c
Normal file
25
pkg/urbit/compat/mingw/seh_handler.c
Normal 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;
|
||||
}
|
65
pkg/urbit/compat/mingw/seh_handler_decorator.cc
Normal file
65
pkg/urbit/compat/mingw/seh_handler_decorator.cc
Normal 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;
|
||||
}
|
24
pkg/urbit/compat/mingw/seh_handler_decorator.mk
Normal file
24
pkg/urbit/compat/mingw/seh_handler_decorator.mk
Normal 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 $@
|
15
pkg/urbit/compat/mingw/setjmp.h
Normal file
15
pkg/urbit/compat/mingw/setjmp.h
Normal 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
|
36
pkg/urbit/compat/mingw/softfloat3.patch
Normal file
36
pkg/urbit/compat/mingw/softfloat3.patch
Normal 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)
|
||||
|
30
pkg/urbit/compat/mingw/uv.patch
Normal file
30
pkg/urbit/compat/mingw/uv.patch
Normal 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;
|
148
pkg/urbit/compat/poor-mans-nix-shell.sh
Normal file
148
pkg/urbit/compat/poor-mans-nix-shell.sh
Normal 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[@]}"
|
91
pkg/urbit/compat/posix/daemon.c
Normal file
91
pkg/urbit/compat/posix/daemon.c
Normal 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));
|
||||
}
|
189
pkg/urbit/compat/posix/ptty.c
Normal file
189
pkg/urbit/compat/posix/ptty.c
Normal 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;
|
||||
}
|
11
pkg/urbit/compat/posix/rsignal.h
Normal file
11
pkg/urbit/compat/posix/rsignal.h
Normal 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
84
pkg/urbit/configure
vendored
@ -1,12 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -euo pipefail
|
||||
|
||||
URBIT_VERSION="$(cat ./version)"
|
||||
|
||||
deps=" \
|
||||
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=" \
|
||||
@ -21,10 +21,28 @@ defmacro () {
|
||||
|
||||
defmacro URBIT_VERSION "\"$URBIT_VERSION\""
|
||||
|
||||
[ -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
|
||||
opt_debug=
|
||||
|
||||
while test $# != 0
|
||||
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-}" ]
|
||||
then os=$(sed 's$^[^-]*-\([^-]*\)-.*$\1$' <<< "$HOST")
|
||||
@ -58,14 +76,53 @@ esac
|
||||
|
||||
# TODO Determine if the target cpu is little or big endian.
|
||||
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*)
|
||||
defmacro U3_OS_linux 1
|
||||
defmacro U3_OS_PROF 1
|
||||
;;
|
||||
*darwin*)
|
||||
defmacro U3_OS_osx 1
|
||||
defmacro U3_OS_PROF 1
|
||||
;;
|
||||
*apple*)
|
||||
defmacro U3_OS_osx 1
|
||||
defmacro U3_OS_PROF 1
|
||||
;;
|
||||
*freebsd*)
|
||||
defmacro U3_OS_bsd 1
|
||||
@ -81,18 +138,27 @@ case $(tr A-Z a-z <<< $os) in
|
||||
esac
|
||||
|
||||
for dep in ${osdeps-} $deps
|
||||
do LDFLAGS="${LDFLAGS-} -l$dep"
|
||||
${PKG_CONFIG-pkg-config} --cflags --libs $dep 2>/dev/null || true
|
||||
do
|
||||
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
|
||||
|
||||
for header in $headers
|
||||
do LDFLAGS="${LDFLAGS-} -I$header"
|
||||
done
|
||||
|
||||
compat="${compat-posix}"
|
||||
for citem in $compat
|
||||
do
|
||||
CFLAGS="${CFLAGS-} -Icompat/$citem"
|
||||
done
|
||||
|
||||
cat >config.mk <<EOF
|
||||
CFLAGS := ${CFLAGS-} -funsigned-char -ffast-math -std=gnu99
|
||||
CFLAGS := $CFLAGS -funsigned-char -ffast-math -fcommon -std=gnu99
|
||||
LDFLAGS := $LDFLAGS
|
||||
CC := ${CC-cc}
|
||||
compat := $compat
|
||||
debug := $opt_debug
|
||||
EOF
|
||||
|
||||
echo == config.mk == >&2
|
||||
|
@ -1,16 +1,13 @@
|
||||
/* vere/main.c
|
||||
**
|
||||
*/
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <limits.h>
|
||||
#include <uv.h>
|
||||
#define U3_GLOBAL
|
||||
#define C3_GLOBAL
|
||||
#include "all.h"
|
||||
#include "vere/vere.h"
|
||||
#if !defined(U3_OS_mingw)
|
||||
#include <sigsegv.h>
|
||||
#include <stdlib.h>
|
||||
#include <termios.h>
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/err.h>
|
||||
@ -18,13 +15,6 @@
|
||||
#include <h2o.h>
|
||||
#include <curl/curl.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 "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) {
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
@ -307,7 +297,7 @@ _main_getopt(c3_i argc, c3_c** argv)
|
||||
}
|
||||
|
||||
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");
|
||||
return c3n;
|
||||
}
|
||||
@ -373,26 +363,64 @@ _main_getopt(c3_i argc, c3_c** argv)
|
||||
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
|
||||
_setup_cert_store(char* tmp_cert_file_name)
|
||||
_setup_cert_store()
|
||||
{
|
||||
errno = 0;
|
||||
int fd = mkstemp(tmp_cert_file_name);
|
||||
if (fd < 1) {
|
||||
printf("boot: failed to write local ssl temporary certificate store: %s\n",
|
||||
strerror(errno));
|
||||
BIO* cbio = BIO_new_mem_buf(include_ca_bundle_crt, include_ca_bundle_crt_len);
|
||||
if ( !cbio || !(_cert_store = PEM_X509_INFO_read_bio(cbio, NULL, NULL, NULL)) ) {
|
||||
u3l_log("boot: failed to decode embedded CA certificates\r\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (-1 == write(fd, include_ca_bundle_crt, include_ca_bundle_crt_len)) {
|
||||
printf("boot: failed to write local ssl temporary certificate store: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
BIO_free(cbio);
|
||||
}
|
||||
|
||||
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("gmp: %s\n", gmp_version);
|
||||
#if !defined(U3_OS_mingw)
|
||||
printf("sigsegv: %d.%d\n",
|
||||
(libsigsegv_version >> 8) & 0xff,
|
||||
libsigsegv_version & 0xff);
|
||||
#endif
|
||||
printf("openssl: %s\n", SSLeay_version(SSLEAY_VERSION));
|
||||
printf("libuv: %s\n", uv_version_string());
|
||||
printf("libh2o: %d.%d.%d\n",
|
||||
@ -517,96 +547,6 @@ _stop_exit(c3_i int_i)
|
||||
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
|
||||
*/
|
||||
static void
|
||||
@ -659,12 +599,24 @@ main(c3_i argc,
|
||||
}
|
||||
|
||||
// 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);
|
||||
#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]);
|
||||
}
|
||||
#else
|
||||
snprintf(u3_Host.wrk_c, worker_exe_len, "%s-worker", argv[0]);
|
||||
#endif
|
||||
|
||||
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 ) {
|
||||
@ -688,6 +640,7 @@ main(c3_i argc,
|
||||
//
|
||||
// XX review, may be unnecessary due to similar in u3m_init()
|
||||
//
|
||||
#if defined(U3_OS_PROF)
|
||||
if ( _(u3_Host.ops_u.pro) ) {
|
||||
sigset_t set;
|
||||
|
||||
@ -698,12 +651,15 @@ main(c3_i argc,
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(U3_OS_mingw)
|
||||
// Handle SIGTSTP as if it was SIGTERM.
|
||||
//
|
||||
// Configured here using signal() so as to be immediately available.
|
||||
//
|
||||
signal(SIGTSTP, _stop_exit);
|
||||
#endif
|
||||
|
||||
printf("~\n");
|
||||
// printf("welcome.\n");
|
||||
@ -735,9 +691,6 @@ main(c3_i argc,
|
||||
}
|
||||
// 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 ) {
|
||||
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
|
||||
//
|
||||
{
|
||||
@ -818,6 +783,10 @@ main(c3_i argc,
|
||||
exit(1);
|
||||
}
|
||||
|
||||
_setup_cert_store();
|
||||
u3K.ssl_curl_f = _setup_ssl_curl;
|
||||
u3K.ssl_x509_f = _setup_ssl_x509;
|
||||
|
||||
u3_king_commence();
|
||||
|
||||
// uninitialize curl
|
||||
|
@ -72,6 +72,25 @@
|
||||
# include <sys/resource.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
|
||||
#error "port: headers"
|
||||
# endif
|
||||
@ -97,14 +116,10 @@
|
||||
# define U3_OS_LoomBase 0x36000000
|
||||
# endif
|
||||
# define U3_OS_LoomBits 29 // ie, 2^29 words == 2GB
|
||||
# elif defined(U3_OS_osx)
|
||||
# ifdef __LP64__
|
||||
# define U3_OS_LoomBase 0x200000000
|
||||
# else
|
||||
# define U3_OS_LoomBase 0x4000000
|
||||
# endif
|
||||
# elif defined(U3_OS_osx) && defined(U3_CPU_aarch64) || defined(U3_OS_mingw)
|
||||
# define U3_OS_LoomBase 0x28000000000
|
||||
# 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__
|
||||
# define U3_OS_LoomBase 0x200000000
|
||||
# else
|
||||
@ -153,7 +168,7 @@
|
||||
|
||||
/* 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_32(x) bswap_32(x)
|
||||
# define c3_bswap_64(x) bswap_64(x)
|
||||
@ -167,7 +182,7 @@
|
||||
|
||||
/* Sync.
|
||||
*/
|
||||
# if defined(U3_OS_linux)
|
||||
# if defined(U3_OS_linux) || defined(U3_OS_mingw)
|
||||
# define c3_sync(fd) (fdatasync(fd))
|
||||
# elif defined(U3_OS_osx)
|
||||
# define c3_sync(fd) (fcntl(fd, F_FULLFSYNC, 0))
|
||||
@ -182,7 +197,7 @@
|
||||
# if defined(U3_OS_linux)
|
||||
# include <stdio_ext.h>
|
||||
# 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
|
||||
# else
|
||||
# error "port: fpurge"
|
||||
@ -190,7 +205,7 @@
|
||||
|
||||
/* 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))
|
||||
# elif defined(U3_OS_osx)
|
||||
# define c3_stat_mtime(dp) (u3_time_in_ts(&((dp)->st_mtimespec)))
|
||||
@ -200,6 +215,16 @@
|
||||
# define lseek64 lseek
|
||||
# else
|
||||
# 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
|
||||
|
||||
/* Static assertion.
|
||||
|
@ -2,6 +2,9 @@
|
||||
**
|
||||
** This file is in the public domain.
|
||||
*/
|
||||
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
/** Constants.
|
||||
**/
|
||||
/* u3a_bits: number of bits in word-addressed pointer. 29 == 2GB.
|
||||
|
@ -222,22 +222,40 @@
|
||||
};
|
||||
#endif
|
||||
|
||||
/* u3_utty: unix tty.
|
||||
*/
|
||||
struct _u3_utty;
|
||||
|
||||
/* u3_ustm: uv stream.
|
||||
*/
|
||||
typedef union _u3_ustm {
|
||||
uv_pipe_t pop_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 {
|
||||
union {
|
||||
uv_pipe_t pop_u;
|
||||
uv_tcp_t wax_u;
|
||||
};
|
||||
u3_ustm pin_u; // input stream
|
||||
u3_ustm pop_u; // output stream
|
||||
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_w tid_l; // terminal identity number
|
||||
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
|
||||
struct termios bak_u; // cooked terminal state
|
||||
struct termios raw_u; // raw terminal state
|
||||
struct _u3_auto* car_u; // driver hack
|
||||
} u3_utty;
|
||||
|
||||
@ -301,6 +319,9 @@
|
||||
c3_d now_d; // event tick
|
||||
uv_loop_t* lup_u; // libuv event loop
|
||||
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_opts ops_u; // commandline options
|
||||
c3_i xit_i; // exit code for shutdown
|
||||
@ -469,6 +490,7 @@
|
||||
time_t wen_t; // process creation time
|
||||
u3_mojo inn_u; // client's stdin
|
||||
u3_moat out_u; // client's stdout
|
||||
uv_pipe_t err_u; // client's stderr
|
||||
c3_w wag_w; // config flags
|
||||
c3_c* bin_c; // binary path
|
||||
c3_c* pax_c; // directory
|
||||
@ -641,7 +663,8 @@
|
||||
/* u3_king: all executing piers.
|
||||
*/
|
||||
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
|
||||
uv_timer_t tim_u; // gc timer
|
||||
} u3_king;
|
||||
@ -716,7 +739,7 @@
|
||||
*/
|
||||
u3_atom
|
||||
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_atom
|
||||
@ -1103,6 +1126,11 @@
|
||||
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.
|
||||
**/
|
||||
@ -1371,6 +1399,15 @@
|
||||
void
|
||||
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
|
||||
u3_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
|
||||
|
@ -1,12 +1,11 @@
|
||||
/* g/e.c
|
||||
**
|
||||
*/
|
||||
#include "all.h"
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "all.h"
|
||||
|
||||
#ifdef U3_SNAPSHOT_VALIDATION
|
||||
/* Image check.
|
||||
*/
|
||||
@ -815,8 +814,8 @@ u3e_save(void)
|
||||
|
||||
_ce_image_sync(&u3P.nor_u);
|
||||
_ce_image_sync(&u3P.sou_u);
|
||||
_ce_patch_delete();
|
||||
_ce_patch_free(pat_u);
|
||||
_ce_patch_delete();
|
||||
}
|
||||
|
||||
/* 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_image_sync(&u3P.nor_u);
|
||||
_ce_image_sync(&u3P.sou_u);
|
||||
_ce_patch_delete();
|
||||
_ce_patch_free(pat_u);
|
||||
_ce_patch_delete();
|
||||
}
|
||||
|
||||
/* Write image files to memory; reinstate protection.
|
||||
|
@ -1,17 +1,15 @@
|
||||
/* n/m.c
|
||||
**
|
||||
*/
|
||||
#include "all.h"
|
||||
#include "rsignal.h"
|
||||
#include "vere/vere.h"
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ctype.h>
|
||||
#include <sigsegv.h>
|
||||
#include <curl/curl.h>
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
#include "all.h"
|
||||
#include "vere/vere.h"
|
||||
|
||||
// XX stack-overflow recovery should be gated by -a
|
||||
//
|
||||
#undef NO_OVERFLOW
|
||||
@ -75,7 +73,17 @@
|
||||
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
|
||||
# define SIGSTKSZ 16384
|
||||
@ -83,6 +91,7 @@ static sigjmp_buf u3_Signal;
|
||||
#ifndef NO_OVERFLOW
|
||||
static uint8_t Sigstk[SIGSTKSZ];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* _cm_punt(): crudely print trace.
|
||||
@ -129,17 +138,25 @@ static void _cm_overflow(void *arg1, void *arg2, void *arg3)
|
||||
static void
|
||||
_cm_signal_handle(c3_l sig_l)
|
||||
{
|
||||
#ifndef U3_OS_mingw
|
||||
if ( c3__over == sig_l ) {
|
||||
#ifndef NO_OVERFLOW
|
||||
sigsegv_leave_handler(_cm_overflow, NULL, NULL, NULL);
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
u3m_signal(sig_l);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NO_OVERFLOW
|
||||
static void
|
||||
#ifndef U3_OS_mingw
|
||||
_cm_signal_handle_over(int emergency, stackoverflow_context_t scp)
|
||||
#else
|
||||
_cm_signal_handle_over(int x)
|
||||
#endif
|
||||
{
|
||||
_cm_signal_handle(c3__over);
|
||||
}
|
||||
@ -330,10 +347,14 @@ _cm_signal_deep(c3_w mil_w)
|
||||
}
|
||||
|
||||
#ifndef NO_OVERFLOW
|
||||
#ifndef U3_OS_mingw
|
||||
stackoverflow_install_handler(_cm_signal_handle_over, Sigstk, SIGSTKSZ);
|
||||
#else
|
||||
rsignal_install_handler(SIGSTK, _cm_signal_handle_over);
|
||||
#endif
|
||||
signal(SIGINT, _cm_signal_handle_intr);
|
||||
signal(SIGTERM, _cm_signal_handle_term);
|
||||
#endif
|
||||
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
|
||||
// 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_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));
|
||||
}
|
||||
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
|
||||
_cm_signal_done()
|
||||
{
|
||||
signal(SIGINT, SIG_IGN);
|
||||
signal(SIGTERM, SIG_IGN);
|
||||
signal(SIGVTALRM, SIG_IGN);
|
||||
rsignal_deinstall_handler(SIGINT);
|
||||
rsignal_deinstall_handler(SIGTERM);
|
||||
rsignal_deinstall_handler(SIGVTALRM);
|
||||
|
||||
#ifndef NO_OVERFLOW
|
||||
#ifndef U3_OS_mingw
|
||||
stackoverflow_deinstall_handler();
|
||||
#else
|
||||
rsignal_deinstall_handler(SIGSTK);
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
struct itimerval itm_u;
|
||||
@ -378,7 +403,7 @@ _cm_signal_done()
|
||||
timerclear(&itm_u.it_interval);
|
||||
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));
|
||||
}
|
||||
}
|
||||
@ -397,7 +422,7 @@ _cm_signal_done()
|
||||
void
|
||||
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.
|
||||
@ -959,7 +984,7 @@ u3m_soft_top(c3_w mil_w, // timer ms
|
||||
*/
|
||||
_cm_signal_deep(mil_w);
|
||||
|
||||
if ( 0 != (sig_l = sigsetjmp(u3_Signal, 1)) ) {
|
||||
if ( 0 != (sig_l = rsignal_setjmp(u3_Signal)) ) {
|
||||
// reinitialize trace state
|
||||
//
|
||||
u3t_init();
|
||||
@ -1559,6 +1584,10 @@ u3m_wall(u3_noun wol)
|
||||
static 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;
|
||||
|
||||
// Moar stack.
|
||||
@ -1606,6 +1635,7 @@ _cm_limits(void)
|
||||
}
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
}
|
||||
|
||||
/* _cm_signals(): set up interrupts, etc.
|
||||
@ -1613,13 +1643,23 @@ _cm_limits(void)
|
||||
static 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) ) {
|
||||
u3l_log("boot: sigsegv install failed\n");
|
||||
exit(1);
|
||||
}
|
||||
// signal(SIGINT, _loom_stop);
|
||||
|
||||
# endif
|
||||
|
||||
# if defined(U3_OS_PROF)
|
||||
// Block SIGPROF, so that if/when we reactivate it on the
|
||||
// main thread for profiling, we won't get hits in parallel
|
||||
// on other threads.
|
||||
@ -1634,6 +1674,7 @@ _cm_signals(void)
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
/* 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("see urbit.org/using/install/#about-swap-space"
|
||||
" 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",
|
||||
dyn_v);
|
||||
}
|
||||
|
@ -2,11 +2,10 @@
|
||||
**
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "all.h"
|
||||
#include "ur/ur.h"
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
/* _cs_jam_buf: struct for tracking the fibonacci-allocated jam of a noun
|
||||
*/
|
||||
|
@ -519,7 +519,7 @@ u3t_boot(void)
|
||||
{
|
||||
if ( u3C.wag_w & u3o_debug_cpu ) {
|
||||
_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
|
||||
//
|
||||
if ( 0 == u3A->roc ) {
|
||||
@ -551,10 +551,6 @@ u3t_boot(void)
|
||||
itm_v.it_value = itm_v.it_interval;
|
||||
setitimer(ITIMER_PROF, &itm_v, 0);
|
||||
}
|
||||
#elif defined(U3_OS_bsd)
|
||||
// XX "Profiling isn't yet supported on BSD"
|
||||
#else
|
||||
# error "port: profiling"
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -565,7 +561,7 @@ void
|
||||
u3t_boff(void)
|
||||
{
|
||||
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
|
||||
// thread that unblocked them).
|
||||
{
|
||||
@ -590,11 +586,6 @@ u3t_boff(void)
|
||||
sig_s.sa_handler = SIG_IGN;
|
||||
sigaction(SIGPROF, &sig_s, 0);
|
||||
}
|
||||
|
||||
#elif defined(U3_OS_bsd)
|
||||
// XX "Profiling isn't yet supported on BSD"
|
||||
#else
|
||||
# error "port: profiling"
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,13 @@
|
||||
/* noun/urth.c
|
||||
**
|
||||
*/
|
||||
#include "all.h"
|
||||
#include "ur/ur.h"
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "all.h"
|
||||
#include "ur/ur.h"
|
||||
|
||||
/* _cu_atom_to_ref(): allocate indirect atom off-loom.
|
||||
*/
|
||||
static inline ur_nref
|
||||
|
@ -1,8 +1,8 @@
|
||||
/* g/v.c
|
||||
**
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "all.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define _CVX_LOAD 4
|
||||
#define _CVX_PEEK 22
|
||||
|
@ -1,21 +1,5 @@
|
||||
/* 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 "vere/vere.h"
|
||||
|
||||
|
@ -2,11 +2,10 @@
|
||||
**
|
||||
** ethereum-integrated pre-boot validation
|
||||
*/
|
||||
#include <curl/curl.h>
|
||||
#include <uv.h>
|
||||
|
||||
#include "all.h"
|
||||
#include "vere/vere.h"
|
||||
#include <curl/curl.h>
|
||||
#include <uv.h>
|
||||
|
||||
/* _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
|
||||
*/
|
||||
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;
|
||||
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?
|
||||
//
|
||||
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_WRITEFUNCTION, _dawn_curl_alloc);
|
||||
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?
|
||||
//
|
||||
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_WRITEFUNCTION, _dawn_curl_alloc);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&buf_u);
|
||||
|
@ -1,17 +1,18 @@
|
||||
/* vere/db/lmdb.c
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <lmdb.h>
|
||||
|
||||
#include "c/portable.h"
|
||||
#include "c/types.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
|
||||
//
|
||||
@ -42,31 +43,28 @@ u3_lmdb_init(const c3_c* pax_c, size_t siz_i)
|
||||
c3_w ret_w;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Our databases have two tables: META and EVENTS
|
||||
//
|
||||
if ( (ret_w = mdb_env_set_maxdbs(env_u, 2)) ) {
|
||||
fprintf(stderr, "lmdb: failed to set number of databases: %s\r\n",
|
||||
mdb_strerror(ret_w));
|
||||
mdb_logerror(stderr, ret_w, "lmdb: failed to set number of databases");
|
||||
// XX dispose env_u
|
||||
//
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( (ret_w = mdb_env_set_mapsize(env_u, siz_i)) ) {
|
||||
fprintf(stderr, "lmdb: failed to set database size: %s\r\n",
|
||||
mdb_strerror(ret_w));
|
||||
mdb_logerror(stderr, ret_w, "lmdb: failed to set database size");
|
||||
// XX dispose env_u
|
||||
//
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( (ret_w = mdb_env_open(env_u, pax_c, 0, 0664)) ) {
|
||||
fprintf(stderr, "lmdb: failed to open event log: %s\r\n",
|
||||
mdb_strerror(ret_w));
|
||||
mdb_logerror(stderr, ret_w, "lmdb: failed to open event log");
|
||||
// XX dispose env_u
|
||||
//
|
||||
return 0;
|
||||
@ -111,18 +109,17 @@ u3_lmdb_stat(MDB_env* env_u, FILE* fil_u)
|
||||
}
|
||||
|
||||
{
|
||||
c3_i fid_i;
|
||||
struct stat sat_u;
|
||||
mdb_filehandle_t han_u;
|
||||
mdb_env_get_fd(env_u, &han_u);
|
||||
|
||||
mdb_env_get_fd(env_u, &fid_i);
|
||||
fstat(fid_i, &sat_u);
|
||||
intmax_t dis_i = mdb_get_filesize(han_u);
|
||||
|
||||
if ( siz_i != sat_u.st_size ) {
|
||||
if ( siz_i != dis_i ) {
|
||||
fprintf(fil_u, "MISMATCH:\n");
|
||||
}
|
||||
|
||||
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?
|
||||
//
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
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
|
||||
//
|
||||
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
|
||||
//
|
||||
if ( (ret_w = mdb_cursor_open(txn_u, mdb_u, &cur_u)) ) {
|
||||
fprintf(stderr, "lmdb: gulf: cursor_open fail: %s\r\n",
|
||||
mdb_strerror(ret_w));
|
||||
mdb_logerror(stderr, ret_w, "lmdb: gulf: cursor_open fail");
|
||||
// XX confirm
|
||||
//
|
||||
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;
|
||||
}
|
||||
else if ( ret_w ) {
|
||||
fprintf(stderr, "lmdb: gulf: head fail: %s\r\n",
|
||||
mdb_strerror(ret_w));
|
||||
mdb_logerror(stderr, ret_w, "lmdb: gulf: head fail");
|
||||
mdb_cursor_close(cur_u);
|
||||
mdb_txn_abort(txn_u);
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
else {
|
||||
@ -238,7 +233,7 @@ u3_lmdb_read(MDB_env* env_u,
|
||||
// create a read-only transaction.
|
||||
//
|
||||
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;
|
||||
}
|
||||
|
||||
@ -248,7 +243,7 @@ u3_lmdb_read(MDB_env* env_u,
|
||||
c3_w ops_w = MDB_CREATE | MDB_INTEGERKEY;
|
||||
|
||||
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
|
||||
//
|
||||
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]
|
||||
//
|
||||
if ( (ret_w = mdb_cursor_open(txn_u, mdb_u, &cur_u)) ) {
|
||||
fprintf(stderr, "lmdb: read: cursor_open fail: %s\r\n",
|
||||
mdb_strerror(ret_w));
|
||||
mdb_logerror(stderr, ret_w, "lmdb: read: cursor_open fail");
|
||||
// XX confirm
|
||||
//
|
||||
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]
|
||||
//
|
||||
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",
|
||||
eve_d,
|
||||
mdb_strerror(ret_w));
|
||||
mdb_logerror(stderr, ret_w, "lmdb: read: initial cursor_get failed at %" PRIu64, eve_d);
|
||||
mdb_cursor_close(cur_u);
|
||||
// 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))
|
||||
&& (MDB_NOTFOUND != ret_w) )
|
||||
{
|
||||
fprintf(stderr, "lmdb: read: error: %s\r\n",
|
||||
mdb_strerror(ret_w));
|
||||
mdb_logerror(stderr, ret_w, "lmdb: read: error");
|
||||
ret_o = c3n;
|
||||
break;
|
||||
}
|
||||
@ -359,7 +350,7 @@ u3_lmdb_save(MDB_env* env_u,
|
||||
// create a write transaction
|
||||
//
|
||||
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;
|
||||
}
|
||||
|
||||
@ -369,7 +360,7 @@ u3_lmdb_save(MDB_env* env_u,
|
||||
c3_w ops_w = MDB_CREATE | MDB_INTEGERKEY;
|
||||
|
||||
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);
|
||||
return c3n;
|
||||
}
|
||||
@ -401,7 +392,7 @@ u3_lmdb_save(MDB_env* env_u,
|
||||
// commit transaction
|
||||
//
|
||||
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;
|
||||
}
|
||||
|
||||
@ -423,16 +414,14 @@ u3_lmdb_read_meta(MDB_env* env_u,
|
||||
// create a read transaction
|
||||
//
|
||||
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_strerror(ret_w));
|
||||
mdb_logerror(stderr, ret_w, "lmdb: meta read: txn_begin fail");
|
||||
return read_f(ptr_v, 0, 0);
|
||||
}
|
||||
|
||||
// open the database in the transaction
|
||||
//
|
||||
if ( (ret_w = mdb_dbi_open(txn_u, "META", 0, &mdb_u)) ) {
|
||||
fprintf(stderr, "lmdb: meta read: dbi_open fail: %s\r\n",
|
||||
mdb_strerror(ret_w));
|
||||
mdb_logerror(stderr, ret_w, "lmdb: meta read: dbi_open fail");
|
||||
mdb_txn_abort(txn_u);
|
||||
return read_f(ptr_v, 0, 0);
|
||||
}
|
||||
@ -443,7 +432,7 @@ u3_lmdb_read_meta(MDB_env* env_u,
|
||||
MDB_val 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);
|
||||
return read_f(ptr_v, 0, 0);
|
||||
}
|
||||
@ -472,16 +461,14 @@ u3_lmdb_save_meta(MDB_env* env_u,
|
||||
// create a write transaction
|
||||
//
|
||||
if ( (ret_w = mdb_txn_begin(env_u, 0, 0, &txn_u)) ) {
|
||||
fprintf(stderr, "lmdb: meta write: txn_begin fail: %s\r\n",
|
||||
mdb_strerror(ret_w));
|
||||
mdb_logerror(stderr, ret_w, "lmdb: meta write: txn_begin fail");
|
||||
return c3n;
|
||||
}
|
||||
|
||||
// opens the database in the transaction
|
||||
//
|
||||
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_strerror(ret_w));
|
||||
mdb_logerror(stderr, ret_w, "lmdb: meta write: dbi_open fail");
|
||||
mdb_txn_abort(txn_u);
|
||||
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 };
|
||||
|
||||
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);
|
||||
return c3n;
|
||||
}
|
||||
@ -502,10 +489,31 @@ u3_lmdb_save_meta(MDB_env* env_u,
|
||||
// commit txn
|
||||
//
|
||||
if ( (ret_w = mdb_txn_commit(txn_u)) ) {
|
||||
fprintf(stderr, "lmdb: meta write: commit failed: %s\r\n",
|
||||
mdb_strerror(ret_w));
|
||||
mdb_logerror(stderr, ret_w, "lmdb: meta write: commit failed");
|
||||
return c3n;
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -1,21 +1,5 @@
|
||||
/* 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 "vere/vere.h"
|
||||
#include <vere/db/lmdb.h>
|
||||
|
@ -4,22 +4,6 @@
|
||||
*/
|
||||
|
||||
#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"
|
||||
|
||||
/* assumptions:
|
||||
|
@ -1,15 +1,6 @@
|
||||
/* 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 "vere/vere.h"
|
||||
#include "ur/serial.h"
|
||||
|
@ -1,13 +1,6 @@
|
||||
/* 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 "vere/vere.h"
|
||||
|
||||
|
@ -1,18 +1,10 @@
|
||||
/* 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 "vere/vere.h"
|
||||
#include <openssl/ssl.h>
|
||||
#include <h2o.h>
|
||||
|
||||
/* u3_csat: client connection state.
|
||||
*/
|
||||
@ -985,8 +977,8 @@ _cttp_init_tls(void)
|
||||
// SSL_OP_NO_TLSv1 | // XX test
|
||||
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_default_verify_paths(tls_u);
|
||||
SSL_CTX_set_session_cache_mode(tls_u, SSL_SESS_CACHE_OFF);
|
||||
SSL_CTX_set_cipher_list(tls_u,
|
||||
"ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:"
|
||||
|
@ -1,13 +1,6 @@
|
||||
/* 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 "vere/vere.h"
|
||||
|
||||
|
@ -1,13 +1,6 @@
|
||||
/* 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 "vere/vere.h"
|
||||
|
||||
|
@ -1,21 +1,12 @@
|
||||
/* vere/http.c
|
||||
**
|
||||
*/
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <netinet/in.h>
|
||||
#include <uv.h>
|
||||
#include <errno.h>
|
||||
#include "all.h"
|
||||
#include "vere/vere.h"
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <h2o.h>
|
||||
|
||||
#include "all.h"
|
||||
#include "vere/vere.h"
|
||||
|
||||
typedef struct _u3_h2o_serv {
|
||||
h2o_globalconf_t fig_u; // h2o global config
|
||||
h2o_context_t ctx_u; // h2o ctx
|
||||
@ -1468,7 +1459,7 @@ _http_serv_start(u3_http* htp_u)
|
||||
INADDR_ANY;
|
||||
|
||||
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);
|
||||
@ -1622,11 +1613,12 @@ _http_write_ports_file(u3_httd* htd_u, c3_c *pax_c)
|
||||
|
||||
u3_http* htp_u = htd_u->htp_u;
|
||||
|
||||
c3_c temp[32];
|
||||
while ( 0 != htp_u ) {
|
||||
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->lop) ? "loopback" : "public");
|
||||
(c3y == htp_u->lop) ? "loopback" : "public"));
|
||||
}
|
||||
|
||||
htp_u = htp_u->nex_u;
|
||||
|
@ -1,15 +1,6 @@
|
||||
/* 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 "vere/vere.h"
|
||||
|
||||
@ -25,12 +16,11 @@ static u3_utty* _term_main();
|
||||
static void _term_read_cb(uv_stream_t* tcp_u,
|
||||
ssize_t siz_i,
|
||||
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
|
||||
_write(c3_i fid_i, const void* buf_v, size_t len_i)
|
||||
void
|
||||
u3_write_fd(c3_i fid_i, const void* buf_v, size_t len_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
|
||||
//
|
||||
// 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 ) {
|
||||
fprintf(stderr, "term: write failed %s\r\n", strerror(errno));
|
||||
@ -133,28 +123,24 @@ _term_close_cb(uv_handle_t* han_t)
|
||||
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 ) {
|
||||
uty_u = c3_calloc(sizeof(u3_utty));
|
||||
uty_u->fid_i = 1;
|
||||
|
||||
uv_pipe_init(u3L, &(uty_u->pop_u), 0);
|
||||
uv_pipe_open(&(uty_u->pop_u), uty_u->fid_i);
|
||||
uv_pipe_init(u3L, &(uty_u->pin_u.pop_u), 0);
|
||||
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 {
|
||||
// Initialize event processing. Rawdog it.
|
||||
//
|
||||
{
|
||||
uty_u->fid_i = 0; // stdin, yes we write to it...
|
||||
|
||||
if ( !isatty(uty_u->fid_i) ) {
|
||||
fprintf(stderr, "vere: unable to initialize terminal (not a tty)\r\n"
|
||||
" use -t to disable interactivity\r\n");
|
||||
u3_king_bail();
|
||||
}
|
||||
|
||||
uv_pipe_init(u3L, &(uty_u->pop_u), 0);
|
||||
uv_pipe_open(&(uty_u->pop_u), uty_u->fid_i);
|
||||
const c3_c* err_c;
|
||||
if ( NULL == (uty_u = u3_ptty_init(u3L, &err_c)) ) {
|
||||
fprintf(stderr, "vere: unable to initialize terminal (%s)\r\n"
|
||||
" use -t to disable interactivity\r\n", err_c);
|
||||
u3_king_bail();
|
||||
}
|
||||
|
||||
// configure output escape sequences
|
||||
@ -187,33 +173,6 @@ u3_term_log_init(void)
|
||||
// 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.
|
||||
//
|
||||
{
|
||||
@ -254,18 +213,24 @@ u3_term_log_init(void)
|
||||
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 ( c3n == u3_Host.ops_u.tem ) {
|
||||
// Start raw input.
|
||||
//
|
||||
{
|
||||
if ( 0 != _term_tcsetattr(uty_u->fid_i, TCSADRAIN, &uty_u->raw_u) ) {
|
||||
c3_assert(!"init-tcsetattr");
|
||||
}
|
||||
if ( -1 == fcntl(uty_u->fid_i, F_SETFL, uty_u->nob_i) ) {
|
||||
c3_assert(!"init-fcntl");
|
||||
}
|
||||
if ( c3n == uty_u->sta_f(uty_u) ) {
|
||||
c3_assert(!"init-tcsetattr");
|
||||
}
|
||||
|
||||
// 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 ) {
|
||||
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");
|
||||
}
|
||||
if ( -1 == fcntl(uty_u->fid_i, F_SETFL, uty_u->cug_i) ) {
|
||||
c3_assert(!"exit-fcntl");
|
||||
}
|
||||
_write(uty_u->fid_i, "\r\n", 2);
|
||||
u3_write_fd(uty_u->fid_i, "\r\n", 2);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/* _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.
|
||||
*/
|
||||
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 ) {
|
||||
_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));
|
||||
}
|
||||
#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;
|
||||
c3_i fid_i;
|
||||
|
||||
if ( uv_fileno((uv_handle_t*)&uty_u->pop_u, &fid_i) ) {
|
||||
return;
|
||||
}
|
||||
c3_i fid_i = uty_u->fid_i;
|
||||
|
||||
// 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);
|
||||
c3_l col_l, row_l;
|
||||
|
||||
struct winsize siz_u;
|
||||
if ( (c3n == u3_Host.ops_u.tem) &&
|
||||
uty_u && (0 == ioctl(uty_u->fid_i, TIOCGWINSZ, &siz_u)) )
|
||||
if ( (c3y == u3_Host.ops_u.tem) || !uty_u ||
|
||||
(c3y != uty_u->wsz_f(uty_u, &col_l, &row_l)) )
|
||||
{
|
||||
col_l = siz_u.ws_col;
|
||||
row_l = siz_u.ws_row;
|
||||
}
|
||||
else {
|
||||
col_l = 80;
|
||||
row_l = 24;
|
||||
}
|
||||
@ -1460,32 +1393,18 @@ u3_term_io_hija(void)
|
||||
}
|
||||
else {
|
||||
if ( c3n == u3_Host.ops_u.tem ) {
|
||||
if ( 0 != _term_tcsetattr(1, TCSADRAIN, &uty_u->bak_u) ) {
|
||||
perror("hija-tcsetattr-1");
|
||||
if ( c3y != uty_u->hij_f(uty_u) ) {
|
||||
c3_assert(!"hija-tcsetattr");
|
||||
}
|
||||
if ( -1 == fcntl(1, F_SETFL, uty_u->cug_i) ) {
|
||||
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);
|
||||
u3_write_fd(uty_u->fid_i, "\r", 1);
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
else return stdout;
|
||||
return stdout;
|
||||
}
|
||||
|
||||
/* u3_term_io_loja(): release console from fprintf.
|
||||
@ -1505,24 +1424,10 @@ u3_term_io_loja(int x)
|
||||
else {
|
||||
if ( c3y == u3_Host.ops_u.tem ) {
|
||||
fflush(stdout);
|
||||
}
|
||||
else {
|
||||
if ( 0 != _term_tcsetattr(1, TCSADRAIN, &uty_u->raw_u) ) {
|
||||
perror("loja-tcsetattr-1");
|
||||
} else {
|
||||
if ( c3y != uty_u->loj_f(uty_u) ) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -1599,7 +1504,7 @@ _term_io_talk(u3_auto* car_u)
|
||||
if ( c3n == u3_Host.ops_u.tem ) {
|
||||
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_read_cb);
|
||||
}
|
||||
@ -1760,11 +1665,11 @@ _term_io_exit(u3_auto* car_u)
|
||||
{
|
||||
u3_utty* uty_u = _term_main();
|
||||
|
||||
// NB, closed in u3_term_log_exit()
|
||||
//
|
||||
uv_read_stop((uv_stream_t*)&(uty_u->pop_u));
|
||||
|
||||
if ( c3n == u3_Host.ops_u.tem ) {
|
||||
// NB, closed in u3_term_log_exit()
|
||||
//
|
||||
uv_read_stop((uv_stream_t*)&(uty_u->pin_u));
|
||||
|
||||
uv_timer_t* han_u = &(uty_u->tat_u.sun_u.tim_u);
|
||||
han_u->data = car_u;
|
||||
|
||||
|
@ -2,15 +2,7 @@
|
||||
**
|
||||
*/
|
||||
#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 "vere/vere.h"
|
||||
|
||||
struct _u3_umon;
|
||||
|
@ -2,13 +2,11 @@
|
||||
**
|
||||
** the main loop of the daemon process
|
||||
*/
|
||||
#include <curl/curl.h>
|
||||
#include <unistd.h>
|
||||
#include <uv.h>
|
||||
|
||||
#include "all.h"
|
||||
#include "vere/vere.h"
|
||||
#include "ur/ur.h"
|
||||
#include <curl/curl.h>
|
||||
#include <uv.h>
|
||||
|
||||
#include "ivory.h"
|
||||
|
||||
@ -217,8 +215,10 @@ _king_pier(u3_noun pier)
|
||||
** XX deduplicate with dawn.c
|
||||
*/
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
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_WRITEFUNCTION, _king_curl_alloc);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&buf_u);
|
||||
@ -546,7 +546,7 @@ _king_sign_init(void)
|
||||
|
||||
// handle SIGINFO (if available)
|
||||
//
|
||||
#ifndef U3_OS_linux
|
||||
#ifdef SIGINFO
|
||||
{
|
||||
u3_usig* sig_u;
|
||||
|
||||
@ -592,6 +592,10 @@ _king_sign_cb(uv_signal_t* sil_u, c3_i num_i)
|
||||
case SIGINT: {
|
||||
u3l_log("\r\ninterrupt\r\n");
|
||||
u3_term_ef_ctlc();
|
||||
|
||||
#if defined(U3_OS_mingw)
|
||||
PulseEvent(u3_Host.cev_u);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@ -602,7 +606,7 @@ _king_sign_cb(uv_signal_t* sil_u, c3_i num_i)
|
||||
|
||||
// fallthru if defined
|
||||
//
|
||||
#ifndef U3_OS_linux
|
||||
#ifdef SIGINFO
|
||||
case SIGINFO:
|
||||
#endif
|
||||
case SIGUSR1: {
|
||||
@ -679,7 +683,6 @@ _king_loop_init()
|
||||
void
|
||||
_king_loop_exit()
|
||||
{
|
||||
unlink(u3K.certs_c);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -752,12 +755,14 @@ u3_king_commence()
|
||||
u3C.sign_move_f = _king_sign_move;
|
||||
|
||||
// Ignore SIGPIPE signals.
|
||||
#ifndef U3_OS_mingw
|
||||
{
|
||||
struct sigaction sig_s = {{0}};
|
||||
sigemptyset(&(sig_s.sa_mask));
|
||||
sig_s.sa_handler = SIG_IGN;
|
||||
sigaction(SIGPIPE, &sig_s, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// boot the ivory pill
|
||||
//
|
||||
@ -765,6 +770,7 @@ u3_king_commence()
|
||||
|
||||
// disable core dumps (due to lmdb size)
|
||||
//
|
||||
#ifndef U3_OS_mingw
|
||||
{
|
||||
struct rlimit rlm;
|
||||
|
||||
@ -776,6 +782,7 @@ u3_king_commence()
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// run the loop
|
||||
//
|
||||
|
@ -1,21 +1,5 @@
|
||||
/* 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 "vere/vere.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_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);
|
||||
|
||||
#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_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.
|
||||
*/
|
||||
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 wag_c[11];
|
||||
c3_c hap_c[11];
|
||||
c3_c cev_c[11];
|
||||
c3_i err_i;
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
#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;
|
||||
#endif
|
||||
|
||||
uv_pipe_init(u3L, &god_u->inn_u.pyp_u, 0);
|
||||
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->err_u, 0);
|
||||
|
||||
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;
|
||||
@ -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].data.stream = (uv_stream_t *)&god_u->out_u;
|
||||
|
||||
god_u->cod_u[2].flags = UV_INHERIT_FD;
|
||||
god_u->cod_u[2].data.fd = 2;
|
||||
god_u->cod_u[2].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
|
||||
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_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.file = arg_c[0];
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -9,22 +9,6 @@
|
||||
** the implementation is relatively inefficient and could
|
||||
** 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 "vere/vere.h"
|
||||
|
||||
|
@ -1,26 +1,9 @@
|
||||
/* 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 "vere/vere.h"
|
||||
|
||||
#include <vere/db/lmdb.h>
|
||||
#include "vere/db/lmdb.h"
|
||||
#include <ent.h>
|
||||
|
||||
#define PIER_READ_BATCH 1000ULL
|
||||
#define PIER_PLAY_BATCH 500ULL
|
||||
@ -1628,7 +1611,7 @@ u3_pier_stay(c3_w wag_w, u3_noun pax)
|
||||
if ( c3y == u3_Host.ops_u.veb ) {
|
||||
FILE* fil_u = u3_term_io_hija();
|
||||
u3_lmdb_stat(pir_u->log_u->mdb_u, fil_u);
|
||||
u3_term_io_loja(1 );
|
||||
u3_term_io_loja(1);
|
||||
}
|
||||
|
||||
u3z(pax);
|
||||
|
@ -1,13 +1,6 @@
|
||||
/* 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 "vere/vere.h"
|
||||
|
||||
@ -20,6 +13,7 @@ _save_time_cb(uv_timer_t* tim_u)
|
||||
u3_pier_save(pir_u);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* u3_save_ef_chld(): report save termination.
|
||||
*/
|
||||
void
|
||||
@ -41,6 +35,7 @@ u3_save_ef_chld(u3_pier *pir_u)
|
||||
}
|
||||
sav_u->pid_w = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* u3_save_io_init(): initialize autosave.
|
||||
*/
|
||||
|
@ -1,12 +1,6 @@
|
||||
/* vere/time.c
|
||||
**
|
||||
*/
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <uv.h>
|
||||
|
||||
#include "all.h"
|
||||
#include "vere/vere.h"
|
||||
|
||||
@ -104,7 +98,7 @@ u3_time_in_ts(struct timespec* tim_ts)
|
||||
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_atom
|
||||
@ -117,7 +111,7 @@ u3_time_t_in_ts(time_t tim)
|
||||
|
||||
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.
|
||||
*/
|
||||
|
@ -1,13 +1,6 @@
|
||||
/* 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 "vere/vere.h"
|
||||
|
||||
|
@ -1,21 +1,5 @@
|
||||
/* 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 "vere/vere.h"
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user