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

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

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