[BACK]Return to sm_ext.c CVS log [TXT][DIR] Up to [local] / OpenXM / src / oxc

Annotation of OpenXM/src/oxc/sm_ext.c, Revision 1.10

1.1       ohara       1: /* -*- mode: C; coding: euc-japan -*- */
1.10    ! ohara       2: /* $OpenXM: OpenXM/src/oxc/sm_ext.c,v 1.9 2000/12/14 01:35:58 ohara Exp $ */
1.1       ohara       3:
                      4: #include <stdio.h>
                      5: #include <stdlib.h>
                      6: #include <unistd.h>
                      7: #include <string.h>
1.5       ohara       8: #include <sys/types.h>
1.3       ohara       9: #include <signal.h>
1.1       ohara      10: #include <ox_toolkit.h>
                     11: #include "sm.h"
                     12:
1.8       ohara      13: static int  sm_control_spawn();
                     14: static void sm_control_terminate();
                     15: static void sm_control_kill();
                     16: static void sm_control_reset_pid();
                     17:
                     18: static void pid_extend();
                     19: static int  pid_lookup(pid_t pid);
                     20: static int  pid_registed(pid_t pid);
                     21: static void pid_regist(pid_t pid);
                     22: static void pid_delete(pid_t pid);
                     23: static int  pid_reset(pid_t pid);
                     24: static int  pid_kill(pid_t pid);
                     25: static void pid_kill_all();
                     26:
1.1       ohara      27: /* ultra loose data base. */
1.8       ohara      28: static struct { int (*func_ptr)(); char *key; } tbl_lfunc[] = {
1.6       ohara      29:     {lf_oxc_open, "spawn"},
1.8       ohara      30:     {lf_oxc_open, "oxc_open"},
1.1       ohara      31:     {NULL, NULL}
                     32: };
                     33:
1.8       ohara      34: static struct { int (*func_ptr)(); int key; } tbl_smcmd[] = {
1.6       ohara      35:     {sm_control_spawn,     SM_control_spawn_server},
                     36:     {sm_control_terminate, SM_control_terminate_server},
1.1       ohara      37:     {sm_executeFunction, SM_executeFunction},
                     38:     {sm_mathcap,         SM_mathcap},
1.4       ohara      39:     {sm_set_mathcap,     SM_setMathCap},
1.1       ohara      40:     {sm_popCMO,          SM_popCMO},
                     41:     {sm_pops,            SM_pops},
1.8       ohara      42:     {sm_control_reset_pid, SM_control_reset_connection_server},
                     43:     {sm_control_kill, SM_control_kill},
1.1       ohara      44:     {NULL, NULL}
                     45: };
                     46:
1.6       ohara      47: extern OXFILE *stack_oxfp;
                     48:
1.8       ohara      49: int (*sm_search_f(int code))()
1.1       ohara      50: {
1.8       ohara      51:     int i;
                     52:     for (i=0; tbl_smcmd[i].key != NULL; i++) {
                     53:         if (code == tbl_smcmd[i].key) {
                     54:             return tbl_smcmd[i].func_ptr;
1.1       ohara      55:         }
                     56:     }
                     57:     return NULL;
                     58: }
                     59:
                     60: static int (*lookup_localfunction(char *name))()
                     61: {
1.8       ohara      62:     int i;
                     63:     for (i=0; tbl_lfunc[i].key != NULL; i++) {
                     64:         if (strcmp(name, tbl_lfunc[i].key) == 0) {
                     65:             return tbl_lfunc[i].func_ptr;
                     66:         }
                     67:     }
                     68:     return NULL;
1.1       ohara      69: }
                     70:
                     71: /*
                     72: Normally local functions push a return value to the stack.
                     73: but, if error occurs, then these return non-positive numbers and
                     74: the sm_executeFunction push an error object.
                     75: */
1.6       ohara      76: void sm_executeFunction()
1.1       ohara      77: {
1.6       ohara      78:     int (*func)();
1.4       ohara      79:     int retcode = 0;
1.1       ohara      80:     cmo *ob = pop();
                     81:     if (ob->tag == CMO_STRING) {
                     82:         func = lookup_localfunction(((cmo_string *)ob)->s);
                     83:         if (func != NULL) {
1.6       ohara      84:             if ((retcode = func()) > 0) {
1.4       ohara      85:                 return;
                     86:             }
1.1       ohara      87:         }
                     88:     }
1.4       ohara      89:     push_error(retcode, ob);
1.1       ohara      90: }
                     91:
                     92: /* getargs() set number of popped objects to argc. */
                     93: static int getargs(cmo ***args)
                     94: {
                     95:     cmo **argv;
                     96:     int i;
                     97:     int argc = -1;
1.4       ohara      98:     cmo_int32 *m = (cmo_int32 *)pop();
1.1       ohara      99:
                    100:     if (m->tag != CMO_INT32 || (argc = m->i) < 0) {
1.10    ! ohara     101:         ox_printf("oxc: invalid arguments\n");
1.1       ohara     102:     }else {
                    103:         argv = (cmo **)malloc(sizeof(cmo *)*argc);
                    104:         for(i=0; i<argc; i++) {
                    105:             argv[i] = pop();
                    106:         }
                    107:         *args = argv;
                    108:     }
1.4       ohara     109:     return argc;
1.1       ohara     110: }
                    111:
1.5       ohara     112: #define MAX_PROCESS 1024
                    113:
1.6       ohara     114: /* Process Table */
1.5       ohara     115: static pid_t *pids = NULL;
1.1       ohara     116: static int pid_ptr = 0;
1.5       ohara     117: static int pid_size = 0;
                    118:
1.6       ohara     119: static void pids_extend()
1.5       ohara     120: {
                    121:     int size2 = pid_size + MAX_PROCESS;
                    122:     pid_t *pids2 = (pid_t *)malloc(sizeof(pid_t)*size2);
                    123:     if (pids != NULL) {
                    124:         memcpy(pids2, pids, sizeof(pid_t)*pid_size);
                    125:         free(pids);
                    126:     }
                    127:     pid_size = size2;
                    128:     pids = pids2;
                    129: }
1.1       ohara     130:
1.8       ohara     131: static int pid_lookup(pid_t pid)
1.2       ohara     132: {
1.4       ohara     133:     int i;
                    134:     for(i=0; i<pid_ptr; i++) {
                    135:         if (pids[i] == pid) {
                    136:             return i;
                    137:         }
                    138:     }
                    139:     return -1;
1.2       ohara     140: }
                    141:
1.8       ohara     142: static int pid_registed(pid_t pid)
1.2       ohara     143: {
1.4       ohara     144:     return pid_lookup(pid)+1;
1.2       ohara     145: }
                    146:
1.8       ohara     147: static void pid_regist(pid_t pid)
1.1       ohara     148: {
1.5       ohara     149:     if (pid_ptr >= pid_size) {
1.8       ohara     150:         pids_extend();
1.4       ohara     151:     }
1.8       ohara     152:     pids[pid_ptr++] = pid;
1.1       ohara     153: }
                    154:
1.8       ohara     155: static void pid_delete(pid_t pid)
1.2       ohara     156: {
1.4       ohara     157:     int i = pid_lookup(pid);
                    158:     if (i >= 0 && i != --pid_ptr) {
                    159:         pids[i] = pids[pid_ptr];
                    160:     }
1.2       ohara     161: }
                    162:
1.8       ohara     163: static int pid_reset(pid_t pid)
                    164: {
                    165:     if (pid_registed(pid)) {
                    166:         kill(pid, SIGUSR1);
                    167:         return 1;
                    168:     }
                    169:     return 0;
                    170: }
                    171:
                    172: static int pid_kill(pid_t pid)
1.5       ohara     173: {
1.8       ohara     174:     if (pid_registed(pid)) {
                    175:         kill(pid, SIGKILL);
                    176:         pid_delete(pid);
                    177:         return 1;
                    178:     }
                    179:     return 0;
1.5       ohara     180: }
                    181:
                    182: /* Killing all child processes */
1.8       ohara     183: static void pid_kill_all()
1.5       ohara     184: {
1.8       ohara     185:     while(pid_ptr > 0) {
1.5       ohara     186:         kill(pids[--pid_ptr], SIGKILL);
1.8       ohara     187:     }
1.5       ohara     188: }
                    189:
1.6       ohara     190: cmo_error2 *type_checker(cmo *ob, int type)
                    191: {
1.8       ohara     192: /*  cmo_error2 *err_ob; */
                    193:     if (ob->tag != type) {
                    194:         /* push and return an error object */
                    195:     }
                    196:     return NULL;
1.6       ohara     197: }
                    198:
1.1       ohara     199: int lf_oxc_open()
                    200: {
1.9       ohara     201:     cmo_int32 *argc = pop();
                    202:        if (argc->tag == CMO_INT32 && argc->i == 1) {
                    203:                return sm_control_spawn();
                    204:        }
                    205:        push_error(-1, argc);
                    206:        return -1;
                    207: }
                    208:
                    209: int sm_control_spawn_typecheck(cmo_list *args, cmo_list *ports, cmo_int32 *port, cmo_string *sname)
                    210: {
                    211:        char *cmd = sname->s;
                    212:
                    213:        return args->tag == CMO_LIST
                    214:                && list_length(args) > 1
                    215:                && ports->tag == CMO_LIST
                    216:                && list_length(ports) > 0
                    217:                && port->tag == CMO_INT32
                    218:                && sname->tag == CMO_STRING
                    219:                && cmd != NULL
                    220:                && which(cmd, getenv("PATH")) != NULL;
1.6       ohara     221: }
                    222:
1.8       ohara     223: static int sm_control_spawn()
1.6       ohara     224: {
1.9       ohara     225:        cmo_list *args    = pop();
                    226:        cmo_list *ports   = list_first_cmo(args);
                    227:        cmo_int32 *port   = list_first_cmo(ports);
                    228:        cmo_string *sname = list_nth(args, 1);
                    229:        pid_t pid;
                    230:
                    231:        if (sm_control_spawn_typecheck(args, ports, port, sname)) {
                    232:                pid = lf_oxc_open_main(sname->s, port->i);
                    233:                if (pid > 0) {
                    234:                        push(new_cmo_int32(pid));
                    235:                        pid_regist(pid);
1.10    ! ohara     236:                        ox_printf("oxc: spawns %s\n", sname->s);
1.9       ohara     237:                        return pid;
                    238:                }
                    239:        }
                    240:        push_error(-1, args);
                    241:        return 0;
1.1       ohara     242:
                    243: }
                    244:
1.6       ohara     245: void sm_mathcap()
1.1       ohara     246: {
1.6       ohara     247:     push((cmo *)oxf_cmo_mathcap(stack_oxfp));
1.4       ohara     248: }
                    249:
1.6       ohara     250: void sm_set_mathcap()
1.4       ohara     251: {
                    252:     cmo_mathcap *m = (cmo_mathcap *)pop();
                    253:     if (m->tag == CMO_MATHCAP) {
1.6       ohara     254:         oxf_mathcap_update(stack_oxfp, m);
1.4       ohara     255:     }else {
                    256:         push_error(-1, m);
                    257:         /* an error object must be pushed */
                    258:     }
1.1       ohara     259: }
1.2       ohara     260:
1.8       ohara     261: static void sm_control_kill()
1.2       ohara     262: {
1.8       ohara     263:     pid_kill_all();
1.5       ohara     264: }
                    265:
1.8       ohara     266: static void sm_control_terminate()
1.5       ohara     267: {
1.4       ohara     268:     cmo_int32 *m = (cmo_int32 *)pop();
1.5       ohara     269:     pid_t pid = m->i;
                    270:     if (m->tag != CMO_INT32 || !pid_kill(pid)) {
1.4       ohara     271:         push_error(-1, m);
                    272:     }
1.2       ohara     273: }
                    274:
1.8       ohara     275: static void sm_control_reset_pid()
1.2       ohara     276: {
1.4       ohara     277:     cmo_int32 *m = (cmo_int32 *)pop();
1.5       ohara     278:     pid_t pid = m->i;
                    279:     if (m->tag != CMO_INT32 || !pid_reset(pid)) {
1.4       ohara     280:         push_error(-1, m);
1.8       ohara     281:         return;
1.4       ohara     282:     }
1.8       ohara     283:     /* ... */
1.1       ohara     284: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>