Merge branch 'jb/rc' into release/next-vere

* jb/rc: (86 commits)
  kh: improve code style
  compat: minor refactoring
  compat: add m1brew
  kh: don't error during key validation
  kh: improve naming and code style
  compat: mingw: fix dependency patch path
  king: add crud event to jael
  king: fix noun derivation
  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
  tests, aqua: update  for recent changes
  vere: update argon2u dependency to urbit/argon2@a4c1e3f7
  compat: fix missing newlines at end of file
  vere: ignore more intermediate build files
  dawn: better multikey format
  vere: mingw: fix seh_handler_decorator.mk
  kh: support multikeyfiles
  kh: expose to/fromNoun template logic separately
  vere: mingw: get rid of libsigsegv
  vere: mingw: bump curl version and get rid of CURLOPT_SSL_CTX_FUNCTION typecheck warning
  ...
This commit is contained in:
Joe Bryan 2021-09-02 12:44:05 -04:00
commit 54d476ba0f
81 changed files with 4655 additions and 768 deletions

View File

@ -116,3 +116,24 @@ jobs:
- run: nix-build -A hs.urbit-king.components.exes.urbit-king --arg enableStatic true
- run: nix-build -A hs-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
View File

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

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

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

View File

@ -3,18 +3,26 @@
"branch": "master",
"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",

1
pkg/ent/configure vendored
View File

@ -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

View File

@ -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

View File

@ -85,7 +85,7 @@ instance FromNoun Pass where
-- seed. These aren't actually private keys, but public/private keypairs which
-- can be derived from these seeds.
data Ring = Ring { ringSign :: BS.ByteString, ringCrypt :: BS.ByteString }
deriving (Eq)
deriving (Eq, Ord)
instance ToNoun Ring where
toNoun Ring{..} =
@ -117,6 +117,36 @@ data Seed = Seed
}
deriving (Eq, Show)
data Germs = Germs
{ gShip :: Ship
, gFeed :: [Germ]
}
deriving (Eq, Show)
data Germ = Germ
{ gLife :: Life
, gRing :: Ring
}
deriving (Eq, Ord, Show)
data Feed
= Feed0 Seed
| Feed1 Germs
deriving (Eq, Show)
-- NOTE reify type environment
$(pure [])
instance ToNoun Feed where
toNoun = \case
Feed0 s -> $(deriveToNounFunc ''Seed) s
Feed1 s -> C (C (A 1) (A 0)) $ $(deriveToNounFunc ''Germs) s
instance FromNoun Feed where
parseNoun = \case
(C (C (A 1) (A 0)) s) -> Feed1 <$> $(deriveFromNounFunc ''Germs) s
n -> Feed0 <$> $(deriveFromNounFunc ''Seed) n
type Public = (Life, HoonMap Life Pass)
data Dnses = Dnses { dPri::Cord, dSec::Cord, dTer::Cord }
@ -145,6 +175,7 @@ data Dawn = MkDawn
deriveNoun ''Dnses
deriveNoun ''EthPoint
deriveNoun ''Seed
deriveNoun ''Germ
deriveNoun ''Dawn
@ -239,6 +270,16 @@ data BoatEv
deriveNoun ''BoatEv
-- Jael Events -----------------------------------------------------------------
data JaelEv
= JaelEvRekey () (Life, Ring)
| JaelEvCrud Path Noun
deriving (Eq, Show)
deriveNoun ''JaelEv
-- Timer Events ----------------------------------------------------------------
data BehnEv
@ -313,6 +354,7 @@ data BlipEv
| BlipEvBoat BoatEv
| BlipEvHttpClient HttpClientEv
| BlipEvHttpServer HttpServerEv
| BlipEvJael JaelEv
| BlipEvNewt NewtEv
| BlipEvSync SyncEv
| BlipEvTerm TermEv
@ -335,6 +377,7 @@ instance ToNoun Ev where
EvBlip v@BlipEvBoat{} -> reorgThroughNoun ("clay", v)
EvBlip v@BlipEvHttpClient{} -> reorgThroughNoun ("iris", v)
EvBlip v@BlipEvHttpServer{} -> reorgThroughNoun ("eyre", v)
EvBlip v@BlipEvJael{} -> reorgThroughNoun ("jael", v)
EvBlip v@BlipEvNewt{} -> reorgThroughNoun ("ames", v)
EvBlip v@BlipEvSync{} -> reorgThroughNoun ("clay", v)
EvBlip v@BlipEvTerm{} -> reorgThroughNoun ("dill", v)
@ -362,6 +405,7 @@ getSpinnerNameForEvent = \case
BlipEvBoat _ -> Just "boat"
BlipEvHttpClient _ -> Just "iris"
BlipEvHttpServer _ -> Just "eyre"
BlipEvJael _ -> Just "jael"
BlipEvNewt _ -> Just "newt"
BlipEvSync _ -> Just "clay"
BlipEvTerm t | isRet t -> Nothing

View File

@ -184,8 +184,9 @@ tryBootFromPill
-> Bool
-> Ship
-> LegacyBootEvent
-> Feed
-> RIO PierEnv ()
tryBootFromPill oExit pill lite ship boot = do
tryBootFromPill oExit pill lite ship boot feed = do
mStart <- newEmptyMVar
vSlog <- logSlogs
runOrExitImmediately vSlog (bootedPier vSlog) oExit mStart []
@ -193,7 +194,7 @@ tryBootFromPill oExit pill lite ship boot = do
bootedPier vSlog = do
view pierPathL >>= lockFile
rio $ logInfo "Starting boot"
sls <- Pier.booted vSlog pill lite ship boot
sls <- Pier.booted vSlog pill lite ship boot feed
rio $ logInfo "Completed boot"
pure sls
@ -395,7 +396,12 @@ testPill pax showPil showSeq = do
pill <- fromNounErr pillNoun & either (throwIO . uncurry ParseErr) pure
logInfo "Using pill to generate boot sequence."
bootSeq <- genBootSeq (Ship 0) pill False (Fake (Ship 0))
bootSeq <- genBootSeq
(Ship 0)
pill
False
(Fake (Ship 0))
(Feed1 $ Germs (Ship 0) [])
logInfo "Validate jam/cue and toNoun/fromNoun on pill value"
reJam <- validateNounVal pill
@ -500,12 +506,12 @@ newShip CLI.New{..} opts = do
let seed = mineComet (Set.fromList starList) eny
putStrLn ("boot: found comet " ++ renderShip (sShip seed))
putStrLn ("code: " ++ (tshow $ deriveCode $ sRing seed))
bootFromSeed pill seed
bootFromFeed pill $ Feed0 seed
CLI.BootFake name -> do
pill <- pillFrom nPillSource
ship <- shipFrom name
runTryBootFromPill pill name ship (Fake ship)
runTryBootFromPill pill name ship (Fake ship) (Feed1 $ Germs ship [])
CLI.BootFromKeyfile keyFile -> do
text <- readFileUtf8 keyFile
@ -514,13 +520,13 @@ newShip CLI.New{..} opts = do
Just (UW a) -> pure a
asNoun <- cueExn asAtom
seed :: Seed <- case fromNoun asNoun of
feed :: Feed <- case fromNoun asNoun of
Nothing -> error "Keyfile does not seem to contain a seed."
Just s -> pure s
pill <- pillFrom nPillSource
bootFromSeed pill seed
bootFromFeed pill feed
where
shipFrom :: Text -> RIO HostEnv Ship
@ -541,16 +547,16 @@ newShip CLI.New{..} opts = do
Nothing -> error "Urbit.ob didn't produce string with ~"
Just x -> pure x
bootFromSeed :: Pill -> Seed -> RIO HostEnv ()
bootFromSeed pill seed = do
ethReturn <- dawnVent nEthNode seed
bootFromFeed :: Pill -> Feed -> RIO HostEnv ()
bootFromFeed pill feed = do
ethReturn <- dawnVent nEthNode feed
case ethReturn of
Left x -> error $ unpack x
Right dawn -> do
let ship = sShip $ dSeed dawn
name <- nameFromShip ship
runTryBootFromPill pill name ship (Dawn dawn)
runTryBootFromPill pill name ship (Dawn dawn) feed
-- Now that we have all the information for running an application with a
-- PierConfig, do so.
@ -558,13 +564,14 @@ newShip CLI.New{..} opts = do
-> Text
-> Ship
-> LegacyBootEvent
-> Feed
-> RIO HostEnv ()
runTryBootFromPill pill name ship bootEvent = do
runTryBootFromPill pill name ship bootEvent feed = do
vKill <- view (kingEnvL . kingEnvKillSignal)
let pierConfig = toPierConfig (pierPath name) nSerfExe opts
let networkConfig = toNetworkConfig opts
runPierEnv pierConfig networkConfig vKill $
tryBootFromPill True pill nLite ship bootEvent
tryBootFromPill True pill nLite ship bootEvent feed
runShipEnv :: Maybe Text -> CLI.Run -> CLI.Opts -> TMVar () -> RIO PierEnv a
-> RIO HostEnv a
@ -642,13 +649,13 @@ checkDawn provider keyfilePath = do
Just (UW a) -> pure a
asNoun <- cueExn asAtom
seed :: Seed <- case fromNoun asNoun of
feed :: Feed <- case fromNoun asNoun of
Nothing -> error "Keyfile does not seem to contain a seed."
Just s -> pure s
print $ show seed
print $ show feed
e <- dawnVent provider seed
e <- dawnVent provider feed
print $ show e

View File

@ -335,45 +335,72 @@ retrievePoint endpoint block ship =
[x] -> pure x
_ -> error "JSON server returned multiple return values."
validateShipAndGetSponsor :: String -> TextBlockNum -> Seed -> RIO e Ship
validateShipAndGetSponsor endpoint block (Seed ship life ring oaf) =
case clanFromShip ship of
Ob.Comet -> validateComet
Ob.Moon -> validateMoon
_ -> validateRest
validateFeedAndGetSponsor :: String
-> TextBlockNum
-> Feed
-> RIO e (Seed, Ship)
validateFeedAndGetSponsor endpoint block = \case
Feed0 s -> do
r <- validateSeed s
case r of
Left e -> error e
Right r -> pure (s, r)
Feed1 s -> validateGerms s
where
validateComet = do
-- A comet address is the fingerprint of the keypair
let shipFromPass = cometFingerprint $ ringToPass ring
when (ship /= shipFromPass) $
error ("comet name doesn't match fingerprint " <> show ship <> " vs " <>
show shipFromPass)
when (life /= 1) $
error ("comet can never be re-keyed")
pure (shipSein ship)
validateGerms Germs{..} =
case gFeed of
[] -> error "no usable keys in keyfile"
(Germ{..}:f) -> do
let seed = Seed gShip gLife gRing Nothing
r :: Either String Ship
<- validateSeed seed
case r of
Left _ -> validateGerms $ Germs gShip f
Right r -> pure (seed, r)
validateMoon = do
-- TODO: The current code in zuse does nothing, but we should be able to
-- try to validate the oath against the current as exists planet on
-- chain.
pure $ shipSein ship
validateSeed (Seed ship life ring oaf) = do
case clanFromShip ship of
Ob.Comet -> pure validateComet
Ob.Moon -> pure validateMoon
_ -> validateRest
where
cometFromPass = cometFingerprint $ ringToPass ring
validateComet
-- A comet address is the fingerprint of the keypair
| (ship /= cometFromPass) =
Left ("comet name doesn't match fingerprint " <>
show ship <> " vs " <>
show cometFromPass)
| (life /= 1) =
Left "comet can never be re-keyed"
| otherwise =
Right (shipSein ship)
validateRest = do
putStrLn ("boot: retrieving " <> renderShip ship <> "'s public keys")
validateMoon =
-- TODO: The current code in zuse does nothing, but we should be able
-- to try to validate the oath against the current as exists planet
-- on chain.
Right $ shipSein ship
whoP <- retrievePoint endpoint block ship
case epNet whoP of
Nothing -> error "ship not keyed"
Just (netLife, pass, contNum, (hasSponsor, who), _) -> do
when (netLife /= life) $
error ("keyfile life mismatch; keyfile claims life " <>
show life <> ", but Azimuth claims life " <>
show netLife)
when ((ringToPass ring) /= pass) $
error "keyfile does not match blockchain"
-- TODO: The hoon code does a breach check, but the C code never
-- supplies the data necessary for it to function.
pure who
validateRest = do
putStrLn ("boot: retrieving " <> renderShip ship <> "'s public keys")
--TODO could cache this lookup
whoP <- retrievePoint endpoint block ship
case epNet whoP of
Nothing -> pure $ Left "ship not keyed"
Just (netLife, pass, contNum, (hasSponsor, who), _) -> do
if (netLife /= life) then
pure $ Left ("keyfile life mismatch; keyfile claims life " <>
show life <> ", but Azimuth claims life " <>
show netLife)
else if ((ringToPass ring) /= pass) then
pure $ Left "keyfile does not match blockchain"
-- TODO: The hoon code does a breach check, but the C code never
-- supplies the data necessary for it to function.
else
pure $ Right who
-- Walk through the sponsorship chain retrieving the actual sponsorship chain
@ -402,8 +429,8 @@ getSponsorshipChain endpoint block = loop
pure $ chain <> [(ship, ethPoint)]
-- Produces either an error or a validated boot event structure.
dawnVent :: HasLogFunc e => String -> Seed -> RIO e (Either Text Dawn)
dawnVent provider dSeed@(Seed ship life ring oaf) =
dawnVent :: HasLogFunc e => String -> Feed -> RIO e (Either Text Dawn)
dawnVent provider feed =
-- The type checker can't figure this out on its own.
(onLeft tshow :: Either SomeException Dawn -> Either Text Dawn) <$> try do
putStrLn ("boot: requesting ethereum information from " <> pack provider)
@ -417,7 +444,8 @@ dawnVent provider dSeed@(Seed ship life ring oaf) =
let dBloq = hexStrToAtom hexStrBlock
putStrLn ("boot: ethereum block #" <> tshow dBloq)
immediateSponsor <- validateShipAndGetSponsor provider hexStrBlock dSeed
(dSeed, immediateSponsor)
<- validateFeedAndGetSponsor provider hexStrBlock feed
dSponsor <- getSponsorshipChain provider hexStrBlock immediateSponsor
putStrLn "boot: retrieving galaxy table"
@ -431,7 +459,7 @@ dawnVent provider dSeed@(Seed ship life ring oaf) =
let dNode = Nothing
pure $ MkDawn{..}
pure MkDawn{..}
-- Comet List ------------------------------------------------------------------

View File

@ -79,12 +79,17 @@ genEntropy :: MonadIO m => m Entropy
genEntropy = Entropy . fromIntegral . bytesAtom <$> io (Ent.getEntropy 64)
genBootSeq :: HasKingEnv e
=> Ship -> Pill -> Bool -> LegacyBootEvent -> RIO e BootSeq
genBootSeq _ PillIvory {} _ _ = throwIO CannotBootFromIvoryPill
genBootSeq ship PillPill {..} lite boot = do
=> Ship -> Pill -> Bool -> LegacyBootEvent -> Feed -> RIO e BootSeq
genBootSeq _ PillIvory {} _ _ _ = throwIO CannotBootFromIvoryPill
genBootSeq ship PillPill {..} lite boot feed = do
ent <- io genEntropy
wyr <- wyrd
let ova = preKern ent <> [wyr] <> pKernelOva <> postKern <> pUserspaceOva
let ova = preKern ent
<> [wyr]
<> pKernelOva
<> postKern
<> extraKeys
<> pUserspaceOva
pure $ BootSeq ident pBootFormulae ova
where
ident = LogIdentity ship isFake (fromIntegral $ length pBootFormulae)
@ -96,6 +101,10 @@ genBootSeq ship PillPill {..} lite boot = do
isFake = case boot of
Fake _ -> True
_ -> False
extraKeys = case feed of
Feed0 _ -> []
Feed1 Germs{..} -> fmap rekey gFeed
rekey Germ{..} = EvBlip $ BlipEvJael $ JaelEvRekey () (gLife, gRing)
-- Write to the log. -----------------------------------------------------------
@ -160,9 +169,10 @@ booted
-> Bool
-> Ship
-> LegacyBootEvent
-> Feed
-> RAcquire PierEnv (Serf, EventLog)
booted vSlog pill lite ship boot = do
rio $ bootNewShip pill lite ship boot
booted vSlog pill lite ship boot feed = do
rio $ bootNewShip pill lite ship boot feed
resumed vSlog Nothing
bootSeqJobs :: Time.Wen -> BootSeq -> [Job]
@ -183,9 +193,10 @@ bootNewShip
-> Bool
-> Ship
-> LegacyBootEvent
-> Feed
-> RIO e ()
bootNewShip pill lite ship bootEv = do
seq@(BootSeq ident x y) <- genBootSeq ship pill lite bootEv
bootNewShip pill lite ship bootEv feed = do
seq@(BootSeq ident x y) <- genBootSeq ship pill lite bootEv feed
logInfo "BootSeq Computed"
pierPath <- view pierPathL

View File

@ -1,7 +1,7 @@
{-|
Template Haskell Code to Generate FromNoun and ToNoun Instances
-}
module Urbit.Noun.TH (deriveNoun, deriveToNoun, deriveFromNoun) where
module Urbit.Noun.TH (deriveNoun, deriveToNoun, deriveFromNoun, deriveToNounFunc, deriveFromNounFunc) where
import ClassyPrelude hiding (fromList)
import Control.Monad.Fail (fail)
@ -83,13 +83,9 @@ deriveNoun n = (<>) <$> deriveToNoun n <*> deriveFromNoun n
deriveToNoun :: Name -> Q [Dec]
deriveToNoun tyName = do
(params, shape) <- typeShape tyName
let exp = case shape of Vod -> vodToNoun
Tup con -> tupToNoun con
-- Enu cons -> enumToAtom cons
Sum atoms cells -> sumToNoun atoms cells
(params, _) <- typeShape tyName
exp <- deriveToNounFunc tyName
params <- pure $ zip ['a' ..] params <&> \(n,_) -> mkName (singleton n)
let ty = foldl' (\acc v -> AppT acc (VarT v)) (ConT tyName) params
@ -101,6 +97,15 @@ deriveToNoun tyName = do
pure [InstanceD overlap ctx inst [ValD (VarP 'toNoun) body []]]
deriveToNounFunc :: Name -> Q Exp
deriveToNounFunc tyName = do
(_, shape) <- typeShape tyName
pure case shape of
Vod -> vodToNoun
Tup con -> tupToNoun con
-- Enu cons -> enumToAtom cons
Sum atoms cells -> sumToNoun atoms cells
--------------------------------------------------------------------------------
addErrTag :: String -> Exp -> Exp
@ -111,13 +116,9 @@ addErrTag tag exp =
deriveFromNoun :: Name -> Q [Dec]
deriveFromNoun tyName = do
(params, shape) <- typeShape tyName
let exp = case shape of Vod -> vodFromNoun
Tup con -> tupFromNoun con
-- Enu cons -> enumFromAtom cons
Sum atoms cells -> sumFromNoun atoms cells
(params, _) <- typeShape tyName
exp <- deriveFromNounFunc tyName
params <- pure $ zip ['a' ..] params <&> \(n,_) -> mkName (singleton n)
let ty = foldl' (\acc v -> AppT acc (VarT v)) (ConT tyName) params
@ -129,6 +130,15 @@ deriveFromNoun tyName = do
pure [InstanceD overlap ctx inst [ValD (VarP 'parseNoun) body []]]
deriveFromNounFunc :: Name -> Q Exp
deriveFromNounFunc tyName = do
(_, shape) <- typeShape tyName
pure case shape of
Vod -> vodFromNoun
Tup con -> tupFromNoun con
-- Enu cons -> enumFromAtom cons
Sum atoms cells -> sumFromNoun atoms cells
sumFromNoun :: [(String, Name)] -> [(String, ConInfo)] -> Exp
sumFromNoun [] cl = taggedFromNoun cl
sumFromNoun at [] = enumFromAtom at

View File

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

View File

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

View File

@ -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 $^

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

84
pkg/urbit/configure vendored
View File

@ -1,12 +1,12 @@
#!/usr/bin/env bash
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

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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.
**/
@ -1289,7 +1317,8 @@
u3_noun who, // identity
u3_noun ven, // boot event
u3_noun pil, // type-of/path-to pill
u3_noun pax); // path to pier
u3_noun pax, // path to pier
u3_weak fed); // extra private keys
/* u3_pier_stay(): restart the new pier system.
*/
@ -1334,7 +1363,7 @@
/* u3_dawn_vent(): validated boot event
*/
u3_noun
u3_dawn_vent(u3_noun seed);
u3_dawn_vent(u3_noun ship, u3_noun seed);
/* u3_king_commence(): start the daemon
*/
@ -1371,6 +1400,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);

View File

@ -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.

View File

@ -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);
}

View File

@ -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
*/

View File

@ -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
}
}

View File

@ -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

View File

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

View File

@ -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"

View File

@ -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);
@ -209,7 +210,10 @@ _dawn_fail(u3_noun who, u3_noun rac, u3_noun sas)
u3l_log("boot: invalid keys for %s '%s'\r\n", rac_c, how_c);
// XX deconstruct sas, print helpful error messages
u3m_p("pre-boot error", u3t(sas));
while ( u3_nul != sas ) {
u3m_p("pre-boot error", u3h(sas));
sas = u3t(sas);
}
u3z(how);
c3_free(how_c);
@ -310,7 +314,7 @@ _dawn_sponsor(u3_noun who, u3_noun rac, u3_noun pot)
u3_noun uni = u3dc("sponsor:dawn", u3k(who), u3k(pot));
if ( c3n == u3h(uni) ) {
_dawn_fail(who, rac, uni);
_dawn_fail(who, rac, u3nc(u3t(uni), u3_nul));
return u3_none;
}
@ -324,11 +328,10 @@ _dawn_sponsor(u3_noun who, u3_noun rac, u3_noun pot)
/* u3_dawn_vent(): validated boot event
*/
u3_noun
u3_dawn_vent(u3_noun seed)
u3_dawn_vent(u3_noun ship, u3_noun feed)
{
u3_noun url, bok, pos, pon, zar, tuf;
u3_noun url, bok, sed, pos, pon, zar, tuf;
u3_noun ship = u3k(u3h(seed));
u3_noun rank = u3do("clan:title", u3k(ship));
url = _dawn_purl(rank);
@ -366,22 +369,17 @@ u3_dawn_vent(u3_noun seed)
pot = u3v_wish("*point:azimuth");
}
else {
u3_noun who;
who = u3k(ship);
u3l_log("boot: retrieving %s's public keys\r\n",
u3_Host.ops_u.who_c);
{
u3_noun oct = u3dc("point:give:dawn", u3k(bok), u3k(who));
u3_noun oct = u3dc("point:give:dawn", u3k(bok), u3k(ship));
u3_noun luh = _dawn_eth_rpc(url_c, u3k(oct));
pot = _dawn_need_unit(u3dc("point:take:dawn", u3k(ship), u3k(luh)),
"boot: failed to retrieve public keys");
u3z(oct); u3z(luh);
}
u3z(who);
}
// +live:dawn: network state
@ -392,13 +390,13 @@ u3_dawn_vent(u3_noun seed)
u3l_log("boot: verifying keys\r\n");
// (each sponsor=ship error=@tas)
// (each seed (lest error=@tas))
//
u3_noun sas = u3dt("veri:dawn", u3k(seed), u3k(pot), u3k(liv));
sed = u3dq("veri:dawn", u3k(ship), u3k(feed), u3k(pot), u3k(liv));
if ( u3_nul != sas ) {
if ( c3n == u3h(sed) ) {
// bails, won't return
_dawn_fail(ship, rank, sas);
_dawn_fail(ship, rank, u3t(sed));
return u3_none;
}
@ -458,7 +456,6 @@ u3_dawn_vent(u3_noun seed)
son = _dawn_need_unit(u3dc("point:take:dawn", u3k(pos), u3k(luh)),
"boot: failed to retrieve sponsor keys");
// append to sponsor chain list
//
pon = u3nc(u3nc(u3k(pos), u3k(son)), pon);
@ -475,11 +472,14 @@ u3_dawn_vent(u3_noun seed)
u3z(son);
}
u3z(rank); u3z(pos); u3z(ship);
// [%dawn seed sponsors galaxies domains block eth-url snap]
//
return u3nc(c3__dawn, u3nq(seed, pon, zar, u3nt(tuf, bok, url)));
u3_noun ven = u3nc(c3__dawn,
u3nq(u3k(u3t(sed)), pon, zar, u3nt(tuf, bok, url)));
u3z(sed); u3z(rank); u3z(pos); u3z(ship); u3z(feed);
return ven;
}
/* _dawn_come(): mine a comet under a list of stars

View File

@ -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

View File

@ -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>

View File

@ -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:

View File

@ -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"

View File

@ -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"

View File

@ -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:"

View File

@ -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"

View File

@ -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"

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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"
@ -159,7 +157,7 @@ _king_fake(u3_noun ship, u3_noun pill, u3_noun path)
// XX link properly
//
u3_noun vent = u3nc(c3__fake, u3k(ship));
u3K.pir_u = u3_pier_boot(sag_w, ship, vent, pill, path);
u3K.pir_u = u3_pier_boot(sag_w, ship, vent, pill, path, u3_none);
}
/* _king_come(): mine a comet under star (unit)
@ -182,7 +180,7 @@ _king_slog(u3_noun hod)
/* _king_dawn(): boot from keys, validating
*/
void
_king_dawn(u3_noun seed, u3_noun pill, u3_noun path)
_king_dawn(u3_noun feed, u3_noun pill, u3_noun path)
{
// enable ivory slog printfs
//
@ -190,8 +188,10 @@ _king_dawn(u3_noun seed, u3_noun pill, u3_noun path)
// XX link properly
//
u3_noun vent = u3_dawn_vent(seed);
u3K.pir_u = u3_pier_boot(sag_w, u3k(u3h(seed)), vent, pill, path);
//NOTE +slav is safe because _boothack_key already verified it
u3_noun ship = u3dc("slav", 'p', u3i_string(u3_Host.ops_u.who_c));
u3_noun vent = u3_dawn_vent(u3k(ship), u3k(feed));
u3K.pir_u = u3_pier_boot(sag_w, ship, vent, pill, path, feed);
// disable ivory slog printfs
//
@ -217,8 +217,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 +248,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);
@ -378,7 +380,8 @@ _boothack_pill(void)
static u3_noun
_boothack_key(u3_noun kef)
{
u3_noun seed, ship;
u3_noun seed;
u3_weak ship = u3_none;
{
u3_noun des = u3dc("slaw", c3__uw, u3k(kef));
@ -390,19 +393,24 @@ _boothack_key(u3_noun kef)
exit(1);
}
// +seed:able:jael: private key file
// +feed:able:jael: keyfile
//
u3_noun pro = u3m_soft(0, u3ke_cue, u3k(u3t(des)));
if ( u3_blip != u3h(pro) ) {
u3l_log("dawn: unable to cue private key\r\n");
u3l_log("dawn: unable to cue keyfile\r\n");
exit(1);
}
seed = u3k(u3t(pro));
u3z(pro);
// local reference, not counted
// if it's a single seed, we can trivially sanity-check early
//
ship = u3h(seed);
if ( c3y == u3ud(u3h(seed)) ) {
// local reference, not counted
//
ship = u3h(seed);
}
u3z(des);
u3z(kef);
}
@ -417,7 +425,9 @@ _boothack_key(u3_noun kef)
exit(1);
}
if ( c3n == u3r_sing(ship, u3t(whu)) ) {
if ( (u3_none != ship) &&
(c3n == u3r_sing(ship, u3t(whu))) )
{
u3_noun how = u3dc("scot", 'p', u3k(ship));
c3_c* how_c = u3r_string(u3k(how));
u3l_log("dawn: mismatch between -w %s and -K %s\r\n",
@ -546,7 +556,7 @@ _king_sign_init(void)
// handle SIGINFO (if available)
//
#ifndef U3_OS_linux
#ifdef SIGINFO
{
u3_usig* sig_u;
@ -592,6 +602,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 +616,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 +693,6 @@ _king_loop_init()
void
_king_loop_exit()
{
unlink(u3K.certs_c);
}
static void
@ -752,12 +765,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 +780,7 @@ u3_king_commence()
// disable core dumps (due to lmdb size)
//
#ifndef U3_OS_mingw
{
struct rlimit rlm;
@ -776,6 +792,7 @@ u3_king_commence()
exit(1);
}
}
#endif
// run the loop
//

View File

@ -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)

View File

@ -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"

View File

@ -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);
@ -1732,7 +1715,11 @@ _pier_pill_parse(u3_noun pil)
/* _pier_boot_make(): construct boot sequence
*/
static u3_boot
_pier_boot_make(u3_noun who, u3_noun wyr, u3_noun ven, u3_noun pil)
_pier_boot_make(u3_noun who,
u3_noun wyr,
u3_noun ven,
u3_noun pil,
u3_weak fed)
{
u3_boot bot_u = _pier_pill_parse(pil); // transfer
@ -1756,6 +1743,20 @@ _pier_boot_make(u3_noun who, u3_noun wyr, u3_noun ven, u3_noun pil)
bot_u.mod = u3nc(u3nc(wir, wyr), bot_u.mod); // transfer [wir] and [wyr]
}
// include additional key configuration events if we have multiple keys
//
if ( (u3_none != fed) && (c3y == u3du(u3h(fed))) ) {
u3_noun wir = u3nt(c3__j, c3__seed, u3_nul);
u3_noun tag = u3i_string("rekey");
u3_noun kyz = u3t(u3t(fed));
while ( u3_nul != kyz ) {
u3_noun cad = u3nc(u3k(tag), u3k(u3h(kyz)));
bot_u.use = u3nc(u3nc(u3k(wir), cad), bot_u.use);
kyz = u3t(kyz);
}
u3z(tag); u3z(wir);
}
// prepend legacy boot event to the userspace sequence
//
{
@ -1770,13 +1771,18 @@ _pier_boot_make(u3_noun who, u3_noun wyr, u3_noun ven, u3_noun pil)
bot_u.use = u3nc(u3nc(wir, cad), bot_u.use);
}
u3z(fed);
return bot_u;
}
/* _pier_boot_plan(): construct and commit boot sequence
*/
static c3_o
_pier_boot_plan(u3_pier* pir_u, u3_noun who, u3_noun ven, u3_noun pil)
_pier_boot_plan(u3_pier* pir_u,
u3_noun who,
u3_noun ven,
u3_noun pil,
u3_weak fed)
{
u3_boot bot_u;
{
@ -1784,7 +1790,7 @@ _pier_boot_plan(u3_pier* pir_u, u3_noun who, u3_noun ven, u3_noun pil)
pir_u->fak_o = ( c3__fake == u3h(ven) ) ? c3y : c3n;
u3r_chubs(0, 2, pir_u->who_d, who);
bot_u = _pier_boot_make(who, _pier_wyrd_card(pir_u), ven, pil);
bot_u = _pier_boot_make(who, _pier_wyrd_card(pir_u), ven, pil, fed);
pir_u->lif_w = u3qb_lent(bot_u.bot);
}
@ -1859,7 +1865,8 @@ u3_pier_boot(c3_w wag_w, // config flags
u3_noun who, // identity
u3_noun ven, // boot event
u3_noun pil, // type-of/path-to pill
u3_noun pax) // path to pier
u3_noun pax, // path to pier
u3_weak fed) // extra private keys
{
u3_pier* pir_u;
@ -1871,7 +1878,7 @@ u3_pier_boot(c3_w wag_w, // config flags
// XX must be called from on_lord_live
//
if ( c3n == _pier_boot_plan(pir_u, who, ven, pil) ) {
if ( c3n == _pier_boot_plan(pir_u, who, ven, pil, fed) ) {
fprintf(stderr, "pier: boot plan fail\r\n");
// XX dispose
//

View File

@ -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.
*/

View File

@ -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.
*/

View File

@ -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"

View File

@ -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"

View File

@ -2,23 +2,8 @@
**
** the main loop of a serf process.
*/
#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 "rsignal.h"
#include <vere/vere.h>
#include <vere/serf.h>
@ -146,7 +131,7 @@ _cw_serf_stdio(c3_i* inn_i, c3_i* out_i)
// we replace [FD 0] (stdin) with a fd pointing to /dev/null
// we replace [FD 1] (stdout) with a dup of [FD 2] (stderr)
//
c3_i nul_i = open("/dev/null", O_RDWR, 0);
c3_i nul_i = open(c3_dev_null, O_RDWR, 0);
*inn_i = dup(0);
*out_i = dup(1);
@ -155,6 +140,11 @@ _cw_serf_stdio(c3_i* inn_i, c3_i* out_i)
dup2(2, 1);
close(nul_i);
// set stream I/O to unbuffered because it's now a pipe not a console
//
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
}
/* _cw_serf_stdio(): cleanup on serf exit.
@ -166,6 +156,16 @@ _cw_serf_exit(void)
u3t_trace_close();
}
#if defined(U3_OS_mingw)
/* _mingw_ctrlc_cb(): invoked when the lord signals the Ctrl-C event
*/
static void
_mingw_ctrlc_cb(PVOID param, BOOLEAN timedOut)
{
rsignal_raise(SIGINT);
}
#endif
/* _cw_serf_commence(); initialize and run serf
*/
static void
@ -174,7 +174,23 @@ _cw_serf_commence(c3_i argc, c3_c* argv[])
c3_i inn_i, out_i;
_cw_serf_stdio(&inn_i, &out_i);
#if defined(U3_OS_mingw)
c3_assert( 8 == argc );
// Initialize serf's end of Ctrl-C handling
//
{
HANDLE h;
if ( 1 != sscanf(argv[7], "%u", &h) ) {
fprintf(stderr, "serf: Ctrl-C event: bad handle %s: %s\r\n", argv[7], strerror(errno));
} else
if ( !RegisterWaitForSingleObject(&h, h, _mingw_ctrlc_cb, NULL, INFINITE, 0) ) {
fprintf(stderr, "serf: Ctrl-C event: RegisterWaitForSingleObject(%u) failed (%d)\r\n", h, GetLastError());
}
}
#else
c3_assert( 7 == argc );
#endif
uv_loop_t* lup_u = uv_default_loop();
c3_c* dir_c = argv[2];
@ -211,12 +227,14 @@ _cw_serf_commence(c3_i argc, c3_c* argv[])
// 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
// configure pipe to daemon process
//
@ -444,7 +462,11 @@ _cw_usage(c3_i argc, c3_c* argv[])
" cue persistent state:\n"
" %s queu <pier> <at-event>\n\n"
" run as a 'serf':\n"
" %s serf <pier> <key> <flags> <cache-size> <at-event>\n",
" %s serf <pier> <key> <flags> <cache-size> <at-event>"
#if defined(U3_OS_mingw)
" <ctrlc-handle>"
#endif
"\n",
argv[0], argv[0], argv[0], argv[0], argv[0], argv[0], argv[0]);
}

View File

@ -1,21 +1,5 @@
/* worker/serf.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/serf.h>