=================================================================== RCS file: /home/cvs/OpenXM/src/oxc/sm_ext.c,v retrieving revision 1.2 retrieving revision 1.10 diff -u -p -r1.2 -r1.10 --- OpenXM/src/oxc/sm_ext.c 2000/11/18 06:03:42 1.2 +++ OpenXM/src/oxc/sm_ext.c 2003/05/07 04:00:30 1.10 @@ -1,43 +1,71 @@ /* -*- mode: C; coding: euc-japan -*- */ -/* $OpenXM: OpenXM/src/oxc/sm_ext.c,v 1.1 2000/10/13 06:05:12 ohara Exp $ */ +/* $OpenXM: OpenXM/src/oxc/sm_ext.c,v 1.9 2000/12/14 01:35:58 ohara Exp $ */ #include #include #include #include -#include +#include +#include #include #include "sm.h" +static int sm_control_spawn(); +static void sm_control_terminate(); +static void sm_control_kill(); +static void sm_control_reset_pid(); + +static void pid_extend(); +static int pid_lookup(pid_t pid); +static int pid_registed(pid_t pid); +static void pid_regist(pid_t pid); +static void pid_delete(pid_t pid); +static int pid_reset(pid_t pid); +static int pid_kill(pid_t pid); +static void pid_kill_all(); + /* ultra loose data base. */ -static db db_localfunc[] = { +static struct { int (*func_ptr)(); char *key; } tbl_lfunc[] = { + {lf_oxc_open, "spawn"}, {lf_oxc_open, "oxc_open"}, {NULL, NULL} }; -static db db_sm[] = { +static struct { int (*func_ptr)(); int key; } tbl_smcmd[] = { + {sm_control_spawn, SM_control_spawn_server}, + {sm_control_terminate, SM_control_terminate_server}, {sm_executeFunction, SM_executeFunction}, {sm_mathcap, SM_mathcap}, + {sm_set_mathcap, SM_setMathCap}, {sm_popCMO, SM_popCMO}, {sm_pops, SM_pops}, + {sm_control_reset_pid, SM_control_reset_connection_server}, + {sm_control_kill, SM_control_kill}, {NULL, NULL} }; -__inline__ -static int (*db_search(void *key, db *dbs, int (*cmp)(void *, void *)))() +extern OXFILE *stack_oxfp; + +int (*sm_search_f(int code))() { - while (dbs->key != NULL) { - if (cmp(key, dbs->key) == 0) { - return dbs->func_ptr; + int i; + for (i=0; tbl_smcmd[i].key != NULL; i++) { + if (code == tbl_smcmd[i].key) { + return tbl_smcmd[i].func_ptr; } - dbs++; } return NULL; } static int (*lookup_localfunction(char *name))() { - return db_search(name, db_localfunc, strcmp); + int i; + for (i=0; tbl_lfunc[i].key != NULL; i++) { + if (strcmp(name, tbl_lfunc[i].key) == 0) { + return tbl_lfunc[i].func_ptr; + } + } + return NULL; } /* @@ -45,20 +73,20 @@ Normally local functions push a return value to the st but, if error occurs, then these return non-positive numbers and the sm_executeFunction push an error object. */ -void sm_executeFunction(OXFILE *oxfp) +void sm_executeFunction() { - int (*func)(OXFILE *); - int retcode = 0; + int (*func)(); + int retcode = 0; cmo *ob = pop(); if (ob->tag == CMO_STRING) { func = lookup_localfunction(((cmo_string *)ob)->s); if (func != NULL) { - if ((retcode = func(oxfp)) > 0) { - return; - } + if ((retcode = func()) > 0) { + return; + } } } - push_error(retcode, ob); + push_error(retcode, ob); } /* getargs() set number of popped objects to argc. */ @@ -67,10 +95,10 @@ static int getargs(cmo ***args) cmo **argv; int i; int argc = -1; - cmo_int32 *m = pop(); + cmo_int32 *m = (cmo_int32 *)pop(); if (m->tag != CMO_INT32 || (argc = m->i) < 0) { - fprintf(stderr, "oxc: invalid arguments\n"); + ox_printf("oxc: invalid arguments\n"); }else { argv = (cmo **)malloc(sizeof(cmo *)*argc); for(i=0; i= 0 && i != --pid_ptr) { - pids[i] = pids[pid_ptr]; - } + if (pid_ptr >= pid_size) { + pids_extend(); + } + pids[pid_ptr++] = pid; } -int lf_oxc_open() +static void pid_delete(pid_t pid) { - cmo **argv; - char *cmd; - int port; - int pid; + int i = pid_lookup(pid); + if (i >= 0 && i != --pid_ptr) { + pids[i] = pids[pid_ptr]; + } +} - if (getargs(&argv) != 2 || argv[0]->tag != CMO_STRING - || argv[1]->tag != CMO_INT32) { - fprintf(stderr, "oxc: invalid arguments\n"); - return -1; +static int pid_reset(pid_t pid) +{ + if (pid_registed(pid)) { + kill(pid, SIGUSR1); + return 1; } + return 0; +} - cmd = ((cmo_string *)argv[0])->s; - port = ((cmo_int32 *)argv[1])->i; - pid = lf_oxc_open_main(cmd, port); - if (pid > 0) { - push(new_cmo_int32(pid)); - pid_regist(pid); - } - return pid; +static int pid_kill(pid_t pid) +{ + if (pid_registed(pid)) { + kill(pid, SIGKILL); + pid_delete(pid); + return 1; + } + return 0; } -void sm_mathcap(OXFILE *oxfp) +/* Killing all child processes */ +static void pid_kill_all() { - cmo_mathcap *m = pop(); - if (m->tag == CMO_MATHCAP) { - mathcap_update(m); - }else { - push_error(-1, m); - /* an error object must be pushed */ - } + while(pid_ptr > 0) { + kill(pids[--pid_ptr], SIGKILL); + } } -void sm_control_kill(OXFILE *oxfp) +cmo_error2 *type_checker(cmo *ob, int type) { - cmo_int32 *m = pop(); - int pid = m->i; - if (m->tag != CMO_INT32 || !pid_registed(pid)) { - push_error(-1, m); - }else { - kill(pid, SIGKILL); - pid_delete(pid); +/* cmo_error2 *err_ob; */ + if (ob->tag != type) { + /* push and return an error object */ + } + return NULL; +} + +int lf_oxc_open() +{ + cmo_int32 *argc = pop(); + if (argc->tag == CMO_INT32 && argc->i == 1) { + return sm_control_spawn(); } + push_error(-1, argc); + return -1; } -void sm_control_reset(OXFILE *oxfp) +int sm_control_spawn_typecheck(cmo_list *args, cmo_list *ports, cmo_int32 *port, cmo_string *sname) { - cmo_int32 *m = pop(); - int pid = m->i; - if (m->tag != CMO_INT32 || !pid_registed(pid)) { - push_error(-1, m); - }else { - kill(pid, SIGUSR1); + char *cmd = sname->s; + + return args->tag == CMO_LIST + && list_length(args) > 1 + && ports->tag == CMO_LIST + && list_length(ports) > 0 + && port->tag == CMO_INT32 + && sname->tag == CMO_STRING + && cmd != NULL + && which(cmd, getenv("PATH")) != NULL; +} + +static int sm_control_spawn() +{ + cmo_list *args = pop(); + cmo_list *ports = list_first_cmo(args); + cmo_int32 *port = list_first_cmo(ports); + cmo_string *sname = list_nth(args, 1); + pid_t pid; + + if (sm_control_spawn_typecheck(args, ports, port, sname)) { + pid = lf_oxc_open_main(sname->s, port->i); + if (pid > 0) { + push(new_cmo_int32(pid)); + pid_regist(pid); + ox_printf("oxc: spawns %s\n", sname->s); + return pid; + } } + push_error(-1, args); + return 0; + } -void sm_control_start_engin(OXFILE *oxfp); +void sm_mathcap() +{ + push((cmo *)oxf_cmo_mathcap(stack_oxfp)); +} -static int intcmp(int key1, int key2) +void sm_set_mathcap() { - return key1 != key2; + cmo_mathcap *m = (cmo_mathcap *)pop(); + if (m->tag == CMO_MATHCAP) { + oxf_mathcap_update(stack_oxfp, m); + }else { + push_error(-1, m); + /* an error object must be pushed */ + } } +static void sm_control_kill() +{ + pid_kill_all(); +} -int (*sm_search_f(int code))() +static void sm_control_terminate() { - return db_search(code, db_sm, intcmp); + cmo_int32 *m = (cmo_int32 *)pop(); + pid_t pid = m->i; + if (m->tag != CMO_INT32 || !pid_kill(pid)) { + push_error(-1, m); + } +} + +static void sm_control_reset_pid() +{ + cmo_int32 *m = (cmo_int32 *)pop(); + pid_t pid = m->i; + if (m->tag != CMO_INT32 || !pid_reset(pid)) { + push_error(-1, m); + return; + } + /* ... */ }