[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.11

1.1       ohara       1: /* -*- mode: C; coding: euc-japan -*- */
1.11    ! ohara       2: /* $OpenXM: OpenXM/src/oxc/sm_ext.c,v 1.10 2003/05/07 04:00:30 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();
1.11    ! ohara      14: static int  sm_control_terminate();
        !            15: static int  sm_control_kill();
        !            16: static int  sm_control_reset_pid();
1.8       ohara      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.11    ! ohara      44:     {NULL, 0}
1.1       ohara      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;
1.11    ! ohara      52:     for (i=0; tbl_smcmd[i].key != 0; i++) {
1.8       ohara      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.11    ! ohara      76: int 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.11    ! ohara      85:                 return 0;
1.4       ohara      86:             }
1.1       ohara      87:         }
                     88:     }
1.4       ohara      89:     push_error(retcode, ob);
1.11    ! ohara      90:     return 0;
1.1       ohara      91: }
                     92:
                     93: /* getargs() set number of popped objects to argc. */
                     94: static int getargs(cmo ***args)
                     95: {
                     96:     cmo **argv;
                     97:     int i;
                     98:     int argc = -1;
1.4       ohara      99:     cmo_int32 *m = (cmo_int32 *)pop();
1.1       ohara     100:
                    101:     if (m->tag != CMO_INT32 || (argc = m->i) < 0) {
1.10      ohara     102:         ox_printf("oxc: invalid arguments\n");
1.1       ohara     103:     }else {
                    104:         argv = (cmo **)malloc(sizeof(cmo *)*argc);
                    105:         for(i=0; i<argc; i++) {
                    106:             argv[i] = pop();
                    107:         }
                    108:         *args = argv;
                    109:     }
1.4       ohara     110:     return argc;
1.1       ohara     111: }
                    112:
1.5       ohara     113: #define MAX_PROCESS 1024
                    114:
1.6       ohara     115: /* Process Table */
1.5       ohara     116: static pid_t *pids = NULL;
1.1       ohara     117: static int pid_ptr = 0;
1.5       ohara     118: static int pid_size = 0;
                    119:
1.6       ohara     120: static void pids_extend()
1.5       ohara     121: {
                    122:     int size2 = pid_size + MAX_PROCESS;
                    123:     pid_t *pids2 = (pid_t *)malloc(sizeof(pid_t)*size2);
                    124:     if (pids != NULL) {
                    125:         memcpy(pids2, pids, sizeof(pid_t)*pid_size);
                    126:         free(pids);
                    127:     }
                    128:     pid_size = size2;
                    129:     pids = pids2;
                    130: }
1.1       ohara     131:
1.8       ohara     132: static int pid_lookup(pid_t pid)
1.2       ohara     133: {
1.4       ohara     134:     int i;
                    135:     for(i=0; i<pid_ptr; i++) {
                    136:         if (pids[i] == pid) {
                    137:             return i;
                    138:         }
                    139:     }
                    140:     return -1;
1.2       ohara     141: }
                    142:
1.8       ohara     143: static int pid_registed(pid_t pid)
1.2       ohara     144: {
1.4       ohara     145:     return pid_lookup(pid)+1;
1.2       ohara     146: }
                    147:
1.8       ohara     148: static void pid_regist(pid_t pid)
1.1       ohara     149: {
1.5       ohara     150:     if (pid_ptr >= pid_size) {
1.8       ohara     151:         pids_extend();
1.4       ohara     152:     }
1.8       ohara     153:     pids[pid_ptr++] = pid;
1.1       ohara     154: }
                    155:
1.8       ohara     156: static void pid_delete(pid_t pid)
1.2       ohara     157: {
1.4       ohara     158:     int i = pid_lookup(pid);
                    159:     if (i >= 0 && i != --pid_ptr) {
                    160:         pids[i] = pids[pid_ptr];
                    161:     }
1.2       ohara     162: }
                    163:
1.8       ohara     164: static int pid_reset(pid_t pid)
                    165: {
                    166:     if (pid_registed(pid)) {
                    167:         kill(pid, SIGUSR1);
                    168:         return 1;
                    169:     }
                    170:     return 0;
                    171: }
                    172:
                    173: static int pid_kill(pid_t pid)
1.5       ohara     174: {
1.8       ohara     175:     if (pid_registed(pid)) {
                    176:         kill(pid, SIGKILL);
                    177:         pid_delete(pid);
                    178:         return 1;
                    179:     }
                    180:     return 0;
1.5       ohara     181: }
                    182:
                    183: /* Killing all child processes */
1.8       ohara     184: static void pid_kill_all()
1.5       ohara     185: {
1.8       ohara     186:     while(pid_ptr > 0) {
1.5       ohara     187:         kill(pids[--pid_ptr], SIGKILL);
1.8       ohara     188:     }
1.5       ohara     189: }
                    190:
1.6       ohara     191: cmo_error2 *type_checker(cmo *ob, int type)
                    192: {
1.8       ohara     193: /*  cmo_error2 *err_ob; */
                    194:     if (ob->tag != type) {
                    195:         /* push and return an error object */
                    196:     }
                    197:     return NULL;
1.6       ohara     198: }
                    199:
1.1       ohara     200: int lf_oxc_open()
                    201: {
1.11    ! ohara     202:     cmo_int32 *argc = (cmo_int32 *)pop();
1.9       ohara     203:        if (argc->tag == CMO_INT32 && argc->i == 1) {
                    204:                return sm_control_spawn();
                    205:        }
1.11    ! ohara     206:        push_error(-1, (cmo *)argc);
1.9       ohara     207:        return -1;
                    208: }
                    209:
                    210: int sm_control_spawn_typecheck(cmo_list *args, cmo_list *ports, cmo_int32 *port, cmo_string *sname)
                    211: {
                    212:        char *cmd = sname->s;
                    213:
                    214:        return args->tag == CMO_LIST
                    215:                && list_length(args) > 1
                    216:                && ports->tag == CMO_LIST
                    217:                && list_length(ports) > 0
                    218:                && port->tag == CMO_INT32
                    219:                && sname->tag == CMO_STRING
                    220:                && cmd != NULL
                    221:                && which(cmd, getenv("PATH")) != NULL;
1.6       ohara     222: }
                    223:
1.8       ohara     224: static int sm_control_spawn()
1.6       ohara     225: {
1.11    ! ohara     226:        cmo_list *args    = (cmo_list *)pop();
        !           227:        cmo_list *ports   = (cmo_list *)list_first_cmo(args);
        !           228:        cmo_int32 *port   = (cmo_int32 *)list_first_cmo(ports);
        !           229:        cmo_string *sname = (cmo_string *)list_nth(args, 1);
1.9       ohara     230:        pid_t pid;
                    231:
                    232:        if (sm_control_spawn_typecheck(args, ports, port, sname)) {
1.11    ! ohara     233:                pid = lf_oxc_open_main(sname->s, (short)port->i);
1.9       ohara     234:                if (pid > 0) {
1.11    ! ohara     235:                        push((cmo *)new_cmo_int32(pid));
1.9       ohara     236:                        pid_regist(pid);
1.10      ohara     237:                        ox_printf("oxc: spawns %s\n", sname->s);
1.9       ohara     238:                        return pid;
                    239:                }
                    240:        }
1.11    ! ohara     241:        push_error(-1, (cmo *)args);
1.9       ohara     242:        return 0;
1.1       ohara     243:
                    244: }
                    245:
1.11    ! ohara     246: int sm_mathcap()
1.1       ohara     247: {
1.6       ohara     248:     push((cmo *)oxf_cmo_mathcap(stack_oxfp));
1.11    ! ohara     249:     return 0;
1.4       ohara     250: }
                    251:
1.11    ! ohara     252: int sm_set_mathcap()
1.4       ohara     253: {
                    254:     cmo_mathcap *m = (cmo_mathcap *)pop();
                    255:     if (m->tag == CMO_MATHCAP) {
1.6       ohara     256:         oxf_mathcap_update(stack_oxfp, m);
1.4       ohara     257:     }else {
1.11    ! ohara     258:         push_error(-1, (cmo *)m);
1.4       ohara     259:         /* an error object must be pushed */
                    260:     }
1.11    ! ohara     261:     return 0;
1.1       ohara     262: }
1.2       ohara     263:
1.11    ! ohara     264: static int sm_control_kill()
1.2       ohara     265: {
1.8       ohara     266:     pid_kill_all();
1.11    ! ohara     267:     return 0;
1.5       ohara     268: }
                    269:
1.11    ! ohara     270: static int sm_control_terminate()
1.5       ohara     271: {
1.4       ohara     272:     cmo_int32 *m = (cmo_int32 *)pop();
1.5       ohara     273:     pid_t pid = m->i;
                    274:     if (m->tag != CMO_INT32 || !pid_kill(pid)) {
1.11    ! ohara     275:         push_error(-1, (cmo *)m);
1.4       ohara     276:     }
1.11    ! ohara     277:     return 0;
1.2       ohara     278: }
                    279:
1.11    ! ohara     280: static int sm_control_reset_pid()
1.2       ohara     281: {
1.4       ohara     282:     cmo_int32 *m = (cmo_int32 *)pop();
1.5       ohara     283:     pid_t pid = m->i;
                    284:     if (m->tag != CMO_INT32 || !pid_reset(pid)) {
1.11    ! ohara     285:         push_error(-1, (cmo *)m);
        !           286:         return 0;
1.4       ohara     287:     }
1.8       ohara     288:     /* ... */
1.11    ! ohara     289:     return 0;
1.1       ohara     290: }

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