mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-11-24 10:33:22 +03:00
Merge remote-tracking branch 'cgyarvin/revere-next'
New event system. Command line options are temporarily out of order; please use the exact same command to restart an urbit that you did to start it, including the -c, -A, and -B options.
This commit is contained in:
commit
2be28943fd
16
Makefile
16
Makefile
@ -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)
|
||||
@ -349,15 +350,17 @@ V_OFILES=\
|
||||
vere/behn.o \
|
||||
vere/cttp.o \
|
||||
vere/http.o \
|
||||
vere/loop.o \
|
||||
vere/raft.o \
|
||||
vere/newt.o \
|
||||
vere/reck.o \
|
||||
vere/sist.o \
|
||||
vere/term.o \
|
||||
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
|
||||
@ -388,7 +391,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."
|
||||
@ -397,6 +400,9 @@ all: urbit
|
||||
.make.conf:
|
||||
@echo "# Set custom configuration here, please!" > ".make.conf"
|
||||
|
||||
links: urbit
|
||||
$(LN) $(BIN)/urbit $(BIN)/urbit-worker
|
||||
|
||||
urbit: $(BIN)/urbit
|
||||
|
||||
$(LIBED25519):
|
||||
|
@ -90,3 +90,5 @@
|
||||
c3_assert(!"memory lost"); \
|
||||
} \
|
||||
rut;})
|
||||
#define c3_free(s) free(s)
|
||||
#define c3_realloc(s, l) realloc(s, l)
|
||||
|
@ -187,5 +187,10 @@
|
||||
# define c3_rand(rd) (getentropy((void*)rd, 64) == 0 ? \
|
||||
(void)0 : c3_assert(!"ent"))
|
||||
# else
|
||||
# define c3_rand u3_sist_rand
|
||||
# define c3_rand u3_pier_rand
|
||||
# endif
|
||||
# if defined(U3_OS_linux)
|
||||
# define DEVRANDOM "/dev/urandom"
|
||||
# else
|
||||
# define DEVRANDOM "/dev/random"
|
||||
# endif
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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.
|
||||
**
|
||||
|
@ -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*
|
||||
|
@ -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
|
||||
|
@ -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,16 +609,17 @@
|
||||
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 fog; // -X, skip last event
|
||||
c3_o fak; // -F, fake carrier
|
||||
@ -555,7 +628,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;
|
||||
@ -571,7 +644,6 @@
|
||||
u3_cttp ctp_u; // http clients
|
||||
u3_utel tel_u; // telnet listener
|
||||
u3_utty* uty_u; // linked terminal list
|
||||
u3_ames sam_u; // packet interface
|
||||
u3_save sav_u; // autosave
|
||||
u3_opts ops_u; // commandline options
|
||||
u3_unix unx_u; // sync and clay
|
||||
@ -581,15 +653,101 @@
|
||||
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_ames* sam_u; // packet interface
|
||||
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,17 +884,82 @@
|
||||
u3_noun
|
||||
u3_ve_zeus(u3_noun hap);
|
||||
|
||||
/** Output.
|
||||
/** Filesystem (async)
|
||||
**/
|
||||
/* u3_ve_tank(): print a tank at `tab`.
|
||||
/* 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_ve_tank(c3_l tab_l, u3_noun tac);
|
||||
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_reck_kick(): handle effect.
|
||||
*/
|
||||
void
|
||||
u3_reck_kick(u3_noun ovo);
|
||||
u3_reck_kick(u3_pier* pir_u, u3_noun ovo);
|
||||
|
||||
|
||||
/** Main loop, new style.
|
||||
@ -833,7 +1056,7 @@
|
||||
/* u3_term_ef_bake(): initial effects for new server.
|
||||
*/
|
||||
void
|
||||
u3_term_ef_bake(u3_noun fav);
|
||||
u3_term_ef_bake(void);
|
||||
|
||||
/* u3_term_ef_blit(): send %blit effect to terminal.
|
||||
*/
|
||||
@ -884,33 +1107,39 @@
|
||||
/* u3_ames_ef_bake(): create ames duct.
|
||||
*/
|
||||
void
|
||||
u3_ames_ef_bake(void);
|
||||
u3_ames_ef_bake(u3_pier* pir_u);
|
||||
|
||||
/* u3_ames_ef_send(): send packet to network.
|
||||
*/
|
||||
void
|
||||
u3_ames_ef_send(u3_noun lan,
|
||||
u3_ames_ef_send(u3_pier* pir_u,
|
||||
u3_noun lan,
|
||||
u3_noun pac);
|
||||
|
||||
/* u3_ames_io_init(): initialize ames I/O.
|
||||
*/
|
||||
void
|
||||
u3_ames_io_init(void);
|
||||
u3_ames_io_init(u3_pier* pir_u);
|
||||
|
||||
/* u3_ames_io_talk(): bring up listener.
|
||||
*/
|
||||
void
|
||||
u3_ames_io_talk(void);
|
||||
u3_ames_io_talk(u3_pier* pir_u);
|
||||
|
||||
/* u3_ames_ef_bake(): send initial events.
|
||||
*/
|
||||
void
|
||||
u3_ames_io_bake(u3_pier* pir_u);
|
||||
|
||||
/* u3_ames_io_exit(): terminate ames I/O.
|
||||
*/
|
||||
void
|
||||
u3_ames_io_exit(void);
|
||||
u3_ames_io_exit(u3_pier* pir_u);
|
||||
|
||||
/* u3_ames_io_poll(): update ames IO state.
|
||||
*/
|
||||
void
|
||||
u3_ames_io_poll(void);
|
||||
u3_ames_io_poll(u3_pier* pir_u);
|
||||
|
||||
/** Autosave.
|
||||
**/
|
||||
@ -941,6 +1170,16 @@
|
||||
void
|
||||
u3_unix_ef_hold();
|
||||
|
||||
/* u3_unix_ef_boot(): boot actions
|
||||
*/
|
||||
void
|
||||
u3_unix_ef_boot(void);
|
||||
|
||||
/* u3_unix_ef_bake(): initial effects for new process.
|
||||
*/
|
||||
void
|
||||
u3_unix_ef_bake(void);
|
||||
|
||||
/* u3_unix_ef_move():
|
||||
*/
|
||||
void
|
||||
@ -1068,7 +1307,6 @@
|
||||
void
|
||||
u3_raft_work(void);
|
||||
|
||||
|
||||
/** Disk persistence.
|
||||
**/
|
||||
/* u3_sist_boot(): restore or create pier from disk.
|
||||
@ -1139,6 +1377,7 @@
|
||||
void
|
||||
u3_sist_rand(c3_w* rad_w);
|
||||
|
||||
|
||||
/** New timer system.
|
||||
**/
|
||||
/* u3_behn_io_init(): initialize time timer.
|
||||
@ -1179,3 +1418,83 @@
|
||||
*/
|
||||
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_work(): send event; real pier pointer.
|
||||
*/
|
||||
void
|
||||
u3_pier_work(u3_pier* pir_u, u3_noun pax, u3_noun fav);
|
||||
|
||||
/* u3_pier_stub(): get the One Pier for unreconstructed code.
|
||||
*/
|
||||
u3_pier*
|
||||
u3_pier_stub(void);
|
||||
|
||||
/* u3_pier_plan(): submit event; fake pier
|
||||
*/
|
||||
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
|
||||
|
||||
/* u3_pier_tank(): dump single tank.
|
||||
*/
|
||||
void
|
||||
u3_pier_tank(c3_l tab_l, u3_noun tac);
|
||||
|
||||
/* u3_pier_punt(): dump tank list.
|
||||
*/
|
||||
void
|
||||
u3_pier_punt(c3_l tab_l, u3_noun tac);
|
||||
|
||||
/* u3_pier_sway(): print trace.
|
||||
*/
|
||||
void
|
||||
u3_pier_sway(c3_l tab_l, u3_noun tax);
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "all.h"
|
||||
|
||||
extern void
|
||||
u3_lo_tank(c3_l tab_l, u3_noun tac);
|
||||
u3_pier_tank(c3_l tab_l, u3_noun tac);
|
||||
|
||||
|
||||
// duck: create a duck core for mean.
|
||||
@ -67,7 +67,7 @@
|
||||
sprintf(ugh_c, "%s: %s: 0x%8x:",
|
||||
paz_c, pfix_c, u3r_mug(typ));
|
||||
|
||||
u3_lo_tank(0, u3n_kick_on(u3qfu_dunq(van, ugh_c, typ)));
|
||||
u3_pier_tank(0, u3n_kick_on(u3qfu_dunq(van, ugh_c, typ)));
|
||||
}
|
||||
|
||||
// shew: create a show core for mean
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
126
noun/manage.c
126
noun/manage.c
@ -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
|
||||
@ -1549,10 +1593,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.
|
||||
*/
|
||||
@ -1568,7 +1612,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.
|
||||
*/
|
||||
@ -1587,10 +1631,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;
|
||||
}
|
||||
|
@ -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
|
||||
|
16
noun/trace.c
16
noun/trace.c
@ -36,7 +36,7 @@ u3t_drop(void)
|
||||
}
|
||||
|
||||
extern void
|
||||
u3_lo_tank(c3_l tab_l, u3_noun tac);
|
||||
u3_pier_tank(c3_l tab_l, u3_noun tac);
|
||||
|
||||
#ifdef GHETTO
|
||||
/* _t_ghetto(): ghetto timelapse.
|
||||
@ -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,11 +90,11 @@ 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)));
|
||||
u3_pier_tank(0, u3k(u3t(hod)));
|
||||
}
|
||||
u3z(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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
75
vere/ames.c
75
vere/ames.c
@ -46,9 +46,9 @@ _ames_free(void* ptr_v)
|
||||
/* _ames_czar(): quasi-static route to emperor.
|
||||
*/
|
||||
static c3_w
|
||||
_ames_czar(c3_y imp_y, c3_s* por_s)
|
||||
_ames_czar(u3_pier* pir_u, c3_y imp_y, c3_s* por_s)
|
||||
{
|
||||
u3_ames* sam_u = &u3_Host.sam_u;
|
||||
u3_ames* sam_u = pir_u->sam_u;
|
||||
|
||||
if ( c3y == u3_Host.ops_u.loh ) {
|
||||
*por_s = 31337 + imp_y;
|
||||
@ -183,19 +183,23 @@ _ames_send_cb(uv_udp_send_t* req_u, c3_i sas_i)
|
||||
}
|
||||
|
||||
void
|
||||
u3_ames_ef_bake(void)
|
||||
u3_ames_ef_bake(u3_pier* pir_u)
|
||||
{
|
||||
u3_noun pax = u3nq(u3_blip, c3__newt, u3k(u3A->sen), u3_nul);
|
||||
|
||||
u3v_plan(pax, u3nc(c3__barn, u3_nul));
|
||||
u3_pier_work(pir_u, pax, u3nc(c3__barn, u3_nul));
|
||||
|
||||
u3_pier_work(pir_u,
|
||||
u3nt(u3_blip, c3__ames, u3_nul),
|
||||
u3nc(c3__kick, u3k(u3A->now)));
|
||||
}
|
||||
|
||||
/* u3_ames_ef_send(): send packet to network (v4).
|
||||
*/
|
||||
void
|
||||
u3_ames_ef_send(u3_noun lan, u3_noun pac)
|
||||
u3_ames_ef_send(u3_pier* pir_u, u3_noun lan, u3_noun pac)
|
||||
{
|
||||
u3_ames* sam_u = &u3_Host.sam_u;
|
||||
u3_ames* sam_u = pir_u->sam_u;
|
||||
c3_s por_s;
|
||||
c3_w pip_w;
|
||||
|
||||
@ -212,7 +216,7 @@ u3_ames_ef_send(u3_noun lan, u3_noun pac)
|
||||
|
||||
if ( 0 == pip_w ) {
|
||||
pip_w = 0x7f000001;
|
||||
por_s = u3_Host.sam_u.por_s;
|
||||
por_s = pir_u->sam_u->por_s;
|
||||
}
|
||||
{
|
||||
struct sockaddr_in add_u;
|
||||
@ -220,7 +224,7 @@ u3_ames_ef_send(u3_noun lan, u3_noun pac)
|
||||
if ( (0 == (pip_w >> 16)) && (1 == (pip_w >> 8)) ) {
|
||||
c3_y imp_y = (pip_w & 0xff);
|
||||
|
||||
pip_w = _ames_czar(imp_y, &por_s);
|
||||
pip_w = _ames_czar(pir_u, imp_y, &por_s);
|
||||
}
|
||||
|
||||
if ( 0 != pip_w ) {
|
||||
@ -238,7 +242,7 @@ u3_ames_ef_send(u3_noun lan, u3_noun pac)
|
||||
if ( 0 != (ret = uv_udp_send(&ruq_u->snd_u,
|
||||
&sam_u->wax_u,
|
||||
&buf_u, 1,
|
||||
(const struct sockaddr*) & add_u, // IS THIS RIGHT ?!?!?
|
||||
(const struct sockaddr*) &add_u,
|
||||
_ames_send_cb)) ) {
|
||||
uL(fprintf(uH, "ames: send: %s\n", uv_strerror(ret)));
|
||||
}
|
||||
@ -252,18 +256,18 @@ u3_ames_ef_send(u3_noun lan, u3_noun pac)
|
||||
/* _ames_time_cb(): timer callback.
|
||||
*/
|
||||
static void
|
||||
_ames_time_cb(uv_timer_t* tim_uo)
|
||||
_ames_time_cb(uv_timer_t* tim_u)
|
||||
{
|
||||
u3_ames* sam_u = &u3_Host.sam_u;
|
||||
u3_lo_open();
|
||||
u3_pier* pir_u = tim_u->data;
|
||||
u3_ames* sam_u = pir_u->sam_u;
|
||||
|
||||
sam_u->law_w = time(0);
|
||||
{
|
||||
u3v_plan
|
||||
(u3nt(u3_blip, c3__ames, u3_nul),
|
||||
u3_pier_work
|
||||
(pir_u,
|
||||
u3nt(u3_blip, c3__ames, u3_nul),
|
||||
u3nc(c3__wake, u3_nul));
|
||||
}
|
||||
u3_lo_shut(c3n);
|
||||
}
|
||||
|
||||
/* _ames_recv_cb(): receive callback.
|
||||
@ -275,13 +279,14 @@ _ames_recv_cb(uv_udp_t* wax_u,
|
||||
const struct sockaddr* adr_u,
|
||||
unsigned flg_i)
|
||||
{
|
||||
u3_pier* pir_u = wax_u->data;
|
||||
|
||||
// uL(fprintf(uH, "ames: rx %p\r\n", buf_u.base));
|
||||
|
||||
if ( 0 == nrd_i ) {
|
||||
_ames_free(buf_u->base);
|
||||
}
|
||||
else {
|
||||
u3_lo_open();
|
||||
{
|
||||
u3_noun msg = u3i_bytes((c3_w)nrd_i, (c3_y*)buf_u->base);
|
||||
|
||||
@ -293,25 +298,25 @@ _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
|
||||
(u3nt(u3_blip, c3__ames, u3_nul),
|
||||
u3_pier_work
|
||||
(pir_u,
|
||||
u3nt(u3_blip, c3__ames, u3_nul),
|
||||
u3nt(c3__hear,
|
||||
u3nq(c3__if, u3k(u3A->now), por_s, u3i_words(1, &pip_w)),
|
||||
msg));
|
||||
#endif
|
||||
}
|
||||
_ames_free(buf_u->base);
|
||||
u3_lo_shut(c3y);
|
||||
}
|
||||
}
|
||||
|
||||
/* u3_ames_io_init(): initialize ames I/O.
|
||||
*/
|
||||
void
|
||||
u3_ames_io_init()
|
||||
u3_ames_io_init(u3_pier* pir_u)
|
||||
{
|
||||
u3_ames* sam_u = &u3_Host.sam_u;
|
||||
c3_s por_s;
|
||||
u3_ames* sam_u = pir_u->sam_u;
|
||||
c3_s por_s;
|
||||
|
||||
por_s = u3_Host.ops_u.por_s;
|
||||
if ( 0 != u3_Host.ops_u.imp_c ) {
|
||||
@ -325,16 +330,17 @@ u3_ames_io_init()
|
||||
}
|
||||
num_y = u3r_byte(0, u3t(num));
|
||||
|
||||
_ames_czar(num_y, &por_s);
|
||||
_ames_czar(pir_u, num_y, &por_s);
|
||||
uL(fprintf(uH, "ames: czar: %s on %d\n", u3_Host.ops_u.imp_c, por_s));
|
||||
u3z(num);
|
||||
}
|
||||
|
||||
int ret;
|
||||
if ( 0 != (ret = uv_udp_init(u3L, &u3_Host.sam_u.wax_u)) ) {
|
||||
if ( 0 != (ret = uv_udp_init(u3L, &(pir_u->sam_u->wax_u))) ) {
|
||||
uL(fprintf(uH, "ames: init: %s\n", uv_strerror(ret)));
|
||||
c3_assert(0);
|
||||
}
|
||||
sam_u->wax_u.data = pir_u;
|
||||
|
||||
// Bind and stuff.
|
||||
{
|
||||
@ -366,26 +372,35 @@ u3_ames_io_init()
|
||||
// Timer too.
|
||||
{
|
||||
uv_timer_init(u3L, &sam_u->tim_u);
|
||||
|
||||
sam_u->tim_u.data = pir_u;
|
||||
}
|
||||
}
|
||||
|
||||
/* u3_ames_io_talk(): start receiving ames traffic.
|
||||
*/
|
||||
void
|
||||
u3_ames_io_talk()
|
||||
u3_ames_io_talk(u3_pier* pir_u)
|
||||
{
|
||||
u3_ames* sam_u = &u3_Host.sam_u;
|
||||
u3_ames* sam_u = pir_u->sam_u;
|
||||
|
||||
uL(fprintf(uH, "ames: on localhost, UDP %d.\n", sam_u->por_s));
|
||||
uv_udp_recv_start(&sam_u->wax_u, _ames_alloc, _ames_recv_cb);
|
||||
}
|
||||
|
||||
/* u3_ames_io_bake(): send initial events.
|
||||
*/
|
||||
void
|
||||
u3_ames_io_bake(u3_pier* pir_u)
|
||||
{
|
||||
}
|
||||
|
||||
/* u3_ames_io_exit(): terminate ames I/O.
|
||||
*/
|
||||
void
|
||||
u3_ames_io_exit()
|
||||
u3_ames_io_exit(u3_pier* pir_u)
|
||||
{
|
||||
u3_ames* sam_u = &u3_Host.sam_u;
|
||||
u3_ames* sam_u = pir_u->sam_u;
|
||||
|
||||
uv_close(&sam_u->had_u, 0);
|
||||
}
|
||||
@ -393,9 +408,9 @@ u3_ames_io_exit()
|
||||
/* u3_ames_io_poll(): update ames IO state.
|
||||
*/
|
||||
void
|
||||
u3_ames_io_poll()
|
||||
u3_ames_io_poll(u3_pier* pir_u)
|
||||
{
|
||||
u3_ames* sam_u = &u3_Host.sam_u;
|
||||
u3_ames* sam_u = pir_u->sam_u;
|
||||
u3_noun wen = u3v_keep(u3nt(u3_blip, c3__ames, u3_nul));
|
||||
|
||||
if ( (u3_nul != wen) &&
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -49,13 +49,11 @@ _behn_time_cb(uv_timer_t* tim_u)
|
||||
teh_u->run_w++;
|
||||
}
|
||||
|
||||
u3_lo_open();
|
||||
{
|
||||
u3v_plan
|
||||
u3_pier_plan
|
||||
(u3nt(u3_blip, c3__behn, u3_nul),
|
||||
u3nc(c3__wake, u3_nul));
|
||||
}
|
||||
u3_lo_shut(c3n);
|
||||
}
|
||||
|
||||
/* u3_behn_io_poll(): update behn IO state.
|
||||
|
11
vere/cttp.c
11
vere/cttp.c
@ -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.
|
||||
@ -953,7 +953,6 @@ _cttp_ccon_kick_connect(u3_ccon* coc_u)
|
||||
static void
|
||||
_cttp_ccon_kick_write_cb(uv_write_t* wri_u, c3_i sas_i)
|
||||
{
|
||||
u3_lo_open();
|
||||
{
|
||||
_u3_write_t* ruq_u = (void *)wri_u;
|
||||
|
||||
@ -963,7 +962,6 @@ _cttp_ccon_kick_write_cb(uv_write_t* wri_u, c3_i sas_i)
|
||||
free(ruq_u->buf_y);
|
||||
free(ruq_u);
|
||||
}
|
||||
u3_lo_shut(c3n);
|
||||
}
|
||||
|
||||
/* _cttp_ccon_kick_write_cryp()
|
||||
@ -1192,7 +1190,6 @@ _cttp_ccon_kick_read_cryp_cb(uv_stream_t* tcp_u,
|
||||
{
|
||||
u3_ccon *coc_u = _cttp_ccon_wax((uv_tcp_t*)tcp_u);
|
||||
|
||||
u3_lo_open();
|
||||
{
|
||||
if ( siz_w == UV_EOF ) {
|
||||
// _cttp_ccon_fail(coc_u, c3n); // replaced with uv_close() 2016-06-07
|
||||
@ -1217,7 +1214,6 @@ _cttp_ccon_kick_read_cryp_cb(uv_stream_t* tcp_u,
|
||||
free(buf_u->base);
|
||||
}
|
||||
}
|
||||
u3_lo_shut(c3y);
|
||||
}
|
||||
|
||||
/* _cttp_ccon_read_clyr_cb()
|
||||
@ -1240,7 +1236,6 @@ _cttp_ccon_kick_read_clyr_cb(uv_stream_t* tcp_u,
|
||||
{
|
||||
u3_ccon *coc_u = _cttp_ccon_wax((uv_tcp_t*)tcp_u);
|
||||
|
||||
u3_lo_open();
|
||||
{
|
||||
if ( siz_w == UV_EOF ) {
|
||||
// _cttp_ccon_fail(coc_u, c3n); // replaced with uv_close() 2016-06-07
|
||||
@ -1256,7 +1251,6 @@ _cttp_ccon_kick_read_clyr_cb(uv_stream_t* tcp_u,
|
||||
free(buf_u->base);
|
||||
}
|
||||
}
|
||||
u3_lo_shut(c3y);
|
||||
}
|
||||
|
||||
/* _cttp_ccon_kick_read_clyr(): start reading on insecure socket.
|
||||
@ -1638,6 +1632,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 +1671,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
629
vere/foil.c
Normal 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
694
vere/fuse.c
Normal 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));
|
||||
|
||||
}
|
@ -584,7 +584,6 @@ _http_conn_read_cb(uv_stream_t* tcp_u,
|
||||
{
|
||||
u3_hcon* hon_u = (u3_hcon*)(void*) tcp_u;
|
||||
|
||||
u3_lo_open();
|
||||
{
|
||||
if ( siz_w == UV_EOF ) {
|
||||
_http_conn_dead(hon_u);
|
||||
@ -606,7 +605,6 @@ _http_conn_read_cb(uv_stream_t* tcp_u,
|
||||
free(buf_u->base);
|
||||
}
|
||||
}
|
||||
u3_lo_shut(c3y);
|
||||
}
|
||||
|
||||
/* _http_conn_new(): create http connection.
|
||||
@ -893,7 +891,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)),
|
||||
@ -910,7 +908,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.
|
||||
@ -1001,7 +999,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
38920
vere/ivory.c
Normal file
File diff suppressed because it is too large
Load Diff
845
vere/loop.c
845
vere/loop.c
@ -1,845 +0,0 @@
|
||||
/* v/loop.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 <curses.h>
|
||||
#include <termios.h>
|
||||
#include <term.h>
|
||||
|
||||
#include "all.h"
|
||||
#include "vere/vere.h"
|
||||
|
||||
#if 0
|
||||
static jmp_buf Signal_buf;
|
||||
#ifndef SIGSTKSZ
|
||||
# define SIGSTKSZ 16384
|
||||
#endif
|
||||
static uint8_t Sigstk[SIGSTKSZ];
|
||||
|
||||
uint8_t u3_Critical;
|
||||
|
||||
typedef enum {
|
||||
sig_none,
|
||||
sig_overflow,
|
||||
sig_interrupt,
|
||||
sig_terminate,
|
||||
sig_memory,
|
||||
sig_assert,
|
||||
sig_timer
|
||||
} u3_kill;
|
||||
|
||||
volatile u3_kill Sigcause; // reasons for exception
|
||||
|
||||
static void _lo_cont(void *arg1, void *arg2, void *arg3)
|
||||
{
|
||||
(void)(arg1);
|
||||
(void)(arg2);
|
||||
(void)(arg3);
|
||||
siglongjmp(Signal_buf, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
_lo_signal_handle_over(int emergency, stackoverflow_context_t scp)
|
||||
{
|
||||
if ( u3_Critical ) {
|
||||
// Careful not to grow the stack during critical sections.
|
||||
//
|
||||
write(2, "stack disaster\n", strlen("stack disaster" + 2));
|
||||
abort();
|
||||
}
|
||||
|
||||
#if 0
|
||||
if ( 1 == emergency ) {
|
||||
write(2, "stack emergency\n", strlen("stack emergency" + 2));
|
||||
abort();
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
Sigcause = sig_overflow;
|
||||
sigsegv_leave_handler(_lo_cont, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_lo_signal_handle_term(int x)
|
||||
{
|
||||
if ( !u3_Critical ) {
|
||||
Sigcause = sig_terminate;
|
||||
u3_Host.liv = c3n;
|
||||
longjmp(Signal_buf, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_lo_signal_handle_intr(int x)
|
||||
{
|
||||
if ( !u3_Critical ) {
|
||||
Sigcause = sig_interrupt;
|
||||
longjmp(Signal_buf, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_lo_signal_handle_alrm(int x)
|
||||
{
|
||||
if ( !u3_Critical ) {
|
||||
Sigcause = sig_timer;
|
||||
longjmp(Signal_buf, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* _lo_signal_done():
|
||||
*/
|
||||
static void
|
||||
_lo_signal_done()
|
||||
{
|
||||
// signal(SIGINT, SIG_IGN);
|
||||
signal(SIGTERM, SIG_IGN);
|
||||
signal(SIGVTALRM, SIG_IGN);
|
||||
|
||||
stackoverflow_deinstall_handler();
|
||||
{
|
||||
struct itimerval itm_u;
|
||||
|
||||
timerclear(&itm_u.it_interval);
|
||||
timerclear(&itm_u.it_value);
|
||||
|
||||
setitimer(ITIMER_VIRTUAL, &itm_u, 0);
|
||||
}
|
||||
u3_unix_ef_move();
|
||||
}
|
||||
|
||||
/* _lo_signal_deep(): start deep processing; set timer for sec_w or 0.
|
||||
*/
|
||||
static void
|
||||
_lo_signal_deep(c3_w sec_w)
|
||||
{
|
||||
u3_unix_ef_hold();
|
||||
|
||||
stackoverflow_install_handler(_lo_signal_handle_over, Sigstk, SIGSTKSZ);
|
||||
signal(SIGINT, _lo_signal_handle_intr);
|
||||
signal(SIGTERM, _lo_signal_handle_term);
|
||||
|
||||
{
|
||||
struct itimerval itm_u;
|
||||
|
||||
timerclear(&itm_u.it_interval);
|
||||
itm_u.it_value.tv_sec = sec_w;
|
||||
itm_u.it_value.tv_usec = 0;
|
||||
|
||||
setitimer(ITIMER_VIRTUAL, &itm_u, 0);
|
||||
}
|
||||
signal(SIGVTALRM, _lo_signal_handle_alrm);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* u3_loop_signal_memory(): end computation for out-of-memory.
|
||||
*/
|
||||
void
|
||||
u3_loop_signal_memory()
|
||||
{
|
||||
fprintf(stderr, "\r\nout of memory\r\n");
|
||||
c3_assert(0);
|
||||
|
||||
#if 0
|
||||
Sigcause = sig_memory;
|
||||
longjmp(Signal_buf, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* _lo_init(): initialize I/O across the process.
|
||||
*/
|
||||
static void
|
||||
_lo_init()
|
||||
{
|
||||
c3_l cod_l;
|
||||
|
||||
cod_l = u3a_lush(c3__unix);
|
||||
u3_unix_io_init();
|
||||
u3a_lop(cod_l);
|
||||
|
||||
cod_l = u3a_lush(c3__ames);
|
||||
u3_ames_io_init();
|
||||
u3a_lop(cod_l);
|
||||
|
||||
cod_l = u3a_lush(c3__term);
|
||||
u3_term_io_init();
|
||||
u3a_lop(cod_l);
|
||||
|
||||
cod_l = u3a_lush(c3__http);
|
||||
u3_http_io_init();
|
||||
u3a_lop(cod_l);
|
||||
|
||||
cod_l = u3a_lush(c3__cttp);
|
||||
u3_cttp_io_init();
|
||||
u3a_lop(cod_l);
|
||||
|
||||
cod_l = u3a_lush(c3__save);
|
||||
u3_save_io_init();
|
||||
u3a_lop(cod_l);
|
||||
|
||||
cod_l = u3a_lush(c3__behn);
|
||||
u3_behn_io_init();
|
||||
u3a_lop(cod_l);
|
||||
}
|
||||
|
||||
/* _lo_talk(): bring up listeners across the process.
|
||||
*/
|
||||
static void
|
||||
_lo_talk()
|
||||
{
|
||||
c3_l cod_l;
|
||||
|
||||
cod_l = u3a_lush(c3__unix);
|
||||
u3_unix_io_talk();
|
||||
u3a_lop(cod_l);
|
||||
|
||||
cod_l = u3a_lush(c3__ames);
|
||||
u3_ames_io_talk();
|
||||
u3a_lop(cod_l);
|
||||
|
||||
cod_l = u3a_lush(c3__http);
|
||||
u3_http_io_talk();
|
||||
u3a_lop(cod_l);
|
||||
|
||||
cod_l = u3a_lush(c3__term);
|
||||
u3_term_io_talk();
|
||||
u3a_lop(cod_l);
|
||||
}
|
||||
|
||||
/* u3_lo_exit(): terminate I/O across the process.
|
||||
*/
|
||||
void
|
||||
u3_lo_exit(void)
|
||||
{
|
||||
c3_l cod_l;
|
||||
|
||||
cod_l = u3a_lush(c3__unix);
|
||||
u3_unix_io_exit();
|
||||
u3a_lop(cod_l);
|
||||
|
||||
cod_l = u3a_lush(c3__ames);
|
||||
u3_ames_io_exit();
|
||||
u3a_lop(cod_l);
|
||||
|
||||
cod_l = u3a_lush(c3__term);
|
||||
u3_term_io_exit();
|
||||
u3a_lop(cod_l);
|
||||
|
||||
cod_l = u3a_lush(c3__http);
|
||||
u3_http_io_exit();
|
||||
u3a_lop(cod_l);
|
||||
|
||||
cod_l = u3a_lush(c3__cttp);
|
||||
u3_cttp_io_exit();
|
||||
u3a_lop(cod_l);
|
||||
|
||||
cod_l = u3a_lush(c3__save);
|
||||
u3_save_io_exit();
|
||||
u3a_lop(cod_l);
|
||||
|
||||
cod_l = u3a_lush(c3__behn);
|
||||
u3_behn_io_exit();
|
||||
u3a_lop(cod_l);
|
||||
}
|
||||
|
||||
/* _lo_poll(): reset event flags across the process.
|
||||
*/
|
||||
static void
|
||||
_lo_poll(void)
|
||||
{
|
||||
c3_l cod_l;
|
||||
|
||||
cod_l = u3a_lush(c3__ames);
|
||||
u3_ames_io_poll();
|
||||
u3a_lop(cod_l);
|
||||
|
||||
cod_l = u3a_lush(c3__http);
|
||||
u3_http_io_poll();
|
||||
u3a_lop(cod_l);
|
||||
|
||||
cod_l = u3a_lush(c3__term);
|
||||
u3_term_io_poll();
|
||||
u3a_lop(cod_l);
|
||||
|
||||
cod_l = u3a_lush(c3__save);
|
||||
u3_save_io_poll();
|
||||
u3a_lop(cod_l);
|
||||
|
||||
cod_l = u3a_lush(c3__unix);
|
||||
u3_unix_io_poll();
|
||||
u3a_lop(cod_l);
|
||||
|
||||
cod_l = u3a_lush(c3__behn);
|
||||
u3_behn_io_poll();
|
||||
u3a_lop(cod_l);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* _lo_how(): print how.
|
||||
*/
|
||||
static const c3_c*
|
||||
_lo_how(u3_noun how)
|
||||
{
|
||||
switch ( how ) {
|
||||
default: c3_assert(0); break;
|
||||
|
||||
case c3__ames: return "ames";
|
||||
case c3__behn: return "behn";
|
||||
case c3__term: return "cons";
|
||||
case c3__htcn: return "http-conn";
|
||||
case c3__htls: return "http-lisn";
|
||||
case c3__save: return "save";
|
||||
case c3__unix: return "unix";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* u3_lo_bail(): clean up all event state.
|
||||
*/
|
||||
void
|
||||
u3_lo_bail(void)
|
||||
{
|
||||
fflush(stdout);
|
||||
u3_lo_exit();
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* _lo_tape(): dump a tape, old style. Don't do this.
|
||||
*/
|
||||
static void
|
||||
_lo_tape(FILE* fil_u, u3_noun tep)
|
||||
{
|
||||
u3_noun tap = tep;
|
||||
|
||||
while ( c3y == u3du(tap) ) {
|
||||
c3_c car_c;
|
||||
|
||||
if ( u3h(tap) >= 127 ) {
|
||||
car_c = '?';
|
||||
} else car_c = u3h(tap);
|
||||
|
||||
putc(car_c, fil_u);
|
||||
tap = u3t(tap);
|
||||
}
|
||||
u3z(tep);
|
||||
}
|
||||
|
||||
/* _lo_wall(): dump a wall, old style. Don't do this.
|
||||
*/
|
||||
static void
|
||||
_lo_wall(u3_noun wol)
|
||||
{
|
||||
FILE* fil_u = u3_term_io_hija();
|
||||
u3_noun wal = wol;
|
||||
|
||||
while ( u3_nul != wal ) {
|
||||
_lo_tape(fil_u, u3k(u3h(wal)));
|
||||
|
||||
putc(13, fil_u);
|
||||
putc(10, fil_u);
|
||||
|
||||
wal = u3t(wal);
|
||||
}
|
||||
u3_term_io_loja(0);
|
||||
u3z(wol);
|
||||
}
|
||||
|
||||
/* u3_lo_tank(): dump single tank.
|
||||
*/
|
||||
void
|
||||
u3_lo_tank(c3_l tab_l, u3_noun tac)
|
||||
{
|
||||
u3_lo_punt(tab_l, u3nc(tac, u3_nul));
|
||||
}
|
||||
|
||||
/* u3_lo_punt(): dump tank list.
|
||||
*/
|
||||
void
|
||||
u3_lo_punt(c3_l tab_l, u3_noun tac)
|
||||
{
|
||||
u3_noun blu = u3_term_get_blew(0);
|
||||
c3_l col_l = u3h(blu);
|
||||
u3_noun cat = tac;
|
||||
|
||||
// We are calling nock here, but hopefully need no protection.
|
||||
//
|
||||
while ( c3y == u3r_du(cat) ) {
|
||||
if ( 0 == u3A->roc ) {
|
||||
u3_noun act = u3h(cat);
|
||||
|
||||
if ( c3__leaf == u3h(act) ) {
|
||||
FILE* fil_u = u3_term_io_hija();
|
||||
|
||||
_lo_tape(fil_u, u3k(u3t(act)));
|
||||
putc(13, fil_u);
|
||||
putc(10, fil_u);
|
||||
|
||||
u3_term_io_loja(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
u3_noun wol = u3dc("wash", u3nc(tab_l, col_l), u3k(u3h(cat)));
|
||||
|
||||
_lo_wall(wol);
|
||||
}
|
||||
cat = u3t(cat);
|
||||
}
|
||||
u3z(tac);
|
||||
u3z(blu);
|
||||
}
|
||||
|
||||
/* u3_lo_sway(): print trace.
|
||||
*/
|
||||
void
|
||||
u3_lo_sway(c3_l tab_l, u3_noun tax)
|
||||
{
|
||||
u3_noun mok = u3dc("mook", 2, tax);
|
||||
|
||||
u3_lo_punt(tab_l, u3k(u3t(mok)));
|
||||
u3z(mok);
|
||||
}
|
||||
|
||||
/* _lo_time(): set time.
|
||||
*/
|
||||
static void
|
||||
_lo_time(void)
|
||||
{
|
||||
struct timeval tim_tv;
|
||||
|
||||
gettimeofday(&tim_tv, 0);
|
||||
u3v_time(u3_time_in_tv(&tim_tv));
|
||||
}
|
||||
|
||||
/* u3_lo_open(): begin callback processing.
|
||||
*/
|
||||
void
|
||||
u3_lo_open(void)
|
||||
{
|
||||
if ( u3C.wag_w & (u3o_debug_ram | u3o_check_corrupt) ) {
|
||||
//
|
||||
// Assumption: there are no noun roots outside u3A.
|
||||
//
|
||||
u3m_grab(u3_none);
|
||||
}
|
||||
#if 0
|
||||
if ( u3C.wag_w & u3o_debug_cpu ) {
|
||||
struct itimerval itm_u;
|
||||
|
||||
getitimer(ITIMER_VIRTUAL, &itm_u);
|
||||
fprintf(stderr, "tv_sec %d, tv_usec %d, value %d/%d\r\n",
|
||||
itm_u.it_interval.tv_sec,
|
||||
itm_u.it_interval.tv_usec,
|
||||
itm_u.it_value.tv_sec,
|
||||
itm_u.it_interval.tv_usec);
|
||||
}
|
||||
#endif
|
||||
_lo_time();
|
||||
}
|
||||
|
||||
/* u3_lo_shut(): end callback processing.
|
||||
*/
|
||||
void
|
||||
u3_lo_shut(c3_o inn)
|
||||
{
|
||||
// u3m_grab(u3_none);
|
||||
|
||||
// process actions
|
||||
//
|
||||
u3_raft_work();
|
||||
|
||||
// u3_lo_grab("lo_shut b", u3_none);
|
||||
|
||||
// update time
|
||||
//
|
||||
_lo_time();
|
||||
|
||||
// u3_lo_grab("lo_shut c", u3_none);
|
||||
|
||||
// for input operations, poll fs (XX not permanent)
|
||||
// XX remove raty_lead guard
|
||||
//
|
||||
if ( c3y == inn ) {
|
||||
u3_unix_ef_look(c3n);
|
||||
u3_raft_work();
|
||||
_lo_time();
|
||||
}
|
||||
|
||||
// u3_lo_grab("lo_shut d", u3_none);
|
||||
|
||||
// clean shutdown
|
||||
//
|
||||
if ( c3n == u3_Host.liv ) {
|
||||
// direct save and die
|
||||
//
|
||||
// u3_lo_grab("lo_exit", u3_none);
|
||||
// u3_loom_save(u3A->ent_d);
|
||||
// u3_loom_exit();
|
||||
u3t_damp();
|
||||
u3_lo_exit();
|
||||
|
||||
// save a checkpoint before exiting
|
||||
u3e_save();
|
||||
exit(u3_Host.xit_i);
|
||||
}
|
||||
else {
|
||||
// poll arvo to generate any event binding changes
|
||||
//
|
||||
_lo_poll();
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// _lo_bench_noop(): benchmark no-op events.
|
||||
//
|
||||
static void
|
||||
_lo_bench_noop(c3_w num_w)
|
||||
{
|
||||
c3_w i_w;
|
||||
|
||||
for ( i_w = 0; i_w < num_w; i_w++ ) {
|
||||
u3_reck_plan(u3A, u3nq(u3_blip, c3__term, 1, u3_nul),
|
||||
u3nc(c3__noop, u3_nul));
|
||||
}
|
||||
|
||||
u3_raft_work(u3A);
|
||||
}
|
||||
|
||||
// _lo_bench_scot_p(): benchmark prettyprint.
|
||||
//
|
||||
static void
|
||||
_lo_bench_scot_p(c3_w num_w)
|
||||
{
|
||||
c3_w i_w;
|
||||
|
||||
for ( i_w = 0; i_w < num_w; i_w++ ) {
|
||||
u3_noun soc = u3dc("scot", 'p', u3k(u3A->now));
|
||||
|
||||
u3z(soc);
|
||||
}
|
||||
}
|
||||
|
||||
// _lo_bench_slay_p(): benchmark prettyprint.
|
||||
//
|
||||
static void
|
||||
_lo_bench_slay_p(c3_w num_w)
|
||||
{
|
||||
c3_w i_w;
|
||||
|
||||
for ( i_w = 0; i_w < num_w; i_w++ ) {
|
||||
u3_noun soc = u3dc("scot", 'p', u3k(u3A->now));
|
||||
u3_noun dub = u3do("slay", soc);
|
||||
|
||||
u3z(dub);
|
||||
}
|
||||
}
|
||||
|
||||
// _lo_bench_scot_da(): benchmark prettyprint.
|
||||
//
|
||||
static void
|
||||
_lo_bench_scot_da(c3_w num_w)
|
||||
{
|
||||
c3_w i_w;
|
||||
|
||||
for ( i_w = 0; i_w < num_w; i_w++ ) {
|
||||
u3_noun soc = u3dc("scot", c3__da, u3k(u3A->now));
|
||||
|
||||
u3z(soc);
|
||||
}
|
||||
}
|
||||
|
||||
// _lo_bench_dec(): benchmark decrement.
|
||||
//
|
||||
static void
|
||||
_lo_bench_dec(c3_w num_w)
|
||||
{
|
||||
c3_w i_w;
|
||||
|
||||
for ( i_w = 0; i_w < num_w; i_w++ ) {
|
||||
u3_noun soc = u3do("dec", u3k(u3A->now));
|
||||
|
||||
u3z(soc);
|
||||
}
|
||||
}
|
||||
|
||||
// _lo_bench_scot_ud(): benchmark prettyprint.
|
||||
//
|
||||
static void
|
||||
_lo_bench_scot_ud(c3_w num_w)
|
||||
{
|
||||
c3_w i_w;
|
||||
|
||||
for ( i_w = 0; i_w < num_w; i_w++ ) {
|
||||
u3_noun soc = u3dc("scot", c3__ud, u3k(u3A->now));
|
||||
|
||||
u3z(soc);
|
||||
}
|
||||
}
|
||||
|
||||
// _lo_bench(): lo-tech profiling.
|
||||
//
|
||||
static void
|
||||
_lo_bench(const c3_c* lab_c, void (*fun)(c3_w), c3_w num_w)
|
||||
{
|
||||
u3_noun old, new;
|
||||
|
||||
uL(fprintf(uH, "bench: %s: start...\n", lab_c));
|
||||
u3_reck_time(u3A);
|
||||
old = u3k(u3A->now);
|
||||
|
||||
fun(num_w);
|
||||
|
||||
u3_reck_time(u3A);
|
||||
new = u3k(u3A->now);
|
||||
{
|
||||
c3_w tms_w = (c3_w)u3_time_gap_ms(old, new);
|
||||
|
||||
if ( tms_w > (10 * num_w) ) {
|
||||
uL(fprintf(uH, "bench: %s*%d: %d ms, %d ms each.\n",
|
||||
lab_c, num_w, tms_w, (tms_w / num_w)));
|
||||
}
|
||||
else {
|
||||
uL(fprintf(uH, "bench: %s*%d: %d ms, %d us each.\n",
|
||||
lab_c, num_w, tms_w, ((tms_w * 1000) / num_w)));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* u3_lo_show(): generic noun print.
|
||||
*/
|
||||
void
|
||||
u3_lo_show(c3_c* cap_c, u3_noun nun)
|
||||
{
|
||||
u3_noun pav = u3dc("pave", c3__noun, nun);
|
||||
c3_c* txt_c = (c3_c*)u3r_tape(pav);
|
||||
|
||||
fprintf(stderr, "%s: %s\r\n", cap_c, txt_c);
|
||||
u3z(pav);
|
||||
free(txt_c);
|
||||
}
|
||||
|
||||
static void
|
||||
_lo_slow()
|
||||
{
|
||||
#if 0
|
||||
_lo_bench("scot %p", _lo_bench_scot_p, 256);
|
||||
_lo_bench("scot %da", _lo_bench_scot_da, 256);
|
||||
_lo_bench("scot %ud", _lo_bench_scot_ud, 256);
|
||||
_lo_bench("slay %p", _lo_bench_slay_p, 256);
|
||||
_lo_bench("noop", _lo_bench_noop, 256);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* u3_lo_loop(): begin main event loop.
|
||||
*/
|
||||
void
|
||||
u3_lo_loop()
|
||||
{
|
||||
uv_loop_t* lup_u = uv_default_loop();
|
||||
|
||||
u3_Host.lup_u = lup_u;
|
||||
|
||||
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.tex) ) {
|
||||
u3t_boff();
|
||||
u3t_damp();
|
||||
u3_lo_exit();
|
||||
|
||||
fprintf(stderr, "dry run: exit\r\n");
|
||||
exit(0);
|
||||
}
|
||||
else {
|
||||
if ( c3n == u3_Host.ops_u.bat ) {
|
||||
uv_run(u3L, UV_RUN_DEFAULT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* u3_lo_lead(): actions on promotion to leader.
|
||||
*/
|
||||
void
|
||||
u3_lo_lead(void)
|
||||
{
|
||||
// Further server configuration.
|
||||
//
|
||||
{
|
||||
u3_http_ef_bake();
|
||||
}
|
||||
|
||||
_lo_talk();
|
||||
{
|
||||
u3_unix_ef_look(c3n);
|
||||
u3v_plan(u3nt(u3_blip, c3__ames, u3_nul),
|
||||
u3nc(c3__kick, u3k(u3A->now)));
|
||||
}
|
||||
_lo_poll();
|
||||
|
||||
#if 0
|
||||
u3_loom_save(u3A->ent_d);
|
||||
|
||||
u3_Host.sav_u.ent_d = rec_u->ent_d;
|
||||
#endif
|
||||
|
||||
if ( c3y == u3_Host.ops_u.nuu ) {
|
||||
if ( u3_Host.ops_u.who_c ) {
|
||||
u3_term_ef_ticket(u3_Host.ops_u.who_c, u3_Host.ops_u.tic_c);
|
||||
}
|
||||
u3_term_ef_boil(1);
|
||||
}
|
||||
|
||||
if ( c3y == u3_Host.ops_u.veb ) {
|
||||
u3_term_ef_verb();
|
||||
}
|
||||
|
||||
#if 1
|
||||
_lo_slow();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* _lo_mark_reck(): mark a reck.
|
||||
*/
|
||||
static c3_w
|
||||
_lo_mark_reck(u3_reck* rec_u)
|
||||
{
|
||||
c3_w siz_w = 0;
|
||||
c3_w egg_w;
|
||||
|
||||
siz_w += u3m_mark_noun(rec_u->ken);
|
||||
siz_w += u3m_mark_noun(rec_u->roc);
|
||||
|
||||
siz_w += u3m_mark_noun(rec_u->yot);
|
||||
siz_w += u3m_mark_noun(rec_u->now);
|
||||
siz_w += u3m_mark_noun(rec_u->wen);
|
||||
siz_w += u3m_mark_noun(rec_u->sen);
|
||||
siz_w += u3m_mark_noun(rec_u->own);
|
||||
siz_w += u3m_mark_noun(rec_u->roe);
|
||||
siz_w += u3m_mark_noun(rec_u->key);
|
||||
|
||||
{
|
||||
u3_cart* egg_u;
|
||||
|
||||
egg_w = 0;
|
||||
for ( egg_u = rec_u->ova.egg_u; egg_u; egg_u = egg_u->nex_u ) {
|
||||
egg_w += u3m_mark_noun(egg_u->vir);
|
||||
}
|
||||
siz_w += egg_w;
|
||||
}
|
||||
#if 0
|
||||
fprintf(stderr, "ken %d, roc %d, yot %d, roe %d, egg %d\r\n",
|
||||
ken_w, roc_w, yot_w, roe_w, egg_w);
|
||||
#endif
|
||||
return siz_w;
|
||||
}
|
||||
|
||||
/* _lo_mark(): mark the whole vere system.
|
||||
*/
|
||||
static c3_w
|
||||
_lo_mark()
|
||||
{
|
||||
c3_w siz_w;
|
||||
|
||||
siz_w = u3m_mark_internal();
|
||||
siz_w += _lo_mark_reck(u3_Host.arv_u);
|
||||
|
||||
return siz_w;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* _lo_word(): print a word to the passed stream.
|
||||
*/
|
||||
static void
|
||||
_lo_word(FILE* fil_u, c3_w wod_w)
|
||||
{
|
||||
u3_noun top = c3y;
|
||||
|
||||
if ( wod_w / (1000 * 1000 * 1000) ) {
|
||||
fprintf(fil_u, "%u.", wod_w / (1000 * 1000 * 1000));
|
||||
wod_w %= (1000 * 1000 * 1000);
|
||||
top = c3n;
|
||||
}
|
||||
if ( wod_w / (1000 * 1000) ) {
|
||||
fprintf(fil_u, ((top == c3y) ? "%u." : "%03u."),
|
||||
wod_w / (1000 * 1000));
|
||||
wod_w %= (1000 * 1000);
|
||||
top = c3n;
|
||||
}
|
||||
if ( wod_w / 1000 ) {
|
||||
fprintf(fil_u, ((top == c3y) ? "%u." : "%03u."), wod_w / 1000);
|
||||
wod_w %= 1000;
|
||||
top = c3n;
|
||||
}
|
||||
fprintf(fil_u, ((top == c3y) ? "%u" : "%03u"), wod_w);
|
||||
}
|
||||
|
||||
/* u3_lo_grab(): garbage-collect the world, plus roots.
|
||||
*/
|
||||
void
|
||||
u3_lo_grab(c3_c* cap_c, u3_noun som, ...)
|
||||
{
|
||||
c3_w siz_w, lec_w;
|
||||
|
||||
siz_w = _lo_mark();
|
||||
{
|
||||
va_list vap;
|
||||
u3_noun tur;
|
||||
|
||||
va_start(vap, som);
|
||||
|
||||
if ( som != u3_none ) {
|
||||
siz_w += u3m_mark_noun(som);
|
||||
|
||||
while ( u3_none != (tur = va_arg(vap, u3_noun)) ) {
|
||||
siz_w += u3m_mark_noun(tur);
|
||||
}
|
||||
}
|
||||
va_end(vap);
|
||||
}
|
||||
lec_w = u3m_sweep(siz_w);
|
||||
|
||||
// if ( lec_w || (c3y == u3_Flag_Verbose) )
|
||||
if ( lec_w || !strcmp("init", cap_c) ) {
|
||||
FILE* fil_u = uH;
|
||||
fprintf(fil_u, "%s: gc: ", cap_c);
|
||||
if ( lec_w ) {
|
||||
_lo_word(fil_u, 4 * lec_w);
|
||||
fprintf(fil_u, " bytes shed; ");
|
||||
}
|
||||
_lo_word(fil_u, 4 * siz_w);
|
||||
uL(fprintf(fil_u, " bytes live\n"));
|
||||
|
||||
#if 0
|
||||
if ( lec_w ) {
|
||||
uL(fprintf(uH, "zero garbage tolerance!\n"));
|
||||
u3_lo_exit();
|
||||
c3_assert(0);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
u3_wire_lan(u3_Wire) = c3y;
|
||||
}
|
||||
#endif
|
66
vere/main.c
66
vere/main.c
@ -1,5 +1,4 @@
|
||||
/* v/main.c
|
||||
**
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -395,7 +394,7 @@ overflow_handler(int emergency, stackoverflow_context_t scp)
|
||||
//
|
||||
u3_lo_sway(0, u3k(u3_wire_tax(u3_Wire)));
|
||||
|
||||
u3_lo_bail(u3A);
|
||||
u3_pier_exit(u3A);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
@ -434,13 +433,27 @@ void
|
||||
_stop_exit(c3_i int_i)
|
||||
{
|
||||
fprintf(stderr, "\r\n[received keyboard stop signal, exiting]\r\n");
|
||||
u3_lo_bail();
|
||||
u3_pier_exit();
|
||||
}
|
||||
|
||||
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,21 +466,6 @@ 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 0
|
||||
if ( 0 == getuid() ) {
|
||||
chroot(u3_Host.dir_c);
|
||||
@ -546,38 +544,8 @@ 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 1
|
||||
{
|
||||
struct timeval tim_tv;
|
||||
u3_noun now;
|
||||
|
||||
gettimeofday(&tim_tv, 0);
|
||||
now = u3_time_in_tv(&tim_tv);
|
||||
|
||||
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
|
||||
u3_pier_boot(u3_Host.dir_c, u3_Host.ops_u.pil_c);
|
||||
}
|
||||
|
||||
// u3e_grab("main", u3_none);
|
||||
//
|
||||
u3_lo_loop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
335
vere/newt.c
Normal file
335
vere/newt.c
Normal 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));
|
||||
}
|
||||
}
|
1858
vere/pier.c
Normal file
1858
vere/pier.c
Normal file
File diff suppressed because it is too large
Load Diff
2076
vere/raft.c
2076
vere/raft.c
File diff suppressed because it is too large
Load Diff
42
vere/reck.c
42
vere/reck.c
@ -69,7 +69,7 @@ _reck_lily(u3_noun fot, u3_noun txt, c3_l* tid_l)
|
||||
/* _reck_kick_term(): apply terminal outputs.
|
||||
*/
|
||||
static u3_noun
|
||||
_reck_kick_term(u3_noun pox, c3_l tid_l, u3_noun fav)
|
||||
_reck_kick_term(u3_pier* pir_u, u3_noun pox, c3_l tid_l, u3_noun fav)
|
||||
{
|
||||
u3_noun p_fav;
|
||||
|
||||
@ -92,7 +92,7 @@ _reck_kick_term(u3_noun pox, c3_l tid_l, u3_noun fav)
|
||||
|
||||
case c3__logo:
|
||||
{
|
||||
u3_Host.liv = c3n;
|
||||
u3_pier_exit();
|
||||
u3_Host.xit_i = u3t(fav);
|
||||
|
||||
u3z(pox); u3z(fav); return c3y;
|
||||
@ -122,7 +122,8 @@ _reck_kick_term(u3_noun pox, c3_l tid_l, u3_noun fav)
|
||||
/* _reck_kick_http(): apply http effects.
|
||||
*/
|
||||
static u3_noun
|
||||
_reck_kick_http(u3_noun pox,
|
||||
_reck_kick_http(u3_pier* pir_u,
|
||||
u3_noun pox,
|
||||
c3_l sev_l,
|
||||
c3_l coq_l,
|
||||
c3_l seq_l,
|
||||
@ -157,7 +158,7 @@ _reck_kick_http(u3_noun pox,
|
||||
/* _reck_kick_sync(): apply sync outputs.
|
||||
*/
|
||||
static u3_noun
|
||||
_reck_kick_sync(u3_noun pox, u3_noun fav)
|
||||
_reck_kick_sync(u3_pier* pir_u, u3_noun pox, u3_noun fav)
|
||||
{
|
||||
switch ( u3h(fav) ) {
|
||||
default: break;
|
||||
@ -184,7 +185,7 @@ _reck_kick_sync(u3_noun pox, u3_noun fav)
|
||||
}
|
||||
|
||||
static u3_noun
|
||||
_reck_kick_newt(u3_noun pox, u3_noun fav)
|
||||
_reck_kick_newt(u3_pier* pir_u, u3_noun pox, u3_noun fav)
|
||||
{
|
||||
switch ( u3h(fav) ) {
|
||||
default: break;
|
||||
@ -192,7 +193,7 @@ _reck_kick_newt(u3_noun pox, u3_noun fav)
|
||||
u3_noun lan = u3k(u3h(u3t(fav)));
|
||||
u3_noun pac = u3k(u3t(u3t(fav)));
|
||||
|
||||
u3_ames_ef_send(lan, pac);
|
||||
u3_ames_ef_send(pir_u, lan, pac);
|
||||
u3z(pox); u3z(fav); return c3y;
|
||||
} break;
|
||||
}
|
||||
@ -202,7 +203,7 @@ _reck_kick_newt(u3_noun pox, u3_noun fav)
|
||||
/* _reck_kick_ames(): apply packet network outputs.
|
||||
*/
|
||||
static u3_noun
|
||||
_reck_kick_ames(u3_noun pox, u3_noun fav)
|
||||
_reck_kick_ames(u3_pier* pir_u, u3_noun pox, u3_noun fav)
|
||||
{
|
||||
u3_noun p_fav;
|
||||
|
||||
@ -222,7 +223,7 @@ _reck_kick_ames(u3_noun pox, u3_noun fav)
|
||||
/* _reck_kick_spec(): apply an effect, by path.
|
||||
*/
|
||||
static u3_noun
|
||||
_reck_kick_spec(u3_noun pox, u3_noun fav)
|
||||
_reck_kick_spec(u3_pier* pir_u, u3_noun pox, u3_noun fav)
|
||||
{
|
||||
u3_noun i_pox, t_pox;
|
||||
u3_noun p_fav;
|
||||
@ -275,17 +276,17 @@ _reck_kick_spec(u3_noun pox, u3_noun fav)
|
||||
}
|
||||
}
|
||||
}
|
||||
return _reck_kick_http(pox, sev_l, coq_l, seq_l, fav);
|
||||
return _reck_kick_http(pir_u, pox, sev_l, coq_l, seq_l, fav);
|
||||
} break;
|
||||
|
||||
case c3__clay:
|
||||
case c3__boat:
|
||||
case c3__sync: {
|
||||
return _reck_kick_sync(pox, fav);
|
||||
return _reck_kick_sync(pir_u, pox, fav);
|
||||
} break;
|
||||
|
||||
case c3__newt: {
|
||||
return _reck_kick_newt(pox, fav);
|
||||
return _reck_kick_newt(pir_u, pox, fav);
|
||||
} break;
|
||||
|
||||
case c3__ames: {
|
||||
@ -293,7 +294,7 @@ _reck_kick_spec(u3_noun pox, u3_noun fav)
|
||||
u3z(pox); u3z(fav); return c3n;
|
||||
}
|
||||
else {
|
||||
return _reck_kick_ames(pox, fav);
|
||||
return _reck_kick_ames(pir_u, pox, fav);
|
||||
}
|
||||
} break;
|
||||
|
||||
@ -317,7 +318,7 @@ _reck_kick_spec(u3_noun pox, u3_noun fav)
|
||||
uL(fprintf(uH, "term: bad tire\n"));
|
||||
u3z(pox); u3z(fav); return c3n;
|
||||
} else {
|
||||
return _reck_kick_term(pox, tid_l, fav);
|
||||
return _reck_kick_term(pir_u, pox, tid_l, fav);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
@ -329,7 +330,7 @@ _reck_kick_spec(u3_noun pox, u3_noun fav)
|
||||
/* _reck_kick_norm(): non path-specific effect handling.
|
||||
*/
|
||||
static u3_noun
|
||||
_reck_kick_norm(u3_noun pox, u3_noun fav)
|
||||
_reck_kick_norm(u3_pier* pir_u, u3_noun pox, u3_noun fav)
|
||||
{
|
||||
if ( c3n == u3du(fav) ) {
|
||||
u3z(pox); u3z(fav); return c3n;
|
||||
@ -349,7 +350,7 @@ _reck_kick_norm(u3_noun pox, u3_noun fav)
|
||||
case c3__exit:
|
||||
{
|
||||
uL(fprintf(uH, "<<<goodbye>>>\n"));
|
||||
u3_lo_bail();
|
||||
u3_pier_exit();
|
||||
|
||||
u3z(pox); u3z(fav); return c3y;
|
||||
} break;
|
||||
@ -361,10 +362,10 @@ _reck_kick_norm(u3_noun pox, u3_noun fav)
|
||||
/* u3_reck_kick(): handle effect.
|
||||
*/
|
||||
void
|
||||
u3_reck_kick(u3_noun ovo)
|
||||
u3_reck_kick(u3_pier* pir_u, u3_noun ovo)
|
||||
{
|
||||
if ( (c3n == _reck_kick_spec(u3k(u3h(ovo)), u3k(u3t(ovo)))) &&
|
||||
(c3n == _reck_kick_norm(u3k(u3h(ovo)), u3k(u3t(ovo)))) )
|
||||
if ( (c3n == _reck_kick_spec(pir_u, u3k(u3h(ovo)), u3k(u3t(ovo)))) &&
|
||||
(c3n == _reck_kick_norm(pir_u, u3k(u3h(ovo)), u3k(u3t(ovo)))) )
|
||||
{
|
||||
#if 0
|
||||
if ( (c3__warn != u3h(u3t(ovo))) &&
|
||||
@ -379,8 +380,9 @@ u3_reck_kick(u3_noun ovo)
|
||||
(c3__init == u3h(u3t(ovo))) )
|
||||
#endif
|
||||
{
|
||||
u3v_plan(u3nt(u3_blip, c3__term, u3_nul),
|
||||
u3nc(c3__flog, u3k(u3t(ovo))));
|
||||
u3_pier_work(pir_u,
|
||||
u3nt(u3_blip, c3__term, u3_nul),
|
||||
u3nc(c3__flog, u3k(u3t(ovo))));
|
||||
}
|
||||
else {
|
||||
u3_noun tox = u3do("spat", u3k(u3h(ovo)));
|
||||
|
405
vere/serf.c
Normal file
405
vere/serf.c
Normal file
@ -0,0 +1,405 @@
|
||||
/* 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) ) {
|
||||
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) )
|
||||
{
|
||||
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: {
|
||||
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;
|
||||
}
|
1222
vere/sist.c
1222
vere/sist.c
File diff suppressed because it is too large
Load Diff
50
vere/term.c
50
vere/term.c
@ -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;
|
||||
}
|
||||
}
|
||||
@ -904,7 +904,6 @@ _term_read_tn_cb(uv_stream_t* tcp_u,
|
||||
{
|
||||
u3_utel* pty_u = (u3_utel*)(void*) tcp_u;
|
||||
|
||||
u3_lo_open();
|
||||
{
|
||||
if ( siz_i == UV_EOF ) {
|
||||
// nothing
|
||||
@ -920,7 +919,6 @@ _term_read_tn_cb(uv_stream_t* tcp_u,
|
||||
err:
|
||||
free(buf_u->base);
|
||||
}
|
||||
u3_lo_shut(c3y);
|
||||
}
|
||||
|
||||
/* _term_suck(): process a chunk of input
|
||||
@ -941,7 +939,6 @@ _term_read_tn_cb(uv_stream_t* tcp_u,
|
||||
static inline void
|
||||
_term_suck(u3_utty* uty_u, const c3_y* buf, ssize_t siz_i)
|
||||
{
|
||||
u3_lo_open();
|
||||
{
|
||||
if ( siz_i == UV_EOF ) {
|
||||
// nothing
|
||||
@ -956,7 +953,6 @@ _term_suck(u3_utty* uty_u, const c3_y* buf, ssize_t siz_i)
|
||||
}
|
||||
}
|
||||
}
|
||||
u3_lo_shut(c3y);
|
||||
}
|
||||
|
||||
/* _term_read_cb(): server read callback.
|
||||
@ -1218,7 +1214,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,24 +1224,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_term_ef_boil(): initial effects for loaded servers.
|
||||
*/
|
||||
void
|
||||
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));
|
||||
|
||||
u3z(pax);
|
||||
}
|
||||
u3_pier_plan(pax, u3nt(c3__belt, c3__ctl, 'c'));
|
||||
}
|
||||
|
||||
/* u3_term_ef_verb(): initial effects for verbose events
|
||||
@ -1255,7 +1234,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,20 +1260,19 @@ 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.
|
||||
*/
|
||||
void
|
||||
u3_term_ef_bake(u3_noun fav)
|
||||
u3_term_ef_bake(void)
|
||||
{
|
||||
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), 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);
|
||||
}
|
||||
|
37
vere/unix.c
37
vere/unix.c
@ -534,12 +534,10 @@ _delete_mount_point_out:
|
||||
static void
|
||||
_unix_time_cb(uv_timer_t* tim_u)
|
||||
{
|
||||
u3_lo_open();
|
||||
{
|
||||
u3_Host.unx_u.alm = c3n;
|
||||
u3_Host.unx_u.dyr = c3y;
|
||||
}
|
||||
u3_lo_shut(c3y);
|
||||
}
|
||||
|
||||
/* _unix_fs_event_cb(): filesystem event callback.
|
||||
@ -962,7 +960,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));
|
||||
}
|
||||
}
|
||||
@ -1088,7 +1086,6 @@ _unix_initial_update_dir(c3_c* pax_c)
|
||||
static void
|
||||
_unix_sign_cb(uv_signal_t* sil_u, c3_i num_i)
|
||||
{
|
||||
u3_lo_open();
|
||||
{
|
||||
switch ( num_i ) {
|
||||
default: fprintf(stderr, "\r\nmysterious signal %d\r\n", num_i); break;
|
||||
@ -1103,7 +1100,6 @@ _unix_sign_cb(uv_signal_t* sil_u, c3_i num_i)
|
||||
case SIGWINCH: u3_term_ef_winc(); break;
|
||||
}
|
||||
}
|
||||
u3_lo_shut(c3y);
|
||||
}
|
||||
|
||||
/* _unix_ef_sync(): check for files to sync.
|
||||
@ -1111,8 +1107,6 @@ _unix_sign_cb(uv_signal_t* sil_u, c3_i num_i)
|
||||
static void
|
||||
_unix_ef_sync(uv_check_t* han_u)
|
||||
{
|
||||
u3_lo_open();
|
||||
u3_lo_shut(c3y);
|
||||
}
|
||||
|
||||
/* _unix_sync_file(): sync file to unix
|
||||
@ -1335,11 +1329,6 @@ u3_unix_io_init(void)
|
||||
uv_timer_init(u3L, &unx_u->tim_u);
|
||||
unx_u->alm = c3n;
|
||||
unx_u->dyr = c3n;
|
||||
|
||||
if ( c3n == u3_Host.ops_u.nuu ) {
|
||||
u3v_plan(u3nt(u3_blip, c3__boat, u3_nul),
|
||||
u3nc(c3__boat, u3_nul));
|
||||
}
|
||||
}
|
||||
|
||||
/* u3_unix_acquire(): acquire a lockfile, killing anything that holds it.
|
||||
@ -1432,6 +1421,16 @@ u3_unix_ef_hold(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* u3_unix_ef_bake(): initial effects for new process.
|
||||
*/
|
||||
void
|
||||
u3_unix_ef_bake(void)
|
||||
{
|
||||
u3_pier_plan(u3nt(u3_blip, c3__boat, u3_nul),
|
||||
u3nc(c3__boat, u3_nul));
|
||||
|
||||
}
|
||||
|
||||
/* u3_unix_ef_move()
|
||||
*/
|
||||
void
|
||||
@ -1445,15 +1444,19 @@ u3_unix_ef_move(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* u3_unix_ef_boot(): boot actions
|
||||
*/
|
||||
void
|
||||
u3_unix_ef_initial_into()
|
||||
u3_unix_ef_boot(void)
|
||||
{
|
||||
u3_noun can = _unix_initial_update_dir(u3_Host.ops_u.arv_c);
|
||||
if ( u3_Host.ops_u.imp_c ) {
|
||||
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),
|
||||
u3nq(c3__into, u3_nul, c3y, can));
|
||||
u3_pier_plan(u3nq(u3_blip, c3__sync, u3k(u3A->sen), u3_nul),
|
||||
u3nq(c3__into, u3_nul, c3y, can));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* u3_unix_ef_look(): update the root.
|
||||
*/
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user