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

Diff for /OpenXM/src/oxc/sm_ext.c between version 1.3 and 1.12

version 1.3, 2000/11/28 04:02:56 version 1.12, 2016/04/02 15:01:46
Line 1 
Line 1 
 /* -*- mode: C; coding: euc-japan -*- */  /* -*- mode: C; coding: euc-japan -*- */
 /* $OpenXM: OpenXM/src/oxc/sm_ext.c,v 1.2 2000/11/18 06:03:42 ohara Exp $ */  /* $OpenXM: OpenXM/src/oxc/sm_ext.c,v 1.11 2016/04/01 18:12:39 ohara Exp $ */
   
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <unistd.h>  #include <unistd.h>
 #include <string.h>  #include <string.h>
   #include <sys/types.h>
 #include <signal.h>  #include <signal.h>
 #include <ox_toolkit.h>  #include <ox_toolkit.h>
 #include "sm.h"  #include "sm.h"
   
   static int  sm_control_spawn();
   static int  sm_control_terminate();
   static int  sm_control_kill();
   static int  sm_control_reset_pid();
   
   static void pid_extend();
   static int  pid_lookup(pid_t pid);
   static int  pid_registered(pid_t pid);
   static void pid_register(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();
   
   #define IS_CMO_INT32(c)       ((c) && ((c)->tag == CMO_INT32))
   #define IS_CMO_STRING(c)      ((c) && ((c)->tag == CMO_STRING))
   #define IS_CMO_LIST(c)        ((c) && ((c)->tag == CMO_LIST))
   #define IS_CMO_LIST_LEN(c,n)  (IS_CMO_LIST(c) && (list_length((c)) >= (n)))
   
 /* ultra loose data base. */  /* 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"},      {lf_oxc_open, "oxc_open"},
     {NULL, NULL}      {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_executeFunction, SM_executeFunction},
     {sm_mathcap,         SM_mathcap},      {sm_mathcap,         SM_mathcap},
       {sm_set_mathcap,     SM_setMathCap},
     {sm_popCMO,          SM_popCMO},      {sm_popCMO,          SM_popCMO},
     {sm_pops,            SM_pops},      {sm_pops,            SM_pops},
     {NULL, NULL}      {sm_control_reset_pid, SM_control_reset_connection_server},
       {sm_control_kill, SM_control_kill},
       {NULL, 0}
 };  };
   
 __inline__  extern OXFILE *stack_oxfp;
 static int (*db_search(void *key, db *dbs, int (*cmp)(void *, void *)))()  
   int (*sm_search_f(int code))()
 {  {
     while (dbs->key != NULL) {      int i;
         if (cmp(key, dbs->key) == 0) {      for (i=0; tbl_smcmd[i].key != 0; i++) {
             return dbs->func_ptr;          if (code == tbl_smcmd[i].key) {
               return tbl_smcmd[i].func_ptr;
         }          }
         dbs++;  
     }      }
     return NULL;      return NULL;
 }  }
   
 static int (*lookup_localfunction(char *name))()  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;
 }  }
   
 /*  /*
Line 45  Normally local functions push a return value to the st
Line 78  Normally local functions push a return value to the st
 but, if error occurs, then these return non-positive numbers and  but, if error occurs, then these return non-positive numbers and
 the sm_executeFunction push an error object.  the sm_executeFunction push an error object.
 */  */
 void sm_executeFunction(OXFILE *oxfp)  int sm_executeFunction()
 {  {
     int (*func)(OXFILE *);      int (*func)();
         int retcode = 0;      int retcode = 0;
     cmo *ob = pop();      cmo *ob = pop();
     if (ob->tag == CMO_STRING) {      if (ob->tag == CMO_STRING) {
         func = lookup_localfunction(((cmo_string *)ob)->s);          func = lookup_localfunction(((cmo_string *)ob)->s);
         if (func != NULL) {          if (func != NULL) {
             if ((retcode = func(oxfp)) > 0) {              if ((retcode = func()) > 0) {
                                 return;                  return 0;
                         }              }
         }          }
     }      }
         push_error(retcode, ob);      push_error(retcode, ob);
       return 0;
 }  }
   
 /* getargs() set number of popped objects to argc. */  /* getargs() set number of popped objects to argc. */
Line 67  static int getargs(cmo ***args)
Line 101  static int getargs(cmo ***args)
     cmo **argv;      cmo **argv;
     int i;      int i;
     int argc = -1;      int argc = -1;
     cmo_int32 *m = pop();      cmo_int32 *m = (cmo_int32 *)pop();
   
     if (m->tag != CMO_INT32 || (argc = m->i) < 0) {      if (m->tag != CMO_INT32 || (argc = m->i) < 0) {
         fprintf(stderr, "oxc: invalid arguments\n");          ox_printf("oxc: invalid arguments\n");
     }else {      }else {
         argv = (cmo **)malloc(sizeof(cmo *)*argc);          argv = (cmo **)malloc(sizeof(cmo *)*argc);
         for(i=0; i<argc; i++) {          for(i=0; i<argc; i++) {
Line 78  static int getargs(cmo ***args)
Line 112  static int getargs(cmo ***args)
         }          }
         *args = argv;          *args = argv;
     }      }
         return argc;      return argc;
 }  }
   
 static int pids[1024] = {0};  #define MAX_PROCESS 1024
   
   /* Process Table */
   static pid_t *pids = NULL;
 static int pid_ptr = 0;  static int pid_ptr = 0;
   static int pid_size = 0;
   
 int pid_lookup(int pid)  static void pids_extend()
 {  {
         int i;      int size2 = pid_size + MAX_PROCESS;
         for(i=0; i<pid_ptr; i++) {      pid_t *pids2 = (pid_t *)malloc(sizeof(pid_t)*size2);
                 if (pids[i] == pid) {      if (pids != NULL) {
                         return i;          memcpy(pids2, pids, sizeof(pid_t)*pid_size);
                 }          free(pids);
         }      }
         return -1;      pid_size = size2;
       pids = pids2;
 }  }
   
 int pid_registed(int pid)  static int pid_lookup(pid_t pid)
 {  {
         return pid_lookup(pid)+1;      int i;
       for(i=0; i<pid_ptr; i++) {
           if (pids[i] == pid) {
               return i;
           }
       }
       return -1;
 }  }
   
 int pid_regist(int pid)  static int pid_registered(pid_t pid)
 {  {
         if (pid_ptr < 1024) {      return pid_lookup(pid)+1;
                 pids[pid_ptr++] = pid;  
                 return pid;  
         }  
         return 0;  
 }  }
   
 void pid_delete(int pid)  static void pid_register(pid_t pid)
 {  {
         int i = pid_lookup(pid);      if (pid_ptr >= pid_size) {
         if (i >= 0 && i != --pid_ptr) {          pids_extend();
                 pids[i] = pids[pid_ptr];      }
         }      pids[pid_ptr++] = pid;
 }  }
   
 int lf_oxc_open()  static void pid_delete(pid_t pid)
 {  {
     cmo **argv;      int i = pid_lookup(pid);
     char *cmd;      if (i >= 0 && i != --pid_ptr) {
     int port;          pids[i] = pids[pid_ptr];
     int pid;      }
   }
   
     if (getargs(&argv) != 2 || argv[0]->tag != CMO_STRING  static int pid_reset(pid_t pid)
                 || argv[1]->tag != CMO_INT32) {  {
                 fprintf(stderr, "oxc: invalid arguments\n");      if (pid_registered(pid)) {
         return -1;          kill(pid, SIGUSR1);
           return 1;
     }      }
       return 0;
   }
   
         cmd  = ((cmo_string *)argv[0])->s;  static int pid_kill(pid_t pid)
         port = ((cmo_int32 *)argv[1])->i;  {
         pid = lf_oxc_open_main(cmd, port);      if (pid_registered(pid)) {
         if (pid > 0) {          kill(pid, SIGKILL);
                 push(new_cmo_int32(pid));          pid_delete(pid);
                 pid_regist(pid);          return 1;
         }      }
         return pid;      return 0;
 }  }
   
 void sm_mathcap(OXFILE *oxfp)  /* Killing all child processes */
   static void pid_kill_all()
 {  {
         cmo_mathcap *m = pop();      while(pid_ptr > 0) {
         if (m->tag == CMO_MATHCAP) {          kill(pids[--pid_ptr], SIGKILL);
                 oxf_mathcap_update(oxfp, m);      }
         }else {  
                 push_error(-1, m);  
                 /* an error object must be pushed */  
         }  
 }  }
   
 void sm_control_kill(OXFILE *oxfp)  cmo_error2 *type_checker(cmo *ob, int type)
 {  {
         cmo_int32 *m = pop();  /*  cmo_error2 *err_ob; */
         int pid = m->i;      if (ob->tag != type) {
         if (m->tag != CMO_INT32 || !pid_registed(pid)) {          /* push and return an error object */
                 push_error(-1, m);      }
         }else {      return NULL;
                 kill(pid, SIGKILL);  
                 pid_delete(pid);  
         }  
 }  }
   
 void sm_control_reset(OXFILE *oxfp)  int lf_oxc_open()
 {  {
         cmo_int32 *m = pop();      cmo_int32 *argc = (cmo_int32 *)pop();
         int pid = m->i;          if (argc->tag == CMO_INT32 && argc->i == 1) {
         if (m->tag != CMO_INT32 || !pid_registed(pid)) {                  return sm_control_spawn();
                 push_error(-1, m);  
         }else {  
                 kill(pid, SIGUSR1);  
         }          }
           push_error(-1, (cmo *)argc);
           return -1;
 }  }
   
 void sm_control_start_engin(OXFILE *oxfp);  int sm_control_spawn_typecheck(cmo_list *args, int *portp, char **s)
   {
       cmo_int32 *port;
       cmo_string *name;
   
 static int intcmp(int key1, int key2)      if( IS_CMO_LIST_LEN(args,2) ) {
           name = (cmo_string *)list_nth(args, 1);
           args = (cmo_list *)list_first_cmo(args);
           if( IS_CMO_STRING(name) && IS_CMO_LIST_LEN(args,1) ) {
               port   = (cmo_int32 *)list_first_cmo(args);
               if( IS_CMO_INT32(port) && name->s && which(name->s, getenv("PATH")) != NULL) {
                   *portp = port->i;
                   *s     = name->s;
                   return 1;
               }
           }
       }
       return 0;
   }
   
   static int sm_control_spawn()
 {  {
     return key1 != key2;      int port;
       char *s;
       pid_t pid;
       cmo *args = pop();
   
       if (sm_control_spawn_typecheck((cmo_list *)args, &port, &s)) {
           pid = lf_oxc_open_main(s, (short)port);
           if (pid > 0) {
               push((cmo *)new_cmo_int32(pid));
               pid_register(pid);
               ox_printf("oxc: spawns %s\n", s);
               return pid;
           }
       }
       push_error(-1, (cmo *)args);
       return 0;
 }  }
   
   int sm_mathcap()
   {
       push((cmo *)oxf_cmo_mathcap(stack_oxfp));
       return 0;
   }
   
 int (*sm_search_f(int code))()  int sm_set_mathcap()
 {  {
     return db_search(code, db_sm, intcmp);      cmo_mathcap *m = (cmo_mathcap *)pop();
       if (m->tag == CMO_MATHCAP) {
           oxf_mathcap_update(stack_oxfp, m);
       }else {
           push_error(-1, (cmo *)m);
           /* an error object must be pushed */
       }
       return 0;
   }
   
   static int sm_control_kill()
   {
       pid_kill_all();
       return 0;
   }
   
   static int sm_control_terminate()
   {
       cmo_int32 *m = (cmo_int32 *)pop();
       pid_t pid = m->i;
       if (m->tag != CMO_INT32 || !pid_kill(pid)) {
           push_error(-1, (cmo *)m);
       }
       return 0;
   }
   
   static int 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, (cmo *)m);
           return 0;
       }
       /* ... */
       return 0;
 }  }

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.12

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