New event system; activate with -j.

This commit is contained in:
C. Guy Yarvin 2016-12-30 13:26:59 -05:00
parent 4126bd39b1
commit f30fc4b218
30 changed files with 43108 additions and 139 deletions

View File

@ -66,6 +66,7 @@ CURLLIB=$(shell curl-config --libs)
RM=rm -f
CC=cc
LN=ln -f
CXX=c++
CXXFLAGS=$(CFLAGS)
CLD=c++ $(CFLAGS) -L/usr/local/lib $(OPTLOCALLFLAGS) $(OPENSSLLFLAGS)
@ -355,6 +356,7 @@ V_OFILES=\
vere/cttp.o \
vere/http.o \
vere/loop.o \
vere/newt.o \
vere/raft.o \
vere/reck.o \
vere/sist.o \
@ -362,7 +364,11 @@ V_OFILES=\
vere/time.o \
vere/unix.o \
vere/save.o \
vere/walk.o
vere/serf.o \
vere/pier.o \
vere/foil.o \
vere/walk.o \
vere/ivory.o
MAIN_FILE =\
vere/main.o
@ -412,7 +418,7 @@ TAGS=\
GPATH GTAGS GRTAGS \
cscope.in.out cscope.po.out cscope.out
all: urbit
all: urbit links
.MAKEFILE-VERSION: Makefile .make.conf
@echo "Makefile update."
@ -421,6 +427,9 @@ all: urbit
.make.conf:
@echo "# Set custom configuration here, please!" > ".make.conf"
links: urbit
$(LN) $(BIN)/urbit $(BIN)/urbit-worker
urbit: $(BIN)/urbit
$(LIBUV_MAKEFILE) $(LIBUV_MAKEFILE2):

View File

@ -90,3 +90,5 @@
c3_assert(!"memory lost"); \
} \
rut;})
#define c3_free(s) free(s)
#define c3_realloc(s, l) realloc(s, l)

View File

@ -73,6 +73,11 @@
c3_o
u3e_live(c3_o nuu_o, c3_c* dir_c);
/* u3e_live_new(): start the persistence system.
*/
c3_o
u3e_live_new(c3_c* dir_c);
/* u3e_dirty(): count dirty pages.
*/
c3_w

View File

@ -10,7 +10,7 @@
*/
u3_noun
u3i_words(c3_w a_w,
const c3_w* b_w);
const c3_w* b_w);
/* u3i_bytes():
**
@ -18,7 +18,7 @@
*/
u3_noun
u3i_bytes(c3_w a_w,
const c3_y* b_y);
const c3_y* b_y);
/* u3i_mp():
**
@ -76,7 +76,7 @@
*/
u3_atom
u3i_chubs(c3_w a_w,
const c3_d* b_d);
const c3_d* b_d);
/* u3i_tape(): from a C string, to a list of bytes.
*/

View File

@ -7,7 +7,18 @@
/* u3m_boot(): start the u3 system.
*/
void
u3m_boot(c3_o nuu_o, c3_o bug_o, c3_c* dir_c, c3_c *pil_c);
u3m_boot(c3_o nuu_o, c3_c* dir_c, c3_c *pil_c);
/* u3m_boot_new(): start the u3 system (new). return next event,
** starting from 1.
*/
c3_d
u3m_boot_new(c3_c* dir_c);
/* u3m_boot_pier(): start without checkpointing.
*/
c3_d
u3m_boot_pier(void);
/* u3m_bail(): bail out. Does not return.
**

View File

@ -409,6 +409,16 @@
c3_w* c_w,
u3_atom d);
/* u3r_chubs():
**
** Copy double-words (a_w) through (a_w + b_w - 1) from (d) to (c).
*/
void
u3r_chubs(c3_w a_w,
c3_w b_w,
c3_d* c_d,
u3_atom d);
/* u3r_string(): `a`, a text atom, as malloced C string.
*/
c3_c*

View File

@ -31,6 +31,7 @@
u3_noun roe; // temporary unsaved events
u3_noun key; // log key, or 0
u3_noun sys; // system pill
u3_noun ken; // kernel formula
u3_noun roc; // kernel core
@ -69,6 +70,11 @@
void
u3v_boot(c3_c* pas_c);
/* u3v_boot_lite(): light bootstrap sequence, just making a kernel.
*/
void
u3v_boot_lite(u3_noun lit);
/* u3v_make(): make a new pier by loading a pill.
*/
void

View File

@ -199,6 +199,78 @@
c3_y hun_y[0]; // data
} u3_apac;
/* u3_poke: poke callback function.
*/
typedef void (*u3_poke)(void*, u3_noun);
/* u3_bail: bailout callback function.
*/
typedef void (*u3_bail)(void*, const c3_c* err_c);
/* u3_done: completion function.
*/
typedef void (*u3_done)(void *);
/* u3_mess: blob message in process.
*/
typedef struct _u3_mess {
c3_d len_d; // blob length in bytes
c3_d has_d; // currently held
struct _u3_meat* meq_u; // exit of message queue
struct _u3_meat* qem_u; // entry of message queue
} u3_mess;
/* u3_meat: blob message block.
*/
typedef struct _u3_meat {
struct _u3_meat* nex_u;
c3_d len_d;
c3_y hun_y[0];
} u3_meat;
/* u3_moat: inbound message stream.
*/
typedef struct _u3_moat {
uv_pipe_t pyp_u; // input stream
void* vod_p; // callback pointer
u3_poke pok_f; // action function
u3_bail bal_f; // error response function
struct _u3_mess* mes_u; // message in progress
c3_d len_d; // length of stray bytes
c3_y* rag_y; // stray bytes
} u3_moat;
/* u3_mojo: outbound message stream.
*/
typedef struct _u3_mojo {
uv_pipe_t pyp_u; // output stream
u3_bail bal_f; // error response function
} u3_mojo;
/* u3_foil: abstract chub-addressed file.
*/
typedef struct _u3_foil {
uv_file fil_u; // libuv file handle
struct _u3_dire* dir_u; // parent directory
c3_c* nam_c; // name within parent
c3_d end_d; // end of file
} u3_foil;
/* u3_dent: directory entry.
*/
typedef struct _u3_dent {
c3_c* nam_c;
struct _u3_dent* nex_u;
} u3_dent;
/* u3_dire: simple directory state.
*/
typedef struct _u3_dire {
c3_c* pax_c; // path of directory
uv_file fil_u; // file, opened read-only to fsync
u3_dent* all_u; // file list
} u3_dire;
/* u3_ames: ames networking.
*/
typedef struct _u3_ames { // packet network state
@ -537,17 +609,19 @@
c3_c* tic_c; // -t, ticket value
c3_c* pil_c; // -B, bootstrap from
c3_c* arv_c; // -A, initial sync from
c3_c* lit_c; // -J, ivory (fastboot) kernel
c3_c* gen_c; // -G, czar generator
c3_w kno_w; // -k, kernel version
c3_w fuz_w; // -f, fuzz testing
c3_s por_s; // -p, ames port
c3_s rop_s; // -l, raft port
c3_o abo; // -a
c3_o abo; // -a, abort aggressively
c3_o bat; // -b, batch create
c3_o gab; // -g
c3_o gab; // -g, test garbage collection
c3_o dem; // -d, daemon
c3_o dry; // -D, dry compute
c3_o dry; // -D, dry compute, no checkpoint
c3_o tex; // -x, exit after loading
c3_o mad; // -j, run manager
c3_o fog; // -X, skip last event
c3_o fak; // -F, fake carrier
c3_o loh; // -L, local-only networking
@ -555,7 +629,7 @@
c3_o veb; // -v, verbose (inverse of -q)
c3_o nuu; // -c, new pier
c3_o qui; // -q, quiet
c3_o vno; // -V, replay without reboots
c3_o vno; // -V, turn on +verb
c3_o mem; // -M, memory madness
c3_o rep; // -R, report build info
} u3_opts;
@ -581,15 +655,100 @@
void* ssl_u; // struct SSL_CTX*
} u3_host; // host == computer == process
/** New pier system.
**/
/* u3_writ: inbound event.
*/
typedef struct _u3_writ {
struct _u3_pier* pir_u; // backpointer to pier
u3_noun job; // (pair date ovum)
c3_d evt_d; // event number
u3_noun now; // event time
c3_l msc_l; // ms to timeout
c3_l mug_l; // hash before executing
u3_foil* fol_u; // precommit file
u3_atom mat; // jammed $work, or 0
u3_noun act; // action list
struct _u3_writ* nex_u; // next in queue, or 0
} u3_writ;
/* u3_lord: working process controller.
*/
typedef struct _u3_lord {
uv_process_t cub_u; // process handle
uv_process_options_t ops_u; // process configuration
uv_stdio_container_t cod_u[3]; // process options
time_t wen_t; // process creation time
u3_mojo inn_u; // client's stdin
u3_moat out_u; // client's stdout
c3_d sen_d; // last event dispatched
c3_d dun_d; // last event completed
c3_d rel_d; // last event released
c3_l mug_l; // mug after last completion
struct _u3_pier* pir_u; // pier backpointer
} u3_lord;
/* u3_disk: manage events on disk.
**
** any event once discovered should be in one of these sets.
** at present, all sets are ordered and can be defined by a
** simple counter. any events <= the counter is in the set.
*/
typedef struct _u3_disk {
u3_dire* dir_u; // main pier directory
u3_dire* urb_u; // urbit system data
u3_dire* com_u; // log directory
u3_dire* pre_u; // precommit directory
u3_foil* fol_u; // logfile
c3_d end_d; // byte end of file
c3_d rep_d; // precommit requested
c3_d pre_d; // precommitted
c3_d moc_d; // commit requested
c3_d com_d; // committed
struct _u3_pier* pir_u; // pier backpointer
} u3_disk;
/* u3_boot: startup controller.
*/
typedef struct _u3_boot {
} u3_boot;
/* u3_pier: ship controller.
*/
typedef struct _u3_pier {
c3_c* pax_c; // pier directory
c3_c* sys_c; // pill directory
c3_d gen_d; // last event discovered
c3_d but_d; // boot barrier
c3_d key_d[4]; // save and passkey
u3_disk* log_u; // event log
u3_lord* god_u; // computer
u3_writ* ent_u; // entry of queue
u3_writ* ext_u; // exit of queue
} u3_pier;
/* u3_king: all executing piers.
*/
typedef struct _u3_king {
c3_w len_w; // number of lords used
c3_w all_w; // number of lords allocated
u3_pier** tab_u; // lord table
} u3_king;
static u3_king u3K;
# define u3L u3_Host.lup_u // global event loop
# define u3Z (&(u3_Raft))
# define u3S u3_Host.ssl_u
# define u3K u3_King
/** Global variables.
**/
c3_global u3_host u3_Host;
c3_global u3_raft u3_Raft;
c3_global c3_c* u3_Local;
c3_global u3_king u3_King;
/** Functions.
**/
@ -726,6 +885,76 @@
u3_noun
u3_ve_zeus(u3_noun hap);
/** Filesystem (async)
**/
/* u3_foil_folder(): load directory, blockingly. create if nonexistent.
*/
u3_dire*
u3_foil_folder(const c3_c* pax_c); // directory object, or 0
/* u3_foil_create(): create a new, empty file, not syncing.
*/
void
u3_foil_create(void (*fun_f)(void*, // context pointer
u3_foil*),// file object
void* vod_p, // context pointer
u3_dire* dir_u, // directory
const c3_c* nam_c); // name of new file
/* u3_foil_absorb(): absorb logfile, truncating to last good frame; block.
*/
u3_foil*
u3_foil_absorb(u3_dire* dir_u, // directory
c3_c* nam_c); // filename
/* u3_foil_delete(): delete a file; free descriptor.
*/
void
u3_foil_delete(void (*fun_f)(void*), // context pointer
void* vod_p, // context pointer
u3_foil* fol_u); // file to delete
/* u3_foil_append(): write a frame at the end of a file, freeing buffer.
*/
void
u3_foil_append(void (*fun_f)(void*), // context pointer
void* vod_p, // context pointer
u3_foil* fol_u, // file
c3_d* buf_d, // buffer to write from
c3_d len_d); // length in chubs
/* u3_foil_reveal(): read the frame before a position, blocking.
*/
c3_d*
u3_foil_reveal(u3_foil* fol_u, // file from
c3_d* pos_d, // end position/prev end
c3_d* len_d); // length return
/* u3_foil_commit(): reveal from one file, append to another.
*/
void
u3_foil_commit(void (*fun_f)(void*, // context pointer
u3_foil*, // file from
c3_d, // previous from
u3_foil*, // file to
c3_d), // end of to
void* vod_p, // context pointer
u3_foil* del_u, // file from
c3_d del_d, // end of from frame
u3_foil* unt_u, // file to
c3_d unt_d); // end of to frame
/* u3_foil_invent(): make new file with one frame; free buffer, sync.
*/
void
u3_foil_invent(void (*fun_f)(void*, // context pointer
u3_foil*), // new file
void* vod_p, // context pointer
u3_dire* dir_u, // directory
c3_c* nam_c, // filename
c3_d* buf_d, // buffer (to free)
c3_d len_d); // length
/** Output.
**/
/* u3_ve_tank(): print a tank at `tab`.
@ -1068,7 +1297,6 @@
void
u3_raft_work(void);
/** Disk persistence.
**/
/* u3_sist_boot(): restore or create pier from disk.
@ -1139,6 +1367,7 @@
void
u3_sist_rand(c3_w* rad_w);
/** New timer system.
**/
/* u3_behn_io_init(): initialize time timer.
@ -1179,3 +1408,59 @@
*/
void
u3_cttp_io_poll(void);
/** Stream messages.
**/
/* u3_newt_write(): write atom to stream; free atom.
*/
void
u3_newt_write(u3_mojo* moj_u,
u3_atom mat,
void* vod_p);
/* u3_newt_read(): activate reading on input stream.
*/
void
u3_newt_read(u3_moat* mot_u);
/** Main for worker process.
**/
c3_i
u3_serf_main(c3_i arg_i,
c3_c** arg_c);
/** Pier control.
**/
/* u3_pier_create(): create a pier, loading existing.
*/
u3_pier*
u3_pier_create(c3_c* pax_c, c3_c* sys_c);
/* u3_pier_interrupt(): interrupt running process.
*/
void
u3_pier_interrupt(u3_pier* pir_u);
/* u3_pier_discover(): insert task into process controller.
*/
void
u3_pier_discover(u3_pier* pir_u,
c3_l msc_l,
u3_noun job);
/* u3_pier_exit(): trigger a gentle shutdown.
*/
void
u3_pier_exit(void);
/* u3_pier_plan(): submit event.
*/
void
u3_pier_plan(u3_noun pax, u3_noun fav);
/* u3_pier_boot(): start the new pier system.
*/
void
u3_pier_boot(c3_c* pax_c, // pier path
c3_c* sys_c); // path to boot pill

View File

@ -165,9 +165,9 @@ u3e_fault(void* adr_v, c3_i ser_i)
/* _ce_image_open(): open or create image.
*/
static c3_o
_ce_image_open(u3e_image* img_u, c3_o nuu_o)
_ce_image_open(u3e_image* img_u)
{
c3_i mod_i = _(nuu_o) ? (O_RDWR | O_CREAT) : O_RDWR;
c3_i mod_i = O_RDWR | O_CREAT;
c3_c ful_c[8193];
snprintf(ful_c, 8192, "%s", u3P.dir_c);
@ -197,11 +197,7 @@ _ce_image_open(u3e_image* img_u, c3_o nuu_o)
c3_d pgs_d = (siz_d + (c3_d)((1 << (u3a_page + 2)) - 1)) >>
(c3_d)(u3a_page + 2);
if ( c3y == nuu_o ) {
if ( siz_d ) {
c3_assert(0);
return c3n;
}
if ( !siz_d ) {
return c3y;
}
else {
@ -275,12 +271,12 @@ _ce_patch_create(u3_ce_patch* pat_u)
mkdir(ful_c, 0700);
snprintf(ful_c, 8192, "%s/.urb/chk/control.bin", u3P.dir_c);
if ( -1 == (pat_u->ctl_i = open(ful_c, O_RDWR | O_CREAT | O_EXCL, 0666)) ) {
if ( -1 == (pat_u->ctl_i = open(ful_c, O_RDWR | O_CREAT | O_EXCL, 0600)) ) {
c3_assert(0);
}
snprintf(ful_c, 8192, "%s/.urb/chk/memory.bin", u3P.dir_c);
if ( -1 == (pat_u->mem_i = open(ful_c, O_RDWR | O_CREAT | O_EXCL, 0666)) ) {
if ( -1 == (pat_u->mem_i = open(ful_c, O_RDWR | O_CREAT | O_EXCL, 0600)) ) {
c3_assert(0);
}
}
@ -815,7 +811,7 @@ u3e_save(void)
_ce_patch_free(pat_u);
}
/* u3e_live(): start the persistence system.
/* u3e_live(): start the checkpointing system.
*/
c3_o
u3e_live(c3_o nuu_o, c3_c* dir_c)
@ -830,29 +826,15 @@ u3e_live(c3_o nuu_o, c3_c* dir_c)
} else
#endif
{
/* Open and apply any patches.
*/
if ( _(nuu_o) ) {
if ( (c3n == _ce_image_open(&u3P.nor_u, c3y)) ||
(c3n == _ce_image_open(&u3P.sou_u, c3y)) )
{
printf("boot: image failed\r\n");
exit(1);
}
if ( (c3n == _ce_image_open(&u3P.nor_u)) ||
(c3n == _ce_image_open(&u3P.sou_u)) )
{
printf("boot: image failed\r\n");
exit(1);
}
else {
u3_ce_patch* pat_u;
/* Open image files.
*/
{
if ( (c3n == _ce_image_open(&u3P.nor_u, c3n)) ||
(c3n == _ce_image_open(&u3P.sou_u, c3n)) )
{
fprintf(stderr, "boot: no image\r\n");
return u3e_live(c3y, dir_c);
}
}
/* Load any patch files; apply them to images.
*/
if ( 0 != (pat_u = _ce_patch_open()) ) {
@ -901,4 +883,3 @@ u3e_live(c3_o nuu_o, c3_c* dir_c)
}
return nuu_o;
}

View File

@ -344,7 +344,7 @@ u3j_boot(void)
memset(u3D.ray_u, 0, (u3D.all_l * sizeof(u3j_core)));
jax_l = _cj_install(u3D.ray_u, 1, u3D.dev_u);
fprintf(stderr, "boot: installed %d jets\n", jax_l);
fprintf(stderr, "boot: installed %d jets\r\n", jax_l);
}
/* _cj_soft(): kick softly by arm axis.

View File

@ -482,7 +482,7 @@ u3m_mark(void)
/* _cm_pave(): instantiate or activate image.
*/
static void
_cm_pave(c3_o nuu_o, c3_o bug_o)
_cm_pave(c3_o nuu_o)
{
if ( c3y == nuu_o ) {
u3H = (void *)_pave_north(u3_Loom + 1,
@ -1497,6 +1497,50 @@ _cm_init(c3_o chk_o)
}
}
/* _cm_init_new(): start the environment.
*/
void
_cm_init_new(void)
{
_cm_limits();
_cm_signals();
/* Make sure GMP uses our malloc.
*/
mp_set_memory_functions(u3a_malloc, u3a_realloc2, u3a_free2);
/* Map at fixed address.
*/
{
c3_w len_w = u3a_bytes;
void* map_v;
map_v = mmap((void *)u3_Loom,
len_w,
(PROT_READ | PROT_WRITE),
(MAP_ANON | MAP_FIXED | MAP_PRIVATE),
-1, 0);
if ( -1 == (c3_ps)map_v ) {
void* dyn_v = mmap((void *)0,
len_w,
PROT_READ,
MAP_ANON | MAP_PRIVATE,
-1, 0);
fprintf(stderr, "boot: mapping %dMB failed\r\n", (len_w / (1024 * 1024)));
fprintf(stderr, "see urbit.org/docs/using/install to add swap space\r\n");
if ( -1 != (c3_ps)map_v ) {
fprintf(stderr,
"if porting to a new platform, try U3_OS_LoomBase %p\r\n",
dyn_v);
}
exit(1);
}
printf("loom: mapped %dMB\r\n", len_w >> 20);
}
}
/* _boot_home(): create ship directory.
*/
static void
@ -1573,10 +1617,10 @@ _boot_home(c3_c *dir_c, c3_c *pil_c)
}
}
/* u3m_boot(): start the u3 system.
/* u3m_boot(): start the u3 system (old).
*/
void
u3m_boot(c3_o nuu_o, c3_o bug_o, c3_c* dir_c, c3_c *pil_c)
u3m_boot(c3_o nuu_o, c3_c* dir_c, c3_c *pil_c)
{
/* Activate the loom.
*/
@ -1592,7 +1636,7 @@ u3m_boot(c3_o nuu_o, c3_o bug_o, c3_c* dir_c, c3_c *pil_c)
/* Construct or activate the allocator.
*/
_cm_pave(nuu_o, bug_o);
_cm_pave(nuu_o);
/* Initialize the jet system.
*/
@ -1611,10 +1655,82 @@ u3m_boot(c3_o nuu_o, c3_o bug_o, c3_c* dir_c, c3_c *pil_c)
printf("boot: loading %s\r\n", ful_c);
u3v_boot(ful_c);
}
}
else {
u3v_hose();
u3j_ream();
}
}
/* u3m_boot_new(): start the u3 system (new). return next event,
** starting from 1.
*/
c3_d
u3m_boot_new(c3_c* dir_c)
{
c3_o nuu_o;
/* Activate the loom.
*/
_cm_init_new();
/* Activate the storage system.
*/
nuu_o = u3e_live(c3n, dir_c);
/* Activate tracing.
*/
u3t_init();
/* Construct or activate the allocator.
*/
_cm_pave(nuu_o);
/* Initialize the jet system.
*/
u3j_boot();
/* Reactivate jets on old kernel.
*/
if ( !_(nuu_o) ) {
u3v_hose();
u3j_ream();
return u3A->ent_d;
}
else {
/* Basic initialization.
*/
memset(u3A, 0, sizeof(*u3A));
return 0;
}
}
/* u3m_boot_pier(): start without checkpointing.
*/
c3_d
u3m_boot_pier(void)
{
/* Activate the loom.
*/
_cm_init_new();
/* Activate tracing.
*/
u3t_init();
/* Construct or activate the allocator.
*/
_cm_pave(c3y);
/* Initialize the jet system.
*/
u3j_boot();
/* Basic initialization.
*/
memset(u3A, 0, sizeof(*u3A));
return 0;
}

View File

@ -1535,9 +1535,9 @@ u3r_chub(c3_w a_w,
*/
void
u3r_words(c3_w a_w,
c3_w b_w,
c3_w* c_w,
u3_atom d)
c3_w b_w,
c3_w* c_w,
u3_atom d)
{
c3_assert(u3_none != d);
c3_assert(_(u3a_is_atom(d)));
@ -1570,6 +1570,21 @@ u3r_words(c3_w a_w,
}
}
/* u3r_chubs():
**
** Copy double-words (a_w) through (a_w + b_w - 1) from (d) to (c).
*/
void
u3r_chubs(c3_w a_w,
c3_w b_w,
c3_d* c_d,
u3_atom d)
{
/* XX: assumes little-endian
*/
u3r_words(a_w * 2, b_w * 2, (c3_w *)c_d, d);
}
/* u3r_chop():
**
** Into the bloq space of `met`, from position `fum` for a

View File

@ -55,11 +55,11 @@ _t_ghetto(void)
ms_w = (d0.tv_sec * 1000) + (d0.tv_usec / 1000);
if (ms_w > 1) {
#if 0
printf("%6d.%02dms: %9d ",
fprintf(stderr, "%6d.%02dms: %9d ",
ms_w, (int) (d0.tv_usec % 1000) / 10,
((int) (u3R->pro.nox_d - b4_d)));
#else
printf("%6d.%02dms ",
fprintf(stderr, "%6d.%02dms ",
ms_w, (int) (d0.tv_usec % 1000) / 10);
#endif
gettimeofday(&b4, 0);
@ -90,9 +90,9 @@ u3t_slog(u3_noun hod)
u3_noun pri = u3h(hod);
switch ( pri ) {
case 3: printf(">>> "); break;
case 2: printf(">> "); break;
case 1: printf("> "); break;
case 3: fprintf(stderr, ">>> "); break;
case 2: fprintf(stderr, ">> "); break;
case 1: fprintf(stderr, "> "); break;
}
u3_lo_tank(0, u3k(u3t(hod)));
}
@ -112,7 +112,7 @@ u3t_shiv(u3_noun hod)
}
else {
c3_c *str_c = u3r_string(hod);
printf("%s\r\n", str_c);
fprintf(stderr, "%s\r\n", str_c);
free(str_c);
}
}

View File

@ -46,8 +46,30 @@ u3_noun
u3v_load(u3_noun pil)
{
u3_noun sys = u3ke_cue(pil);
u3_noun cor = u3v_fire(sys);
u3_noun pro;
fprintf(stderr, "load: mug: %x\r\n", u3r_mug(sys));
{
u3_noun cor = u3v_fire(sys);
u3_noun pro;
pro = u3k(u3r_at(7, cor));
u3z(cor);
return pro;
}
}
/* u3v_lite(): load lightweight, core-only pill.
*/
u3_noun
u3v_lite(u3_noun pil)
{
u3_noun arv = u3ke_cue(pil);
u3_noun cor, pro;
fprintf(stderr, "lite: arvo formula %x\r\n", u3r_mug(arv));
cor = u3n_nock_on(0, arv);
fprintf(stderr, "lite: core %x\r\n", u3r_mug(cor));
pro = u3k(u3r_at(7, cor));
@ -60,16 +82,41 @@ u3v_load(u3_noun pil)
void
u3v_boot(c3_c* pas_c)
{
u3_noun pil = u3m_file(pas_c);
u3_noun pru = u3m_soft(0, u3v_load, pil);
u3_noun pru;
if ( !u3A->sys ) {
u3A->sys = u3m_file(pas_c);
}
pru = u3m_soft(0, u3v_load, u3k(u3A->sys));
if ( u3h(pru) != 0 ) {
fprintf(stderr, "boot failed\r\n");
exit(1);
}
fprintf(stderr, "final state %x\r\n", u3r_mug(u3t(pru)));
fprintf(stderr, "boot: final state %x\r\n", u3r_mug(u3t(pru)));
u3A->ken = 0;
u3A->roc = u3k(u3t(pru));
u3z(pru);
}
/* u3v_boot_lite(): light bootstrap sequence, just making a kernel.
*/
void
u3v_boot_lite(u3_atom lit)
{
u3_noun pru = u3m_soft(0, u3v_lite, lit);
if ( u3h(pru) != 0 ) {
fprintf(stderr, "boot failed\r\n");
exit(1);
}
fprintf(stderr, "lite: final state %x\r\n", u3r_mug(u3t(pru)));
u3A->ken = 0;
u3A->roc = u3k(u3t(pru));
@ -260,7 +307,7 @@ _cv_nock_poke(u3_noun ovo)
u3_noun tox = u3do("spat", u3k(u3h(ovo)));
c3_c* tox_c = u3r_string(tox);
printf("poke: %%%s (%x) on %s\r\n", ovi_c, u3r_mug(ovo), tox_c);
fprintf(stderr, "poke: %%%s (%x) on %s\r\n", ovi_c, u3r_mug(ovo), tox_c);
free(tox_c); free(ovi_c); u3z(tox);
}
#endif
@ -273,8 +320,11 @@ _cv_nock_poke(u3_noun ovo)
{
c3_c* ovi_c = u3r_string(u3h(u3t(ovo)));
printf("poked: %s\r\n", ovi_c);
if ( u3_nul == u3h(pro) ) {
fprintf(stderr, " blank: %s\r\n", ovi_c);
} else {
fprintf(stderr, " happy: %s: %d\r\n", ovi_c, u3kb_lent(u3k(u3h(pro))));
}
free(ovi_c);
}
#endif

View File

@ -187,7 +187,7 @@ u3_ames_ef_bake(void)
{
u3_noun pax = u3nq(u3_blip, c3__newt, u3k(u3A->sen), u3_nul);
u3v_plan(pax, u3nc(c3__barn, u3_nul));
u3_pier_plan(pax, u3nc(c3__barn, u3_nul));
}
/* u3_ames_ef_send(): send packet to network (v4).
@ -259,7 +259,7 @@ _ames_time_cb(uv_timer_t* tim_uo)
sam_u->law_w = time(0);
{
u3v_plan
u3_pier_plan
(u3nt(u3_blip, c3__ames, u3_nul),
u3nc(c3__wake, u3_nul));
}
@ -293,7 +293,7 @@ _ames_recv_cb(uv_udp_t* wax_u,
c3_s por_s = ntohs(add_u->sin_port);
c3_w pip_w = ntohl(add_u->sin_addr.s_addr);
u3v_plan
u3_pier_plan
(u3nt(u3_blip, c3__ames, u3_nul),
u3nt(c3__hear,
u3nq(c3__if, u3k(u3A->now), por_s, u3i_words(1, &pip_w)),

View File

@ -51,7 +51,7 @@ _batz_time_cb(uv_timer_t* tim_u)
u3_lo_open();
{
u3v_plan
u3_pier_plan
(u3nt(u3_blip, c3__batz, u3_nul),
u3nc(c3__wake, u3_nul));
}

View File

@ -51,7 +51,7 @@ _behn_time_cb(uv_timer_t* tim_u)
u3_lo_open();
{
u3v_plan
u3_pier_plan
(u3nt(u3_blip, c3__behn, u3_nul),
u3nc(c3__wake, u3_nul));
}

View File

@ -445,7 +445,7 @@ _cttp_httr(c3_l num_l, c3_w sas_w, u3_noun mes, u3_noun uct)
u3_noun htr = u3nt(sas_w, mes, uct);
u3_noun pox = u3nt(u3_blip, c3__http, u3_nul);
u3v_plan(pox, u3nt(c3__they, num_l, htr));
u3_pier_plan(pox, u3nt(c3__they, num_l, htr));
}
/* _cttp_httr_cres(): deliver valid response.
@ -1638,6 +1638,7 @@ u3_cttp_io_init()
SSL_load_error_strings();
u3_Host.ssl_u = SSL_CTX_new(TLSv1_client_method());
SSL_CTX_set_options(u3S, SSL_OP_NO_SSLv2);
SSL_CTX_set_verify(u3S, SSL_VERIFY_PEER, NULL);
SSL_CTX_set_default_verify_paths(u3S);
@ -1676,5 +1677,5 @@ u3_cttp_io_poll(void)
void
u3_cttp_io_exit(void)
{
SSL_CTX_free(u3S);
SSL_CTX_free(u3S);
}

629
vere/foil.c Normal file
View File

@ -0,0 +1,629 @@
/* vere/foil.c
**
** This file is in the public domain.
*/
#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 <termios.h>
#include <term.h>
#include <errno.h>
#include <libgen.h>
#include <ftw.h>
#include "vere/vere.h"
/* assumptions:
** all measurements are in chubs (double-words, c3_d, uint64_t).
** little-endian addressing is ASSUMED.
**
** framing:
** the last two chubs of a frame:
**
** {
** 64-bit frame length
** {
** (high 32 bits) mug of frame
** (low 32 bits) mug of current address
** }
** }
**
** we can scan for one of these frames with very low probability
** of a false positive. we always write to and read from the end
** of a file. a frame position points to its end.
**
** protocol:
** once the callback is called, all results are fully fsynced.
** all callbacks are optional and can be passed 0.
*/
/* _foil_fail(): fail with error.
*/
static void
_foil_fail(const c3_c* why_c, c3_i err_i)
{
if ( err_i ) {
fprintf(stderr, "%s: error: %s\r\n", why_c, uv_strerror(err_i));
c3_assert(0);
} else {
fprintf(stderr, "%s: file error\r\n", why_c);
}
exit(1);
}
/* _foil_close(): close file, blockingly.
*/
static void
_foil_close(uv_file fil_f)
{
c3_i err_i;
uv_fs_t ruq_u;
if ( 0 != (err_i = uv_fs_close(u3L, &ruq_u, fil_f, 0)) ) {
_foil_fail("uv_fs_close", err_i);
}
}
/* _foil_path(): allocate path.
*/
static c3_c*
_foil_path(u3_dire* dir_u,
const c3_c* nam_c)
{
c3_w len_w = strlen(dir_u->pax_c);
c3_c* pax_c;
pax_c = c3_malloc(1 + len_w + 1 + strlen(nam_c));
strcpy(pax_c, dir_u->pax_c);
pax_c[len_w] = '/';
strcpy(pax_c + len_w + 1, nam_c);
return pax_c;
}
/* u3_foil_folder(): load directory, blockingly. null if nonexistent.
*/
u3_dire*
u3_foil_folder(const c3_c* pax_c)
{
u3_dire* dir_u;
uv_fs_t ruq_u;
uv_dirent_t den_u;
c3_i err_i;
/* open directory, synchronously
*/
{
err_i = uv_fs_scandir(u3L, &ruq_u, pax_c, 0, 0);
if ( err_i < 0 ) {
if ( UV_ENOENT != err_i ) {
_foil_fail(pax_c, err_i);
return 0;
}
else {
if ( 0 != (err_i = uv_fs_mkdir(u3L, &ruq_u, pax_c, 0700, 0)) ) {
_foil_fail(pax_c, err_i);
return 0;
}
else {
uv_fs_req_cleanup(&ruq_u);
return u3_foil_folder(pax_c);
}
}
}
dir_u = c3_malloc(sizeof *dir_u);
dir_u->all_u = 0;
dir_u->pax_c = c3_malloc(1 + strlen(pax_c));
strcpy(dir_u->pax_c, pax_c);
}
/* create entries for all files
*/
while ( UV_EOF != uv_fs_scandir_next(&ruq_u, &den_u) ) {
if ( UV_DIRENT_FILE == den_u.type ) {
u3_dent* det_u = c3_malloc(sizeof(*det_u));
det_u->nam_c = c3_malloc(1 + strlen(den_u.name));
strcpy(det_u->nam_c, den_u.name);
det_u->nex_u = dir_u->all_u;
dir_u->all_u = det_u;
}
}
/* clean up request
*/
{
uv_fs_req_cleanup(&ruq_u);
}
/* open directory file for reading, to fsync
*/
{
if ( 0 > (err_i = uv_fs_open(u3L,
&ruq_u,
pax_c,
O_RDONLY,
0600,
0)) )
{
_foil_fail("open directory", err_i);
return 0;
}
dir_u->fil_u = ruq_u.result;
uv_fs_req_cleanup(&ruq_u);
}
return dir_u;
}
/* u3_foil_create(): create a new, empty, open file, not syncing.
*/
struct _foil_create_request {
uv_fs_t ruq_u;
void (*fun_f)(void*, u3_foil*);
void* vod_p;
u3_dire* dir_u;
c3_c* nam_c;
c3_c* pax_c;
};
static void
_foil_create_cb(uv_fs_t* ruq_u)
{
struct _foil_create_request* req_u = (void *)ruq_u;
u3_foil* fol_u;
fol_u = c3_malloc(sizeof(*fol_u));
fol_u->fil_u = ruq_u->result;
fol_u->dir_u = req_u->dir_u;
fol_u->nam_c = req_u->nam_c;
fol_u->end_d = 0;
req_u->fun_f(req_u->vod_p, fol_u);
c3_free(req_u->pax_c);
uv_fs_req_cleanup(ruq_u);
c3_free(req_u);
}
void
u3_foil_create(void (*fun_f)(void*, // context pointer
u3_foil*),// file object
void* vod_p, // context pointer
u3_dire* dir_u, // directory
const c3_c* nam_c) // name of new file
{
c3_c* pax_c;
c3_i err_i;
/* construct full path
*/
pax_c = _foil_path(dir_u, nam_c);
/* perform create
*/
{
struct _foil_create_request* req_u;
req_u = c3_malloc(sizeof(*req_u));
req_u->fun_f = fun_f;
req_u->vod_p = vod_p;
req_u->dir_u = dir_u;
req_u->nam_c = c3_malloc(1 + strlen(nam_c));
strcpy(req_u->nam_c, nam_c);
req_u->pax_c = pax_c;
if ( 0 != (err_i = uv_fs_open(u3L,
&req_u->ruq_u,
pax_c,
O_CREAT | O_WRONLY,
0600,
_foil_create_cb)) )
{
_foil_fail("uv_fs_open", err_i);
}
}
}
/* u3_foil_absorb(): open logfile, truncating to last good frame; blocking.
*/
u3_foil*
u3_foil_absorb(u3_dire* dir_u, // directory
c3_c* nam_c) // filename
{
u3_foil* fol_u;
uv_fs_t ruq_u;
c3_i err_i;
/* open file and create wrapper
*/
{
c3_c* pax_c = _foil_path(dir_u, nam_c);
if ( 0 > (err_i = uv_fs_open(u3L,
&ruq_u,
pax_c,
O_RDWR | O_CREAT,
0600,
0)) )
{
_foil_fail(pax_c, err_i);
c3_free(pax_c);
return 0;
}
c3_free(pax_c);
fol_u = c3_malloc(sizeof(*fol_u));
fol_u->dir_u = dir_u;
fol_u->fil_u = ruq_u.result;
fol_u->nam_c = c3_malloc(1 + strlen(nam_c));
strcpy(fol_u->nam_c, nam_c);
uv_fs_req_cleanup(&ruq_u);
}
/* measure file
*/
{
if ( 0 != (err_i = uv_fs_fstat(u3L, &ruq_u, fol_u->fil_u, 0)) ) {
_foil_fail("uv_fs_fstat", err_i);
return 0;
}
if ( 0 != (7 & ruq_u.statbuf.st_size) ) {
_foil_fail("logfile size corrupt", 0);
return 0;
}
fol_u->end_d = (ruq_u.statbuf.st_size >> 3ULL);
}
/* XX: scan for good frame.
*/
return fol_u;
}
/* u3_foil_delete(): delete a file; free descriptor.
*/
struct _foil_delete_request {
uv_fs_t ruq_u;
void (*fun_f)(void*);
void* vod_p;
u3_foil* fol_u;
c3_c* pax_c;
};
static void
_foil_delete_cb(uv_fs_t* ruq_u)
{
struct _foil_delete_request* req_u = (void *)ruq_u;
if ( req_u->fun_f ) {
req_u->fun_f(req_u->vod_p);
}
c3_free(req_u->pax_c);
c3_free(req_u->fol_u->nam_c);
c3_free(req_u->fol_u);
uv_fs_req_cleanup(ruq_u);
c3_free(req_u);
}
void
u3_foil_delete(void (*fun_f)(void*), // context pointer
void* vod_p, // context pointer
u3_foil* fol_u) // file to delete
{
c3_i err_i;
c3_c* pax_c;
/* construct full path
*/
pax_c = _foil_path(fol_u->dir_u, fol_u->nam_c);
/* perform delete
*/
{
struct _foil_delete_request* req_u;
req_u = c3_malloc(sizeof(*req_u));
req_u->fun_f = fun_f;
req_u->vod_p = vod_p;
req_u->fol_u = fol_u;
req_u->pax_c = pax_c;
if ( 0 != (err_i = uv_fs_unlink(u3L,
&req_u->ruq_u,
pax_c,
_foil_delete_cb)) )
{
_foil_fail("uv_fs_unlink", err_i);
}
}
}
/* u3_foil_append(): write a frame at the end of a file, freeing the buffer.
*/
struct _foil_append_request {
uv_fs_t ruq_u;
void (*fun_f)(void*);
void* vod_p;
u3_foil* fol_u;
c3_d* fam_d;
c3_d* buf_d;
};
static void
_foil_append_cb_2(uv_fs_t* ruq_u)
{
struct _foil_append_request* req_u = (void*) ruq_u;
req_u->fun_f(req_u->vod_p);
uv_fs_req_cleanup(ruq_u);
c3_free(req_u);
}
static void
_foil_append_cb_1(uv_fs_t* ruq_u)
{
struct _foil_append_request* req_u = (void*) ruq_u;
uv_fs_req_cleanup(ruq_u);
c3_free(req_u->buf_d);
uv_fs_fsync(u3L, &req_u->ruq_u,
req_u->fol_u->fil_u,
_foil_append_cb_2);
}
void
u3_foil_append(void (*fun_f)(void*), // context pointer
void* vod_p, // context pointer
u3_foil* fol_u, // file
c3_d* buf_d, // buffer to write from
c3_d len_d) // length in chubs
{
c3_d pos_d = fol_u->end_d;
struct _foil_append_request* req_u;
c3_i err_i;
/* set up request
*/
{
req_u = c3_malloc(sizeof(*req_u));
req_u->fun_f = fun_f;
req_u->vod_p = vod_p;
req_u->fol_u = fol_u;
req_u->buf_d = buf_d;
req_u->fam_d = c3_malloc(16);
}
/* framing
*/
{
c3_w top_w, bot_w;
fol_u->end_d = pos_d + len_d + 2;
/* XX: assumes "little-endian won", 32-bit frame length.
*/
top_w = u3r_mug_words((c3_w *)(void *) buf_d, (2 * len_d));
bot_w = (req_u->fol_u->end_d & 0xffffffff);
bot_w = u3r_mug_words(&bot_w, 1);
req_u->fam_d[0] = len_d;
req_u->fam_d[1] = ((c3_d)top_w) << 32ULL | ((c3_d) bot_w);
}
/* do it
*/
{
uv_buf_t buf_u[2];
buf_u[0] = uv_buf_init((void *)buf_d, (len_d * 8));
buf_u[1] = uv_buf_init((void *)req_u->fam_d, 16);
if ( 0 != (err_i = uv_fs_write(u3L,
&req_u->ruq_u,
fol_u->fil_u,
buf_u,
2,
(8ULL * pos_d),
_foil_append_cb_1)) )
{
_foil_fail("uv_fs_write", err_i);
}
}
}
/* u3_foil_reveal(): read the frame before a position, blocking.
*/
c3_d*
u3_foil_reveal(u3_foil* fol_u, // file from
c3_d* sop_d, // end position/prev end
c3_d* len_d) // length return
{
c3_d pos_d = *sop_d;
c3_d fam_d[2];
c3_l mug_l;
uv_fs_t ruq_u;
c3_i err_i;
c3_assert(pos_d >= 2);
c3_assert(pos_d <= fol_u->end_d);
/* read frame data
*/
{
uv_buf_t buf_u = uv_buf_init((void *)fam_d, 16);
fam_d[0] = fam_d[1] = 0;
if ( 0 > (err_i = uv_fs_read(u3L,
&ruq_u,
fol_u->fil_u,
&buf_u, 1,
(8ULL * (pos_d - 2ULL)),
0)) )
{
_foil_fail("uv_fs_read", err_i);
return 0;
}
uv_fs_req_cleanup(&ruq_u);
}
/* validate frame
*/
{
c3_w top_w, bot_w;
c3_l chk_l;
*len_d = fam_d[0];
if ( *len_d > (pos_d - 2ULL) ) {
_foil_fail("corrupt frame a", 0);
return 0;
}
top_w = fam_d[1] >> 32ULL;
mug_l = top_w;
bot_w = fam_d[1] & 0xffffffff;
chk_l = (pos_d & 0xffffffff);
chk_l = u3r_mug_words(&chk_l, 1);
if ( bot_w != chk_l ) {
_foil_fail("corrupt frame b", 0);
}
}
/* read frame
*/
{
c3_d* buf_d = c3_malloc(8 * *len_d);
uv_buf_t buf_u = uv_buf_init((void *)buf_d, 8 * *len_d);
c3_l gum_l;
if ( 0 > (err_i = uv_fs_read(u3L,
&ruq_u,
fol_u->fil_u,
&buf_u, 1,
(8ULL * (pos_d - (*len_d + 2ULL))),
0) ) )
{
_foil_fail("uv_fs_read", err_i);
return 0;
}
uv_fs_req_cleanup(&ruq_u);
gum_l = u3r_mug_words((c3_w *)(void *) buf_d, (2 * *len_d));
if ( mug_l != gum_l ) {
_foil_fail("corrupt frame c", 0);
return 0;
}
*sop_d = (pos_d - (*len_d + 2ULL));
return buf_d;
}
}
/* u3_foil_invent(): create a new file with one frame, freeing buffer; sync.
*/
struct _foil_invent_request {
uv_fs_t ruq_u;
void (*fun_f)(void*, u3_foil*);
u3_foil* fol_u;
void* vod_p;
c3_d* buf_d;
c3_d len_d;
c3_d num_d;
#if 0
struct timeval bef_u;
#endif
};
static void
_foil_invent_cb_2a(void* req_p)
{
struct _foil_invent_request* req_u = req_p;
if ( 1 == req_u->num_d ) {
#if 0
{
struct timeval aft_u, gap_u;
c3_w mls_w;
gettimeofday(&aft_u, 0);
timersub(&aft_u, &req_u->bef_u, &gap_u);
mls_w = (gap_u.tv_sec * 1000) + (gap_u.tv_usec / 1000);
fprintf(stderr, "invent ms: %d\r\n", mls_w);
}
#endif
req_u->fun_f(req_u->vod_p, req_u->fol_u);
_foil_close(req_u->fol_u->fil_u);
c3_free(req_u);
}
else {
req_u->num_d++;
}
}
static void
_foil_invent_cb_2b(uv_fs_t* ruq_u)
{
struct _foil_invent_request* req_u = (void *)ruq_u;
uv_fs_req_cleanup(ruq_u);
_foil_invent_cb_2a(req_u);
}
static void
_foil_invent_cb_1(void* req_p,
u3_foil* fol_u)
{
struct _foil_invent_request* req_u = req_p;
req_u->fol_u = fol_u;
/* fsync the parent directory, since we just created a file.
*/
uv_fs_fsync(u3L, &req_u->ruq_u,
req_u->fol_u->dir_u->fil_u,
_foil_invent_cb_2b);
u3_foil_append(_foil_invent_cb_2a,
req_u,
fol_u,
req_u->buf_d,
req_u->len_d);
}
void
u3_foil_invent(void (*fun_f)(void*, // context pointer
u3_foil*), // new file
void* vod_p, // context pointer
u3_dire* dir_u, // directory
c3_c* nam_c, // filename
c3_d* buf_d, // buffer (to free)
c3_d len_d) // length
{
struct _foil_invent_request* req_u;
req_u = malloc(sizeof(*req_u));
req_u->fun_f = fun_f;
req_u->fol_u = 0;
req_u->vod_p = vod_p;
req_u->buf_d = buf_d;
req_u->len_d = len_d;
req_u->num_d = 0;
#if 0
gettimeofday(&req_u->bef_u, 0);
#endif
u3_foil_create(_foil_invent_cb_1, req_u, dir_u, nam_c);
}

694
vere/fuse.c Normal file
View File

@ -0,0 +1,694 @@
/* v/fuse.c
**
** This file is in the public domain.
*/
#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 <termios.h>
#include <term.h>
#include <errno.h>
#include <libgen.h>
#include <ftw.h>
#include "vere/vere.h"
/* helper routines adapted from FUSE example code
*/
struct _fusedr_buf {
c3_c* buf_c;
c3_z siz_z;
};
static void
_fusedr_buf_add(fuse_req_t req_u,
struct _fusedr_buf* buf_u,
const c3_c* nam_c,
fuse_ino_t ino_i)
{
struct stat sat_u;
c3_z old_z = buf_u->siz_z;
buf_u->siz_z += fuse_add_direntry(req_u, NULL, 0, nam_c, NULL, 0);
buf_u->buf_c = (c3_c*) realloc(buf_u->buf_c, buf_u->siz_z);
memset(&sat_u, 0, sizeof(sat_u));
sat_u.st_ino = ino_i;
fuse_add_direntry(req_u,
buf_u->buf_c + old_z,
buf_u->siz_z - old_z,
nam_c,
&sat_u,
buf_u->siz_z);
}
static void
_fuse_buf_reply(fuse_req_t req_u,
c3_c* buf_c,
c3_z siz_z,
c3_f off_f,
c3_z max_z)
{
if ( off_f < siz_z ) {
fuse_reply_buf(req_u,
buf_c + off_f,
c3_min(siz_z - off_f, max_z));
} else {
fuse_reply_buf(req_u, NULL, 0);
}
}
static void
_inode_init(void)
{
u3_fuse* fus_u = &u3_Host.fus_u;
memset(fus_u, 0, sizeof(u3_fuse));
{
fus_u->rot_u.ino_i = FUSE_ROOT_ID;
fus_u->rot_u.val_u = 0;
fus_u->rot_u.nam_c = strdup("/");
fus_u->rot_u.pax_c = 0;
fus_u->rot_u.val_u = 0;
fus_u->rot_u.ref_w = 0x1fffffff;
fus_u->rot_u.par_u = 0;
fus_u->rot_u.kid_u = 0;
fus_u->rot_u.nex_u = 0;
}
{
fus_u->ion_u.ino_i = FUSE_ROOT_ID + 1;
fus_u->ion_u.len_w = 64;
fus_u->ion_u.nod_u = calloc(64, sizeof(struct fnod *));
fus_u->ion_u.nod_u[FUSE_ROOT_ID] = &fus_u->rot_u;
}
}
/* _inode_get(): look up an inode.
*/
static u3_fnod*
_inode_get(fuse_ino_t ino_i)
{
u3_fuse* fus_u = &u3_Host.fus_u;
c3_assert(ino_i < fus_u->ion_u.ino_i);
return fus_u->ion_u.nod_u[ino_i];
}
/* _inode_new(): create an inode.
*/
static u3_fnod*
_inode_new(void)
{
u3_fuse* fus_u = &u3_Host.fus_u;
u3_fnod* nod_u = calloc(1, sizeof(u3_fnod));
nod_u->ino_i = fus_u->ion_u.ino_i;
fus_u->ion_u.nod_u[nod_u->ino_i] = nod_u;
fus_u->ion_u.ino_i++;
if ( fus_u->ion_u.len_w == fus_u->ion_u.ino_i ) {
fus_u->ion_u.len_w *= 2;
fus_u->ion_u.nod_u = realloc(fus_u->ion_u.nod_u,
(fus_u->ion_u.len_w *
sizeof(struct fnod *)));
}
return nod_u;
}
/* _inode_make(): set up an inode.
*/
static u3_fnod*
_inode_make(u3_fnod* par_u, c3_c* nam_c)
{
u3_fnod* nod_u = _inode_new();
nod_u->nam_c = nam_c;
nod_u->par_u = par_u;
nod_u->nex_u = par_u->kid_u;
par_u->kid_u = nod_u;
return nod_u;
}
/* _inode_stat(): fill stat buffer from inode; return c3y if available
*/
static c3_o
_inode_stat(u3_fnod* nod_u, struct stat* buf_u)
{
memset(buf_u, 0, sizeof(struct stat));
switch ( nod_u->typ_e ) {
case u3_fuse_type_unknown: return c3n;
case u3_fuse_type_file: {
if ( 0 == nod_u->val_u ) {
return c3n;
}
else {
buf_u->st_mode = S_IFREG | 0444;
buf_u->st_nlink = 1;
buf_u->st_size = nod_u->val_u->siz_z;
return c3y;
}
}
case u3_fuse_type_directory: {
buf_u->st_mode = S_IFDIR | 0555;
buf_u->st_nlink = 2;
return c3y;
}
}
}
/* _inode_path(): map inode path to noun.
*/
static u3_noun
_inode_path(u3_fnod* nod_u, u3_noun end)
{
if ( nod_u->par_u == 0 ) {
return end;
}
else {
end = u3nc(u3i_string(nod_u->nam_c), end);
return _inode_path(nod_u->par_u, end);
}
}
/* _inode_load_arch(): load urbit's own "inode".
*/
static u3_weak
_inode_load_arch(u3_noun hap)
{
if ( u3_nul == u3A->own ) {
return u3_none;
}
else {
u3_noun our = u3dc("scot", 'p', u3k(u3h(u3A->own)));
u3_noun pax = u3nc(c3__cy, u3nq(our, c3__home, u3k(u3A->wen), hap));
u3_noun val = u3v_peek(pax);
if ( u3_nul == val ) {
return u3_none;
} else {
u3_noun ret = u3k(u3t(val));
u3z(val);
return ret;
}
}
}
/* _inode_load_data(): load urbit file contents.
*/
static u3_weak
_inode_load_data(u3_noun hap)
{
if ( u3_nul == u3A->own ) {
return u3_none;
}
else {
u3_noun our = u3dc("scot", 'p', u3k(u3h(u3A->own)));
u3_noun pax = u3nc(c3__cx, u3nq(our, c3__home, u3k(u3A->wen), hap));
u3_noun val = u3v_peek(pax);
if ( u3_nul == val ) {
return u3_none;
} else {
u3_noun ret = u3k(u3t(val));
u3z(val);
if ( c3n == u3ud(ret) ) {
uL(fprintf(uH, "inode_load_data: not an atom\n"));
u3z(ret);
ret = 0;
}
return ret;
}
}
}
/* _inode_fill_directory(): fill directory inode.
*/
static u3_fdir*
_inode_fill_directory(u3_fnod* par_u, u3_noun kiz)
{
u3_fdir* dir_u;
dir_u = malloc(sizeof(u3_fdir));
dir_u->num_w = 0;
{
u3_noun zik = kiz;
while ( u3_nul != zik ) {
u3_noun ph_zik = u3h(u3h(zik));
c3_c* nam_c = u3r_string(ph_zik);
u3_fent* fen_u = calloc(1, sizeof(u3_fent));
fen_u->nod_u = _inode_make(par_u, nam_c);
fen_u->nex_u = dir_u->fen_u;
dir_u->fen_u = fen_u;
dir_u->num_w += 1;
zik = u3t(zik);
}
u3z(kiz);
}
return dir_u;
}
/* _inode_fill_file(): fill file inode.
*/
static u3_fval*
_inode_fill_file(u3_atom dat)
{
u3_fval* val_u = calloc(1, sizeof(u3_fval));
val_u->siz_z = u3r_met(3, dat);
val_u->buf_y = malloc(val_u->siz_z);
u3r_bytes(0, val_u->siz_z, val_u->buf_y, dat);
u3z(dat);
return val_u;
}
/* _inode_load(): load inode value.
*/
static c3_o
_inode_load(u3_fnod* nod_u)
{
if ( u3_nul == u3A->own ) {
return c3n;
}
else {
if ( nod_u->typ_e != u3_fuse_type_unknown ) {
return c3y;
}
else {
u3_noun hap = _inode_path(nod_u, u3_nul);
u3_weak ark = _inode_load_arch(u3k(hap));
c3_o ret;
if ( u3_none == ark ) {
ret = c3n;
}
else {
if ( u3_nul == u3h(ark) ) {
nod_u->typ_e = u3_fuse_type_directory;
nod_u->dir_u = _inode_fill_directory
(nod_u, u3qdb_tap(u3t(ark), u3_nul));
}
else {
u3_noun dat;
nod_u->typ_e = u3_fuse_type_file;
dat = _inode_load_data(u3k(hap));
nod_u->val_u = _inode_fill_file(dat);
}
ret = c3y;
u3z(ark);
}
u3z(hap);
return ret;
}
}
}
/**
* Initialize filesystem
*
* Called before any other filesystem method
*
* There's no reply to this function
*
* @param userdata the user data passed to fuse_lowlevel_new()
*/
static void
_fuse_ll_init(void* usr_v,
struct fuse_conn_info* con_u)
{
uL(fprintf(uH, "ll_init\n"));
{
_inode_init();
}
}
/**
* Look up a directory entry by name and get its attributes.
*
* Valid replies:
* fuse_reply_entry
* fuse_reply_err
*
* @param req request handle
* @param parent inode number of the parent directory
* @param name the name to look up
*/
static void
_fuse_ll_lookup(fuse_req_t req_u,
fuse_ino_t pno_i,
const c3_c* nam_c)
{
uL(fprintf(uH, "ll_lookup %ld %s\n", pno_i, nam_c));
{
u3_fnod* par_u = _inode_get(pno_i);
u3_fnod* nod_u;
// Find, then make.
{
for ( nod_u = par_u->kid_u; nod_u; nod_u = nod_u->nex_u ) {
if ( !strcmp(nam_c, nod_u->nam_c) ) {
break;
}
}
if ( !nod_u ) {
nod_u = _inode_make(par_u, strdup(nam_c));
}
}
if ( c3n == _inode_load(nod_u) ) {
fuse_reply_err(req_u, ENOENT);
}
else {
struct fuse_entry_param ent_u;
memset(&ent_u, 0, sizeof(ent_u));
if ( c3n == _inode_stat(nod_u, &ent_u.attr) ) {
fuse_reply_err(req_u, ENOENT);
}
ent_u.ino = nod_u->ino_i;
ent_u.generation = 1;
ent_u.attr_timeout = 1.0;
ent_u.entry_timeout = 1.0;
fuse_reply_entry(req_u, &ent_u);
}
}
}
/**
* Get file attributes
*
* Valid replies:
* fuse_reply_attr
* fuse_reply_err
*
* @param req request handle
* @param ino the inode number
* @param fi for future use, currently always NULL
*/
static void
_fuse_ll_getattr(fuse_req_t req_u,
fuse_ino_t ino_i,
struct fuse_file_info* ffi_u)
{
uL(fprintf(uH, "ll_getattr %ld\n", ino_i));
{
u3_fnod* nod_u = _inode_get(ino_i);
if ( c3n == _inode_load(nod_u) ) {
fuse_reply_err(req_u, ENOENT);
}
else {
struct stat buf_u;
if ( c3n == _inode_stat(nod_u, &buf_u) ) {
fuse_reply_err(req_u, ENOENT);
}
else {
fuse_reply_attr(req_u, &buf_u, 1.0);
}
}
}
}
/**
* Read directory
*
* Send a buffer filled using fuse_add_direntry(), with size not
* exceeding the requested size. Send an empty buffer on end of
* stream.
*
* fi->fh will contain the value set by the opendir method, or
* will be undefined if the opendir method didn't set any value.
*
* Valid replies:
* fuse_reply_buf
* fuse_reply_err
*
* @param req request handle
* @param ino the inode number
* @param size maximum number of bytes to send
* @param off offset to continue reading the directory stream
* @param fi file information
*/
static void
_fuse_ll_readdir(fuse_req_t req_u,
fuse_ino_t ino_i,
c3_z max_z,
c3_f off_f,
struct fuse_file_info* ffi_u)
{
uL(fprintf(uH, "ll_readdir %ld %ld %lld\n", ino_i, max_z, off_f));
{
u3_fnod* nod_u = _inode_get(ino_i);
if ( c3n == _inode_load(nod_u) ) {
fuse_reply_err(req_u, ENOENT);
}
else if ( u3_fuse_type_directory != nod_u->typ_e ) {
fuse_reply_err(req_u, ENOTDIR);
}
else {
struct _fusedr_buf buf_u;
memset(&buf_u, 0, sizeof(buf_u));
_fusedr_buf_add(req_u, &buf_u, ".", ino_i);
_fusedr_buf_add(req_u, &buf_u, "..", nod_u->par_u
? nod_u->par_u->ino_i
: ino_i);
{
u3_fent* fen_u;
for ( fen_u = nod_u->dir_u->fen_u; fen_u; fen_u = fen_u->nex_u ) {
_fusedr_buf_add(req_u,
&buf_u,
fen_u->nod_u->nam_c,
fen_u->nod_u->ino_i);
}
}
_fuse_buf_reply(req_u, buf_u.buf_c, buf_u.siz_z, off_f, max_z);
}
}
}
/**
* Open a file
*
* Open flags (with the exception of O_CREAT, O_EXCL, O_NOCTTY and
* O_TRUNC) are available in fi->flags.
*
* Filesystem may store an arbitrary file handle (pointer, index,
* etc) in fi->fh, and use this in other all other file operations
* (read, write, flush, release, fsync).
*
* Filesystem may also implement stateless file I/O and not store
* anything in fi->fh.
*
* There are also some flags (direct_io, keep_cache) which the
* filesystem may set in fi, to change the way the file is opened.
* See fuse_file_info structure in <fuse_common.h> for more details.
*
* Valid replies:
* fuse_reply_open
* fuse_reply_err
*
* @param req request handle
* @param ino the inode number
* @param fi file information
*/
static void
_fuse_ll_open(fuse_req_t req_u,
fuse_ino_t ino_i,
struct fuse_file_info* ffi_u)
{
uL(fprintf(uH, "ll_open %ld\n", ino_i));
{
u3_fnod* nod_u = _inode_get(ino_i);
if ( c3n == _inode_load(nod_u) ) {
fuse_reply_err(req_u, ENOENT);
}
else if ( u3_fuse_type_file != nod_u->typ_e ) {
fuse_reply_err(req_u, ENOTDIR);
}
else if ( (ffi_u->flags & 3) != O_RDONLY ) {
fuse_reply_err(req_u, EACCES);
}
else {
fuse_reply_open(req_u, ffi_u);
}
}
}
/**
* Read data
*
* Read should send exactly the number of bytes requested except
* on EOF or error, otherwise the rest of the data will be
* substituted with zeroes. An exception to this is when the file
* has been opened in 'direct_io' mode, in which case the return
* value of the read system call will reflect the return value of
* this operation.
*
* fi->fh will contain the value set by the open method, or will
* be undefined if the open method didn't set any value.
*
* Valid replies:
* fuse_reply_buf
* fuse_reply_err
*
* @param req request handle
* @param ino the inode number
* @param size number of bytes to read
* @param off offset to read from
* @param fi file information
*/
static void
_fuse_ll_read(fuse_req_t req_u,
fuse_ino_t ino_i,
c3_z max_z,
c3_f off_f,
struct fuse_file_info* ffi_u)
{
uL(fprintf(uH, "ll_read %ld %ld %lld\n", ino_i, max_z, off_f));
{
u3_fnod* nod_u = _inode_get(ino_i);
if ( c3n == _inode_load(nod_u) ) {
fuse_reply_err(req_u, ENOENT);
} else {
_fuse_buf_reply(req_u,
(c3_c*)(nod_u->val_u->buf_y),
nod_u->val_u->siz_z,
off_f,
max_z);
}
}
}
static struct fuse_lowlevel_ops fuse_api = {
.init = _fuse_ll_init,
.lookup = _fuse_ll_lookup,
.getattr = _fuse_ll_getattr,
.readdir = _fuse_ll_readdir,
.open = _fuse_ll_open,
.read = _fuse_ll_read,
};
/* _fuse_poll_cb():
*/
static void
_fuse_poll_cb(uv_poll_t* wax_u,
c3_i sas_i,
c3_i evt_i)
{
u3_fuse* fus_u = &u3_Host.fus_u;
uL(fprintf(uH, "fuse_poll_cb\n"));
{
c3_z buf_z = fuse_chan_bufsize(fus_u->cha_u);
c3_y* buf_y = malloc(buf_z + 1);
c3_i res_i = fuse_chan_recv(&fus_u->cha_u, (c3_c *)buf_y, buf_z);
if ( res_i < 0 ) {
if ( (res_i != -EINTR) && (res_i != -EAGAIN) ) {
uL(fprintf(uH, "fuse_poll_cb: error: %s\n", strerror(res_i)));
c3_assert(0);
}
}
else {
uL(fprintf(uH, "fuse_session_process\n"));
fuse_session_process(fus_u->sez_u,
(c3_c *)buf_y,
buf_z,
fus_u->cha_u);
uv_poll_start(&fus_u->wax_u, UV_READABLE, _fuse_poll_cb);
}
}
}
/* u3_fuse_io_init(): initialize FUSE.
*/
void
u3_fuse_io_init(void)
{
u3_fuse* fus_u = &u3_Host.fus_u;
#if 0
fus_u->mnt_c = malloc(strlen(u3_Host.dir_c) + 16);
strcpy(fus_u->mnt_c, u3_Host.dir_c);
strncat(fus_u->mnt_c, "/.urb/fun", 14);
#else
fus_u->mnt_c = strdup("/Users/cyarvin/urbit");
#endif
mkdir(fus_u->mnt_c, 0755);
uL(fprintf(uH, "fuse: mounting: %s\n", fus_u->mnt_c));
if ( !(fus_u->cha_u = fuse_mount(fus_u->mnt_c, 0)) ) {
uL(fprintf(uH, "fuse: could not mount %s\n", fus_u->mnt_c));
}
if ( !(fus_u->sez_u=fuse_lowlevel_new(0, &fuse_api, sizeof(fuse_api), 0)) ) {
uL(fprintf(uH, "fuse: could not create session\n"));
}
fuse_session_add_chan(fus_u->sez_u, fus_u->cha_u);
{
c3_i fid_i = fuse_chan_fd(fus_u->cha_u);
c3_i err_i;
uL(fprintf(uH, "fuse: fd: %d (loop %p)\n", fid_i, u3L));
if ( (err_i = uv_poll_init(u3L, &fus_u->wax_u, fid_i)) < 0 ) {
uL(fprintf(uH, "fuse: poll_init failed: %s\n", uv_strerror(err_i)));
}
uv_poll_start(&fus_u->wax_u, UV_READABLE, _fuse_poll_cb);
}
}
/* u3_fuse_io_exit(): shut down FUSE.
*/
void
u3_fuse_io_exit(void)
{
u3_fuse* fus_u = &u3_Host.fus_u;
uv_poll_stop(&fus_u->wax_u);
fuse_session_remove_chan(fus_u->cha_u);
fuse_session_destroy(fus_u->sez_u);
fuse_unmount(fus_u->mnt_c, fus_u->cha_u);
uL(fprintf(uH, "fuse: unmounted: %s\n", fus_u->mnt_c));
}

View File

@ -892,7 +892,7 @@ _http_request(u3_hreq* req_u)
c3__chis :
c3__this;
u3v_plan(pox,
u3_pier_plan(pox,
u3nq(typ,
req_u->hon_u->htp_u->sec,
u3nc(c3y, u3i_words(1, &req_u->ipf_w)),
@ -909,7 +909,7 @@ _http_request_dead(u3_hreq* req_u)
req_u->hon_u->coq_l,
req_u->seq_l);
u3v_plan(pox, u3nc(c3__thud, u3_nul));
u3_pier_plan(pox, u3nc(c3__thud, u3_nul));
}
/* _http_flush(): transmit any ready data.
@ -1000,7 +1000,7 @@ u3_http_ef_bake(void)
{
u3_noun pax = u3nq(u3_blip, c3__http, u3k(u3A->sen), u3_nul);
u3v_plan(pax, u3nc(c3__born, u3_nul));
u3_pier_plan(pax, u3nc(c3__born, u3_nul));
}
/* u3_http_ef_thou(): send %thou effect (incoming response) to http.

38920
vere/ivory.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -348,6 +348,7 @@ _lo_wall(u3_noun wol)
FILE* fil_u = u3_term_io_hija();
u3_noun wal = wol;
fil_u = stderr; // XX
while ( u3_nul != wal ) {
_lo_tape(fil_u, u3k(u3h(wal)));
@ -386,6 +387,7 @@ u3_lo_punt(c3_l tab_l, u3_noun tac)
if ( c3__leaf == u3h(act) ) {
FILE* fil_u = u3_term_io_hija();
fil_u = stderr; // XX
_lo_tape(fil_u, u3k(u3t(act)));
putc(13, fil_u);
putc(10, fil_u);
@ -485,6 +487,8 @@ u3_lo_shut(c3_o inn)
// clean shutdown
//
if ( c3n == u3_Host.liv ) {
fprintf(stderr, "loop: shut: exit\r\n");
// direct save and die
//
// u3_lo_grab("lo_exit", u3_none);
@ -493,8 +497,13 @@ u3_lo_shut(c3_o inn)
u3t_damp();
u3_lo_exit();
// save a checkpoint before exiting
u3e_save();
if ( _(u3_Host.ops_u.mad) ) {
u3_pier_exit();
}
else {
// save a checkpoint before exiting
u3e_save();
}
exit(u3_Host.xit_i);
}
else {
@ -651,16 +660,18 @@ _lo_slow()
void
u3_lo_loop()
{
uv_loop_t* lup_u = uv_default_loop();
u3_Host.lup_u = lup_u;
if ( !u3_Host.lup_u ) {
u3_Host.lup_u = uv_default_loop();
}
signal(SIGPIPE, SIG_IGN); // pipe, schmipe
// signal(SIGIO, SIG_IGN); // linux is wont to produce for some reason
_lo_init();
u3_raft_init();
if ( !_(u3_Host.ops_u.mad) ) {
u3_raft_init();
}
if ( _(u3_Host.ops_u.tex) ) {
u3t_boff();
@ -691,7 +702,7 @@ u3_lo_lead(void)
_lo_talk();
{
u3_unix_ef_look(c3n);
u3v_plan(u3nt(u3_blip, c3__ames, u3_nul),
u3_pier_plan(u3nt(u3_blip, c3__ames, u3_nul),
u3nc(c3__kick, u3k(u3A->now)));
}
_lo_poll();
@ -706,6 +717,7 @@ u3_lo_lead(void)
if ( u3_Host.ops_u.who_c ) {
u3_term_ef_ticket(u3_Host.ops_u.who_c, u3_Host.ops_u.tic_c);
}
} else {
u3_term_ef_boil(1);
}

View File

@ -1,5 +1,4 @@
/* v/main.c
**
*/
#include <stdio.h>
#include <stdlib.h>
@ -75,6 +74,7 @@ _main_getopt(c3_i argc, c3_c** argv)
u3_Host.ops_u.tex = c3n;
u3_Host.ops_u.pro = c3n;
u3_Host.ops_u.dry = c3n;
u3_Host.ops_u.mad = c3n;
u3_Host.ops_u.veb = c3n;
u3_Host.ops_u.qui = c3n;
u3_Host.ops_u.nuu = c3n;
@ -82,7 +82,7 @@ _main_getopt(c3_i argc, c3_c** argv)
u3_Host.ops_u.rep = c3n;
u3_Host.ops_u.kno_w = DefaultKernel;
while ( (ch_i=getopt(argc, argv,"G:B:A:I:w:t:f:k:l:n:p:r:LabcdgmqvxFMPDXR")) != -1 ) {
while ( (ch_i=getopt(argc, argv,"G:B:A:I:w:t:f:k:l:n:p:r:LabcdgjmqvxFMPDXR")) != -1 ) {
switch ( ch_i ) {
case 'M': {
u3_Host.ops_u.mem = c3y;
@ -113,6 +113,10 @@ _main_getopt(c3_i argc, c3_c** argv)
u3_Host.ops_u.tic_c = _main_presig(optarg);
break;
}
case 'j': {
u3_Host.ops_u.mad = c3y;
break;
}
case 'x': {
u3_Host.ops_u.tex = c3y;
break;
@ -441,6 +445,20 @@ c3_i
main(c3_i argc,
c3_c** argv)
{
// Detect executable purpose.
//
{
c3_c* nam_c = strrchr(argv[0], '/');
if ( !nam_c )
nam_c = argv[0];
else nam_c++;
if ( !strcmp("urbit-worker", nam_c) ) {
return u3_serf_main(argc, argv);
}
}
// Parse options.
//
if ( c3n == _main_getopt(argc, argv) ) {
@ -453,18 +471,21 @@ main(c3_i argc,
return 0;
}
if ( c3y == u3_Host.ops_u.nuu ) {
struct stat s;
if ( !stat(u3_Host.dir_c, &s) ) {
fprintf(stderr, "tried to create, but %s already exists\n", u3_Host.dir_c);
fprintf(stderr, "normal usage: %s %s\n", argv[0], u3_Host.dir_c);
exit(1);
}
} else {
struct stat s;
if ( -1 == stat(u3_Host.dir_c, &s) ) {
fprintf(stderr, "%s: urbit not found\n", u3_Host.dir_c);
u3_ve_usage(argc, argv);
if ( c3n == u3_Host.ops_u.mad ) {
if ( c3y == u3_Host.ops_u.nuu ) {
struct stat s;
if ( !stat(u3_Host.dir_c, &s) ) {
fprintf(stderr, "tried to create, but %s already exists\n",
u3_Host.dir_c);
fprintf(stderr, "normal usage: %s %s\n", argv[0], u3_Host.dir_c);
exit(1);
}
} else {
struct stat s;
if ( -1 == stat(u3_Host.dir_c, &s) ) {
fprintf(stderr, "%s: urbit not found\n", u3_Host.dir_c);
u3_ve_usage(argc, argv);
}
}
}
@ -546,33 +567,29 @@ main(c3_i argc,
u3C.wag_w |= u3o_dryrun;
}
}
u3m_boot(u3_Host.ops_u.nuu,
u3_Host.ops_u.gab,
u3_Host.dir_c,
u3_Host.ops_u.pil_c);
/* Start Arvo.
*/
if ( _(u3_Host.ops_u.mad) ) {
u3_pier_boot(u3_Host.dir_c, u3_Host.ops_u.pil_c);
}
else {
u3m_boot(u3_Host.ops_u.nuu,
u3_Host.dir_c,
u3_Host.ops_u.pil_c);
/* Start Arvo.
*/
#if 1
{
struct timeval tim_tv;
u3_noun now;
{
struct timeval tim_tv;
u3_noun now;
gettimeofday(&tim_tv, 0);
now = u3_time_in_tv(&tim_tv);
gettimeofday(&tim_tv, 0);
now = u3_time_in_tv(&tim_tv);
u3v_start(now);
}
u3v_start(now);
}
#endif
#if 0
/* Initial checkpoint.
*/
if ( _(u3_Host.ops_u.nuu) ) {
printf("about to save.\r\n");
u3e_save();
printf("saved.\r\n");
}
#endif
}
// u3e_grab("main", u3_none);

335
vere/newt.c Normal file
View File

@ -0,0 +1,335 @@
/* vere/newt.c
**
** implements noun blob messages with trivial framing.
**
** a message is a 64-bit little-endian byte count, followed
** by the indicated number of bytes. the bytes are the
** the ++cue of of a noun.
**
** 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 <curses.h>
#include <termios.h>
#include <term.h>
#include "all.h"
#include "vere/vere.h"
/* _newt_consume(): advance buffer processing.
*/
static void
_newt_consume(u3_moat* mot_u)
{
/* process stray bytes, trying to create a new message
** or add a block to an existing one.
*/
while ( 1 ) {
if ( mot_u->rag_y ) {
/* if there is a live message, add a block to the queue.
*/
if ( mot_u->mes_u ) {
u3_meat* met_u;
/* create block
*/
met_u = c3_malloc(mot_u->len_d + (c3_d) sizeof(u3_meat));
met_u->nex_u = 0;
met_u->len_d = mot_u->len_d;
memcpy(met_u->hun_y, mot_u->rag_y, mot_u->len_d);
#if 0
fprintf(stderr,
"newt: %d: create: msg %p, new block %p, len %lld, has %lld, needs %lld\r\n",
getpid(),
mot_u->mes_u,
met_u,
met_u->len_d,
mot_u->mes_u->has_d,
mot_u->mes_u->len_d);
#endif
/* enqueue block
*/
if ( !mot_u->mes_u->meq_u ) {
mot_u->mes_u->meq_u = mot_u->mes_u->qem_u = met_u;
}
else {
mot_u->mes_u->qem_u->nex_u = met_u;
mot_u->mes_u->qem_u = met_u;
}
mot_u->mes_u->has_d += met_u->len_d;
/* free consumed stray bytes
*/
c3_free(mot_u->rag_y);
mot_u->len_d = 0;
mot_u->rag_y = 0;
}
else {
/* no message, but enough stray bytes to fill in
** a length; collect them and create a message.
*/
if ( mot_u->len_d >= 8ULL ) {
c3_d nel_d = 0;
nel_d |= ((c3_d) mot_u->rag_y[0]) << 0ULL;
nel_d |= ((c3_d) mot_u->rag_y[1]) << 8ULL;
nel_d |= ((c3_d) mot_u->rag_y[2]) << 16ULL;
nel_d |= ((c3_d) mot_u->rag_y[3]) << 24ULL;
nel_d |= ((c3_d) mot_u->rag_y[4]) << 32ULL;
nel_d |= ((c3_d) mot_u->rag_y[5]) << 40ULL;
nel_d |= ((c3_d) mot_u->rag_y[6]) << 48ULL;
nel_d |= ((c3_d) mot_u->rag_y[7]) << 56ULL;
#if 0
fprintf(stderr, "newt: %d: parsed length %lld\r\n",
getpid(),
nel_d);
#endif
mot_u->len_d -= 8ULL;
mot_u->mes_u = c3_malloc(sizeof(u3_mess));
mot_u->mes_u->len_d = nel_d;
mot_u->mes_u->has_d = 0;
mot_u->mes_u->meq_u = mot_u->mes_u->qem_u = 0;
if ( !mot_u->len_d ) {
c3_free(mot_u->rag_y);
mot_u->rag_y = 0;
}
else {
/* remove consumed length from stray bytes
*/
c3_y* buf_y = c3_malloc(mot_u->len_d);
memcpy(buf_y, mot_u->rag_y + 8, mot_u->len_d);
c3_free(mot_u->rag_y);
mot_u->rag_y = buf_y;
/* remaining bytes will be installed as message meat
*/
continue;
}
}
}
}
/* check for message completions
*/
if ( mot_u->mes_u && (mot_u->mes_u->has_d >= mot_u->mes_u->len_d) ) {
c3_d len_d = mot_u->mes_u->len_d;
c3_y* buf_y = c3_malloc(len_d);
c3_d pat_d = 0;
u3_meat* met_u;
/* we should have just cleared this
*/
c3_assert(!mot_u->rag_y);
c3_assert(!mot_u->len_d);
/* collect queue blocks, cleaning them up; return any spare meat
** to the rag.
*/
{
met_u = mot_u->mes_u->meq_u;
while ( met_u && (pat_d < len_d) ) {
u3_meat* nex_u = met_u->nex_u;
c3_d end_d = (pat_d + met_u->len_d);
c3_d eat_d;
c3_d rem_d;
eat_d = c3_min(len_d, end_d) - pat_d;
memcpy(buf_y + pat_d, met_u->hun_y, eat_d);
pat_d += eat_d;
rem_d = (met_u->len_d - eat_d);
if ( rem_d ) {
mot_u->rag_y = c3_malloc(rem_d);
memcpy(mot_u->rag_y, met_u->hun_y + eat_d, rem_d);
mot_u->len_d = rem_d;
/* one: unless we got a bad length, this has to be the last
** block in the message.
**
** two: bad data on a newt channel can cause us to assert.
** that's actually the right thing for a private channel.
*/
c3_assert(0 == nex_u);
}
c3_free(met_u);
met_u = nex_u;
}
c3_assert(pat_d == len_d);
/* clear the message
*/
c3_free(mot_u->mes_u);
mot_u->mes_u = 0;
}
/* build and send the object
*/
{
u3_noun mat = u3i_bytes((c3_w) len_d, buf_y);
mot_u->pok_f(mot_u->vod_p, mat);
}
/* continue; spare meat may need processing
*/
continue;
}
/* nothing happening, await next event
*/
break;
}
}
/* _raft_alloc(): libuv-style allocator for raft.
*/
static void
_newt_alloc(uv_handle_t* had_u,
size_t len_i,
uv_buf_t* buf_u)
{
void* ptr_v = c3_malloc(len_i);
*buf_u = uv_buf_init(ptr_v, len_i);
}
/* _newt_read_cb(): stream input callback.
*/
void
_newt_read_cb(uv_stream_t* str_u,
ssize_t len_i,
const uv_buf_t* buf_u)
{
c3_d len_d = (c3_d) len_i;
u3_moat* mot_u = (void *)str_u;
if ( UV_EOF == len_i ) {
fprintf(stderr, "newt: %d: stream closed\r\n", getpid());
uv_read_stop(str_u);
mot_u->bal_f(mot_u->vod_p, "stream closed");
}
else {
#if 0
fprintf(stderr, "newt: %d: read %ld\r\n", getpid(), len_i);
#endif
if ( mot_u->rag_y ) {
mot_u->rag_y = c3_realloc(mot_u->rag_y, mot_u->len_d + len_d);
memcpy(mot_u->rag_y + mot_u->len_d, buf_u->base, len_d);
c3_free(buf_u->base);
}
else {
mot_u->rag_y = (c3_y *)buf_u->base;
mot_u->len_d = len_d;
}
_newt_consume(mot_u);
}
}
/* u3_newt_read(): start stream reading.
*/
void
u3_newt_read(u3_moat* mot_u)
{
c3_i err_i;
mot_u->mes_u = 0;
mot_u->len_d = 0;
mot_u->rag_y = 0;
err_i = uv_read_start((uv_stream_t*) &mot_u->pyp_u,
_newt_alloc,
_newt_read_cb);
if ( err_i != 0 ) {
mot_u->bal_f(mot_u, uv_strerror(err_i));
}
}
/* write request for newt
*/
struct _u3_write_t {
uv_write_t wri_u;
u3_mojo* moj_u;
void* vod_p;
c3_y* buf_y;
};
/* _newt_write_cb(): generic write callback.
*/
static void
_newt_write_cb(uv_write_t* wri_u, c3_i sas_i)
{
struct _u3_write_t* req_u = (struct _u3_write_t*)wri_u;
void* vod_p = req_u->vod_p;
u3_mojo* moj_u = req_u->moj_u;
free(req_u->buf_y);
free(req_u);
if ( 0 != sas_i ) {
fprintf(stderr, "newt: bad write %d\r\n", sas_i);
moj_u->bal_f(vod_p, uv_strerror(sas_i));
}
}
/* u3_newt_write(): write atom to stream; free atom.
*/
void
u3_newt_write(u3_mojo* moj_u,
u3_atom mat,
void* vod_p)
{
c3_w len_w = u3r_met(3, mat);
c3_y* buf_y = c3_malloc(len_w + 8);
struct _u3_write_t* req_u = c3_malloc(sizeof(*req_u));
uv_buf_t buf_u;
c3_i err_i;
/* write header; c3_d is futureproofing
*/
buf_y[0] = ((len_w >> 0) & 0xff);
buf_y[1] = ((len_w >> 8) & 0xff);
buf_y[2] = ((len_w >> 16) & 0xff);
buf_y[3] = ((len_w >> 24) & 0xff);
buf_y[4] = buf_y[5] = buf_y[6] = buf_y[7] = 0;
u3r_bytes(0, len_w, buf_y + 8, mat);
u3z(mat);
req_u->moj_u = moj_u;
req_u->buf_y = buf_y;
buf_u.base = (c3_c*) buf_y;
buf_u.len = len_w + 8;
#if 0
fprintf(stderr, "newt: %d: write %d\n", getpid(), len_w + 8);
#endif
if ( 0 != (err_i = uv_write((uv_write_t*)req_u,
(uv_stream_t*)&moj_u->pyp_u,
&buf_u,
1,
_newt_write_cb)) )
{
moj_u->bal_f(moj_u, uv_strerror(err_i));
}
}

1463
vere/pier.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -379,7 +379,7 @@ u3_reck_kick(u3_noun ovo)
(c3__init == u3h(u3t(ovo))) )
#endif
{
u3v_plan(u3nt(u3_blip, c3__term, u3_nul),
u3_pier_plan(u3nt(u3_blip, c3__term, u3_nul),
u3nc(c3__flog, u3k(u3t(ovo))));
}
else {

408
vere/serf.c Normal file
View File

@ -0,0 +1,408 @@
/* vere/serf.c
**
** the main loop of a worker 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 <curses.h>
#include <termios.h>
#include <term.h>
#include "all.h"
#include <vere/vere.h>
typedef struct _u3_serf {
c3_d evt_d; // last event processed
c3_l mug_l; // hash of state
c3_d key_d[4]; // disk key
u3_moat inn_u; // message input
u3_mojo out_u; // message output
} u3_serf;
static u3_serf u3V;
/* serf-lord protocol:
**
** ++ plea :: from serf to lord
** $% $: $play :: send events
** p/@ :: first number expected
** q/@ :: mug of state (or 0 to boot)
** == ::
** $: $done :: event executed unchanged
** p/@ :: number of this event
** q/@ :: mug of state (or 0)
** r/(list ovum) :: actions
** == ::
** $: $work :: replace and retry
** p/@ :: event number
** q/@ :: mug of state (or 0)
** r/(pair date ovum) :: event
** == == ::
**
** ++ writ :: from lord to serf
** $% $: $exit :: snapshot, then exit
** p/@ :: exit code
** == ::
** $: $save :: save snapshot to disk
** p/@ :: number of old snaps to save
** == ::
** $: $work :: execute event
** p/@ :: event number
** q/@ :: mug of state (or 0)
** r/(pair date ovum) :: event
** == == ::
*/
/* _serf_fail(): failure stub.
*/
static void
_serf_fail(void* vod_p, const c3_c* wut_c)
{
fprintf(stderr, "serf: fail: %s\r\n", wut_c);
exit(1);
}
/* _serf_send(): send result back to lord.
*/
static void
_serf_send(u3_noun job)
{
u3_newt_write(&u3V.out_u, u3ke_jam(job), 0);
}
/* _serf_send_replace(): send replacement job back to lord.
*/
static void
_serf_send_replace(u3_noun ovo)
{
_serf_send(u3nq(c3__work,
u3i_chubs(1, &u3V.evt_d),
u3V.mug_l,
u3nc(u3k(u3A->now), ovo)));
}
/* _serf_send_complete(): report completion.
*/
static void
_serf_send_complete(u3_noun vir)
{
_serf_send(u3nq(c3__done,
u3i_chubs(1, &u3V.evt_d),
u3r_mug(u3A->roc),
vir));
}
/* _serf_lame(): event failed, replace with error event.
*/
static void
_serf_lame(u3_noun ovo, u3_noun why, u3_noun tan)
{
/* XX: the next crud will contain the original event.
*/
u3z(ovo);
_serf_send_replace(u3nt(c3__crud, why, tan));
}
/* _serf_sure(): event succeeded, report completion.
*/
static void
_serf_sure(u3_noun ovo, u3_noun vir, u3_noun cor)
{
u3z(ovo);
u3z(u3A->roc);
u3A->roc = cor;
_serf_send_complete(vir);
}
/* _serf_poke_live(): apply event.
*/
static void
_serf_poke_live(c3_d evt_d, // event number
c3_l mug_l, // mug of state
u3_noun job) // event date
{
u3_noun now = u3k(u3h(job));
u3_noun ovo = u3k(u3t(job));
// fprintf(stderr, "serf: (%lld)| live\r\n", evt_d);
c3_assert(evt_d == u3V.evt_d + 1ULL);
u3V.evt_d = evt_d;
u3z(job);
{
u3_noun gon;
if ( mug_l ) {
c3_assert(u3r_mug(u3A->roc) == mug_l);
}
u3z(u3A->now);
u3A->now = now;
u3A->ent_d = evt_d;
#ifdef GHETTO
struct timeval b4, f2, d0;
gettimeofday(&b4, 0);
#endif
gon = u3m_soft(0, u3v_poke, u3k(ovo));
#ifdef GHETTO
c3_w ms_w;
c3_w clr_w;
gettimeofday(&f2, 0);
timersub(&f2, &b4, &d0);
ms_w = (d0.tv_sec * 1000) + (d0.tv_usec / 1000);
clr_w = ms_w > 1000 ? 1 : ms_w < 100 ? 2 : 3; // red, green, yellow
if (c3__belt != u3h(u3t(ovo)) || clr_w != 2) {
uL(fprintf(uH, "\x1b[3%dm%%%s %4d.%02dms\x1b[0m\n",
clr_w, txt_c, ms_w, (int) (d0.tv_usec % 1000) / 10));
}
free(txt_c);
#endif
if ( u3_blip != u3h(gon) ) {
u3_noun why = u3k(u3h(gon));
u3_noun tan = u3k(u3t(gon));
u3z(gon);
_serf_lame(ovo, why, tan);
}
else {
u3_noun vir = u3k(u3h(u3t(gon)));
u3_noun cor = u3k(u3t(u3t(gon)));
_serf_sure(ovo, vir, cor);
}
}
}
/* _serf_boot_fire(): execute boot sequence.
*/
static u3_noun
_serf_boot_fire(u3_noun eve)
{
u3_noun cor = u3n_nock_on(eve, u3nt(2, u3nc(0, 3), u3nc(0, 2)));
u3_noun pro;
pro = u3k(u3r_at(7, cor));
u3z(cor);
return pro;
}
/* _serf_poke_boot(): apply initial-stage event.
*/
static void
_serf_poke_boot(c3_d evt_d,
c3_l mug_l,
u3_noun job)
{
u3A->roe = u3nc(job, u3A->roe);
c3_assert(evt_d == u3V.evt_d + 1ULL);
u3V.evt_d = evt_d;
fprintf(stderr, "serf: (%lld)| boot\r\n", evt_d);
if ( evt_d == 5 ) {
u3_noun eve = u3kb_flop(u3A->roe);
u3_noun pru;
u3A->roe = 0;
fprintf(stderr, "serf: (5)| pill: %x\r\n", u3r_mug(eve));
pru = u3m_soft(0, _serf_boot_fire, eve);
if ( u3h(pru) != 0 ) {
fprintf(stderr, "boot failed\r\n");
exit(1);
}
fprintf(stderr, "serf: (5)| core: %x\r\n", u3r_mug(u3t(pru)));
u3A->ken = 0;
u3A->roc = u3k(u3t(pru));
u3z(pru);
}
_serf_send(u3nq(c3__done,
u3i_chubs(1, &evt_d),
0,
u3_nul));
}
/* _serf_poke_work(): apply event.
*/
static void
_serf_poke_work(c3_d evt_d, // event number
c3_l mug_l, // mug of state
u3_noun job) // full event
{
if ( evt_d < 6 ) {
_serf_poke_boot(evt_d, mug_l, job);
}
else {
_serf_poke_live(evt_d, mug_l, job);
}
}
/* _serf_poke_exit(): exit on command.
*/
static void
_serf_poke_exit(c3_w cod_w) // exit code
{
exit(cod_w);
}
/* _serf_poke():
*/
void
_serf_poke(void* vod_p, u3_noun mat)
{
u3_noun jar = u3ke_cue(mat);
if ( c3y != u3du(jar) ) {
fprintf(stderr, "1\r\n");
goto error;
}
else {
u3_noun p_jar, q_jar, r_jar;
switch ( u3h(jar) ) {
case c3__work: {
if ( (c3n == u3r_qual(jar, 0, &p_jar, &q_jar, &r_jar)) ||
(c3n == u3ud(p_jar)) ||
(u3r_met(6, p_jar) != 1) ||
(c3n == u3ud(q_jar)) ||
(u3r_met(5, q_jar) > 1) )
{
fprintf(stderr, "2\r\n");
goto error;
}
_serf_poke_work(u3r_chub(0, p_jar),
u3r_word(0, q_jar),
u3k(r_jar));
break;
}
case c3__exit: {
if ( (c3n == u3r_cell(jar, 0, &p_jar)) ||
(c3n == u3ud(p_jar)) ||
(u3r_met(3, p_jar) > 1) )
{
goto error;
}
_serf_poke_exit(u3k(p_jar));
break;
}
case c3__save: {
if ( (c3n == u3r_cell(jar, 0, &p_jar)) ||
(c3n == u3ud(p_jar)) ) {
goto error;
}
fprintf(stderr, "serf: save\r\n");
u3e_save();
break;
}
default: {
fprintf(stderr, "3\r\n");
goto error;
}
}
return;
}
error: {
_serf_fail(0, "bad jar");
}
u3z(jar);
}
/* u3_serf_boot(): send startup message to manager.
*/
void
u3_serf_boot(void)
{
c3_d nex_d = u3A->ent_d + 1ULL;
fprintf(stderr, "serf: play %lld\r\n", nex_d);
_serf_send(u3nt(c3__play, u3i_chubs(1, &nex_d), 0));
}
/* u3_serf_main(): main() when run as urbit-client
*/
c3_i
u3_serf_main(c3_i argc, c3_c* argv[])
{
uv_loop_t* lup_u = uv_default_loop();
c3_c* dir_c = argv[1];
c3_c* key_c = argv[2];
c3_assert(3 == argc);
/* load passkey
*/
{
sscanf(key_c, "%llx:%llx:%llx:%llx", &u3V.key_d[0],
&u3V.key_d[1],
&u3V.key_d[2],
&u3V.key_d[3]);
}
/* boot image
*/
{
u3V.evt_d = u3m_boot_new(dir_c);
}
/* configure pipe to lord process
*/
{
c3_i err_i;
err_i = uv_pipe_init(lup_u, &u3V.inn_u.pyp_u, 0);
c3_assert(!err_i);
uv_pipe_open(&u3V.inn_u.pyp_u, 0);
err_i = uv_pipe_init(lup_u, &u3V.out_u.pyp_u, 0);
c3_assert(!err_i);
uv_pipe_open(&u3V.out_u.pyp_u, 1);
}
/* set up writing
*/
u3V.out_u.bal_f = _serf_fail;
/* start reading
*/
u3V.inn_u.vod_p = &u3V;
u3V.inn_u.pok_f = _serf_poke;
u3V.inn_u.bal_f = _serf_fail;
u3_newt_read(&u3V.inn_u);
/* send start request
*/
u3_serf_boot();
/* enter loop
*/
uv_run(lup_u, UV_RUN_DEFAULT);
return 0;
}

View File

@ -85,7 +85,7 @@ _term_close_cb(uv_handle_t* han_t)
{
u3_noun tid = u3dc("scot", c3__ud, tty_u->tid_l);
u3_noun pax = u3nq(u3_blip, c3__term, tid, u3_nul);
u3v_plan(u3k(pax), u3nc(c3__hook, u3_nul));
u3_pier_plan(u3k(pax), u3nc(c3__hook, u3_nul));
u3z(pax);
}
free(tty_u);
@ -338,9 +338,9 @@ _term_listen_cb(uv_stream_t *wax_u, int sas_i)
{
u3_noun tid = u3dc("scot", c3__ud, tty_u->tid_l);
u3_noun pax = u3nq(u3_blip, c3__term, tid, u3_nul);
// u3v_plan(u3k(pax), u3nq(c3__flow, c3__seat, c3__dojo, u3_nul));
u3v_plan(u3k(pax), u3nc(c3__blew, u3nc(80, 25)));
u3v_plan(u3k(pax), u3nc(c3__hail, u3_nul));
// u3_pier_plan(u3k(pax), u3nq(c3__flow, c3__seat, c3__dojo, u3_nul));
u3_pier_plan(u3k(pax), u3nc(c3__blew, u3nc(80, 25)));
u3_pier_plan(u3k(pax), u3nc(c3__hail, u3_nul));
u3z(pax);
}
@ -721,7 +721,7 @@ _term_io_belt(u3_utty* uty_u, u3_noun blb)
u3_noun tid = u3dc("scot", c3__ud, uty_u->tid_l);
u3_noun pax = u3nq(u3_blip, c3__term, tid, u3_nul);
u3v_plan(pax, u3nc(c3__belt, blb));
u3_pier_plan(pax, u3nc(c3__belt, blb));
}
/* _tel_event(): telnet sucker
@ -793,7 +793,7 @@ _tel_opt(_te_nvt* nvt, telnet_byte opt, _to_evt* evt)
tid = u3dc("scot", c3__ud, tel_u->uty_t.tid_l);
pax = u3nq(u3_blip, c3__term, tid, u3_nul);
blu = u3nc(col_s, row_s);
u3v_plan(pax, u3nc(c3__blew, blu));
u3_pier_plan(pax, u3nc(c3__blew, blu));
break;
}
}
@ -1218,7 +1218,7 @@ u3_term_ef_winc(void)
{
u3_noun pax = u3nq(u3_blip, c3__term, '1', u3_nul);
u3v_plan(pax, u3nc(c3__blew, u3_term_get_blew(1)));
u3_pier_plan(pax, u3nc(c3__blew, u3_term_get_blew(1)));
}
/* u3_term_ef_ctlc(): send ^C on console.
@ -1228,7 +1228,7 @@ u3_term_ef_ctlc(void)
{
u3_noun pax = u3nq(u3_blip, c3__term, '1', u3_nul);
u3v_plan(pax, u3nt(c3__belt, c3__ctl, 'c'));
u3_pier_plan(pax, u3nt(c3__belt, c3__ctl, 'c'));
}
/* u3_term_ef_boil(): initial effects for loaded servers.
@ -1239,10 +1239,10 @@ u3_term_ef_boil(void)
{
u3_noun pax = u3nq(u3_blip, c3__term, '1', u3_nul);
// u3v_plan(u3k(pax), u3nc(c3__init, u3k(u3h(u3A->own))));
u3v_plan(u3k(pax), u3nc(c3__harm, u3_nul));
u3v_plan(u3k(pax), u3nc(c3__blew, u3_term_get_blew(1)));
u3v_plan(u3k(pax), u3nc(c3__hail, u3_nul));
// u3_pier_plan(u3k(pax), u3nc(c3__init, u3k(u3h(u3A->own))));
u3_pier_plan(u3k(pax), u3nc(c3__harm, u3_nul));
u3_pier_plan(u3k(pax), u3nc(c3__blew, u3_term_get_blew(1)));
u3_pier_plan(u3k(pax), u3nc(c3__hail, u3_nul));
u3z(pax);
}
@ -1255,7 +1255,7 @@ u3_term_ef_verb(void)
{
u3_noun pax = u3nq(u3_blip, c3__term, '1', u3_nul);
u3v_plan(pax, u3nc(c3__verb, u3_nul));
u3_pier_plan(pax, u3nc(c3__verb, u3_nul));
}
/* u3_term_ef_ticket(): initial effects for new ticket.
@ -1281,7 +1281,7 @@ u3_term_ef_ticket(c3_c* who_c, c3_c* tic_c)
}
else { tic = u3k(u3t(tuc)); u3z(tuc); }
u3v_plan(pax, u3nt(c3__tick, who, tic));
u3_pier_plan(pax, u3nt(c3__tick, who, tic));
}
/* u3_term_ef_bake(): initial effects for new terminal.
@ -1291,10 +1291,10 @@ u3_term_ef_bake(u3_noun fav)
{
u3_noun pax = u3nq(u3_blip, c3__term, '1', u3_nul);
u3v_plan(u3k(pax), u3nc(c3__boot, fav));
// u3v_plan(u3k(pax), u3nq(c3__flow, c3__seat, c3__dojo, u3_nul));
u3v_plan(u3k(pax), u3nc(c3__blew, u3_term_get_blew(1)));
u3v_plan(u3k(pax), u3nc(c3__hail, u3_nul));
u3_pier_plan(u3k(pax), u3nc(c3__boot, fav));
// u3_pier_plan(u3k(pax), u3nq(c3__flow, c3__seat, c3__dojo, u3_nul));
u3_pier_plan(u3k(pax), u3nc(c3__blew, u3_term_get_blew(1)));
u3_pier_plan(u3k(pax), u3nc(c3__hail, u3_nul));
u3z(pax);
}

View File

@ -962,7 +962,7 @@ _unix_update_mount(u3_umon* mon_u, u3_noun all)
can = u3kb_weld(_unix_update_node(nod_u), can);
}
u3v_plan(u3nq(u3_blip, c3__sync, u3k(u3A->sen), u3_nul),
u3_pier_plan(u3nq(u3_blip, c3__sync, u3k(u3A->sen), u3_nul),
u3nq(c3__into, u3i_string(mon_u->nam_c), all, can));
}
}
@ -1337,7 +1337,7 @@ u3_unix_io_init(void)
unx_u->dyr = c3n;
if ( c3n == u3_Host.ops_u.nuu ) {
u3v_plan(u3nt(u3_blip, c3__boat, u3_nul),
u3_pier_plan(u3nt(u3_blip, c3__boat, u3_nul),
u3nc(c3__boat, u3_nul));
}
}
@ -1450,7 +1450,7 @@ u3_unix_ef_initial_into()
{
u3_noun can = _unix_initial_update_dir(u3_Host.ops_u.arv_c);
u3v_plan(u3nq(u3_blip, c3__sync, u3k(u3A->sen), u3_nul),
u3_pier_plan(u3nq(u3_blip, c3__sync, u3k(u3A->sen), u3_nul),
u3nq(c3__into, u3_nul, c3y, can));
}