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

1.1       ohara       1: /* -*- mode: C; coding: euc-japan -*- */
1.5     ! ohara       2: /* $OpenXM: OpenXM/src/oxc/sm_ext.c,v 1.4 2000/11/28 04:52:05 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:
                     13: /* ultra loose data base. */
                     14: static db db_localfunc[] = {
                     15:     {lf_oxc_open, "oxc_open"},
                     16:     {NULL, NULL}
                     17: };
                     18:
                     19: static db db_sm[] = {
                     20:     {sm_executeFunction, SM_executeFunction},
                     21:     {sm_mathcap,         SM_mathcap},
1.4       ohara      22:     {sm_set_mathcap,     SM_setMathCap},
1.1       ohara      23:     {sm_popCMO,          SM_popCMO},
                     24:     {sm_pops,            SM_pops},
1.5     ! ohara      25:        {sm_control_reset_pid, SM_control_reset_connection_pid},
        !            26:        {sm_control_kill_pid, SM_control_kill_pid},
        !            27:        {sm_control_kill, SM_control_kill},
1.1       ohara      28:     {NULL, NULL}
                     29: };
                     30:
                     31: __inline__
                     32: static int (*db_search(void *key, db *dbs, int (*cmp)(void *, void *)))()
                     33: {
                     34:     while (dbs->key != NULL) {
                     35:         if (cmp(key, dbs->key) == 0) {
                     36:             return dbs->func_ptr;
                     37:         }
                     38:         dbs++;
                     39:     }
                     40:     return NULL;
                     41: }
                     42:
                     43: static int (*lookup_localfunction(char *name))()
                     44: {
                     45:     return db_search(name, db_localfunc, strcmp);
                     46: }
                     47:
                     48: /*
                     49: Normally local functions push a return value to the stack.
                     50: but, if error occurs, then these return non-positive numbers and
                     51: the sm_executeFunction push an error object.
                     52: */
                     53: void sm_executeFunction(OXFILE *oxfp)
                     54: {
                     55:     int (*func)(OXFILE *);
1.4       ohara      56:     int retcode = 0;
1.1       ohara      57:     cmo *ob = pop();
                     58:     if (ob->tag == CMO_STRING) {
                     59:         func = lookup_localfunction(((cmo_string *)ob)->s);
                     60:         if (func != NULL) {
                     61:             if ((retcode = func(oxfp)) > 0) {
1.4       ohara      62:                 return;
                     63:             }
1.1       ohara      64:         }
                     65:     }
1.4       ohara      66:     push_error(retcode, ob);
1.1       ohara      67: }
                     68:
                     69: /* getargs() set number of popped objects to argc. */
                     70: static int getargs(cmo ***args)
                     71: {
                     72:     cmo **argv;
                     73:     int i;
                     74:     int argc = -1;
1.4       ohara      75:     cmo_int32 *m = (cmo_int32 *)pop();
1.1       ohara      76:
                     77:     if (m->tag != CMO_INT32 || (argc = m->i) < 0) {
                     78:         fprintf(stderr, "oxc: invalid arguments\n");
                     79:     }else {
                     80:         argv = (cmo **)malloc(sizeof(cmo *)*argc);
                     81:         for(i=0; i<argc; i++) {
                     82:             argv[i] = pop();
                     83:         }
                     84:         *args = argv;
                     85:     }
1.4       ohara      86:     return argc;
1.1       ohara      87: }
                     88:
1.5     ! ohara      89: #define MAX_PROCESS 1024
        !            90:
        !            91: static pid_t *pids = NULL;
1.1       ohara      92: static int pid_ptr = 0;
1.5     ! ohara      93: static int pid_size = 0;
        !            94:
        !            95: void pids_extend()
        !            96: {
        !            97:     int size2 = pid_size + MAX_PROCESS;
        !            98:     pid_t *pids2 = (pid_t *)malloc(sizeof(pid_t)*size2);
        !            99:     if (pids != NULL) {
        !           100:         memcpy(pids2, pids, sizeof(pid_t)*pid_size);
        !           101:         free(pids);
        !           102:     }
        !           103:     pid_size = size2;
        !           104:     pids = pids2;
        !           105: }
1.1       ohara     106:
1.5     ! ohara     107: int pid_lookup(pid_t pid)
1.2       ohara     108: {
1.4       ohara     109:     int i;
                    110:     for(i=0; i<pid_ptr; i++) {
                    111:         if (pids[i] == pid) {
                    112:             return i;
                    113:         }
                    114:     }
                    115:     return -1;
1.2       ohara     116: }
                    117:
1.5     ! ohara     118: int pid_registed(pid_t pid)
1.2       ohara     119: {
1.4       ohara     120:     return pid_lookup(pid)+1;
1.2       ohara     121: }
                    122:
1.5     ! ohara     123: void pid_regist(pid_t pid)
1.1       ohara     124: {
1.5     ! ohara     125:     if (pid_ptr >= pid_size) {
        !           126:                pids_extend();
1.4       ohara     127:     }
1.5     ! ohara     128:        pids[pid_ptr++] = pid;
1.1       ohara     129: }
                    130:
1.5     ! ohara     131: void pid_delete(pid_t pid)
1.2       ohara     132: {
1.4       ohara     133:     int i = pid_lookup(pid);
                    134:     if (i >= 0 && i != --pid_ptr) {
                    135:         pids[i] = pids[pid_ptr];
                    136:     }
1.2       ohara     137: }
                    138:
1.5     ! ohara     139: int pid_reset(pid_t pid)
        !           140: {
        !           141:        if (pid_registed(pid)) {
        !           142:                kill(pid, SIGUSR1);
        !           143:                return 1;
        !           144:        }
        !           145:        return 0;
        !           146: }
        !           147:
        !           148: int pid_kill(pid_t pid)
        !           149: {
        !           150:        if (pid_registed(pid)) {
        !           151:                kill(pid, SIGKILL);
        !           152:                pid_delete(pid);
        !           153:                return 1;
        !           154:        }
        !           155:        return 0;
        !           156: }
        !           157:
        !           158: /* Killing all child processes */
        !           159: void pid_kill_all()
        !           160: {
        !           161:        while(pid_ptr > 0) {
        !           162:         kill(pids[--pid_ptr], SIGKILL);
        !           163:        }
        !           164: }
        !           165:
1.1       ohara     166: int lf_oxc_open()
                    167: {
                    168:     cmo **argv;
                    169:     char *cmd;
                    170:     int port;
1.5     ! ohara     171:     pid_t pid;
1.1       ohara     172:
                    173:     if (getargs(&argv) != 2 || argv[0]->tag != CMO_STRING
1.4       ohara     174:         || argv[1]->tag != CMO_INT32) {
                    175:         fprintf(stderr, "oxc: invalid arguments\n");
1.1       ohara     176:         return -1;
                    177:     }
                    178:
1.4       ohara     179:     cmd  = ((cmo_string *)argv[0])->s;
                    180:     port = ((cmo_int32 *)argv[1])->i;
                    181:     pid = lf_oxc_open_main(cmd, port);
                    182:     if (pid > 0) {
                    183:         push(new_cmo_int32(pid));
                    184:         pid_regist(pid);
                    185:     }
                    186:     return pid;
1.1       ohara     187: }
                    188:
                    189: void sm_mathcap(OXFILE *oxfp)
                    190: {
1.4       ohara     191:     push((cmo *)oxf_cmo_mathcap(oxfp));
                    192: }
                    193:
                    194: void sm_set_mathcap(OXFILE *oxfp)
                    195: {
                    196:     cmo_mathcap *m = (cmo_mathcap *)pop();
                    197:     if (m->tag == CMO_MATHCAP) {
                    198:         oxf_mathcap_update(oxfp, m);
                    199:     }else {
                    200:         push_error(-1, m);
                    201:         /* an error object must be pushed */
                    202:     }
1.1       ohara     203: }
1.2       ohara     204:
                    205: void sm_control_kill(OXFILE *oxfp)
                    206: {
1.5     ! ohara     207:        pid_kill_all();
        !           208: }
        !           209:
        !           210: void sm_control_kill_pid(OXFILE *oxfp)
        !           211: {
1.4       ohara     212:     cmo_int32 *m = (cmo_int32 *)pop();
1.5     ! ohara     213:     pid_t pid = m->i;
        !           214:     if (m->tag != CMO_INT32 || !pid_kill(pid)) {
1.4       ohara     215:         push_error(-1, m);
                    216:     }
1.2       ohara     217: }
                    218:
1.5     ! ohara     219: void sm_control_reset_pid(OXFILE *oxfp)
1.2       ohara     220: {
1.4       ohara     221:     cmo_int32 *m = (cmo_int32 *)pop();
1.5     ! ohara     222:     pid_t pid = m->i;
        !           223:     if (m->tag != CMO_INT32 || !pid_reset(pid)) {
1.4       ohara     224:         push_error(-1, m);
1.5     ! ohara     225:                return;
1.4       ohara     226:     }
1.5     ! ohara     227:        /* ... */
1.2       ohara     228: }
                    229:
1.4       ohara     230: void sm_control_spawn_server(OXFILE *oxfp);
                    231: void sm_control_terminate_server(OXFILE *oxfp);
1.1       ohara     232:
                    233: static int intcmp(int key1, int key2)
                    234: {
                    235:     return key1 != key2;
                    236: }
                    237:
                    238:
                    239: int (*sm_search_f(int code))()
                    240: {
                    241:     return db_search(code, db_sm, intcmp);
                    242: }

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