Annotation of OpenXM/src/oxc/sm_ext.c, Revision 1.8
1.1 ohara 1: /* -*- mode: C; coding: euc-japan -*- */
1.8 ! ohara 2: /* $OpenXM: OpenXM/src/oxc/sm_ext.c,v 1.7 2000/12/01 01:53:34 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) {
101: fprintf(stderr, "oxc: invalid arguments\n");
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.8 ! ohara 199: static int sm_control_spawn_main(int argc, cmo *argv[])
1.6 ohara 200: {
201: char *cmd = ((cmo_string *)argv[0])->s;
202: int port = ((cmo_int32 *)argv[1])->i;
203: pid_t pid = lf_oxc_open_main(cmd, port);
204: if (pid > 0) {
205: push(new_cmo_int32(pid));
206: pid_regist(pid);
207: }
208: return pid;
209: }
210:
1.1 ohara 211: int lf_oxc_open()
212: {
213: cmo **argv;
1.8 ! ohara 214: if (getargs(&argv) != 2 ||
! 215: type_checker(argv[0], CMO_STRING) != NULL
! 216: || type_checker(argv[0], CMO_INT32) != NULL) {
1.4 ohara 217: fprintf(stderr, "oxc: invalid arguments\n");
1.1 ohara 218: return -1;
219: }
1.8 ! ohara 220: return sm_control_spawn_main(2, argv);
1.6 ohara 221: }
222:
1.8 ! ohara 223: static int sm_control_spawn()
1.6 ohara 224: {
225: cmo *argv[2];
1.8 ! ohara 226: argv[0] = pop();
! 227: argv[1] = pop();
1.1 ohara 228:
1.8 ! ohara 229: if (type_checker(argv[0], CMO_STRING) != NULL
! 230: || type_checker(argv[0], CMO_INT32) != NULL) {
1.6 ohara 231: fprintf(stderr, "oxc: invalid arguments\n");
232: return -1;
1.4 ohara 233: }
1.8 ! ohara 234: return sm_control_spawn_main(2, argv);
1.1 ohara 235: }
236:
1.6 ohara 237: void sm_mathcap()
1.1 ohara 238: {
1.6 ohara 239: push((cmo *)oxf_cmo_mathcap(stack_oxfp));
1.4 ohara 240: }
241:
1.6 ohara 242: void sm_set_mathcap()
1.4 ohara 243: {
244: cmo_mathcap *m = (cmo_mathcap *)pop();
245: if (m->tag == CMO_MATHCAP) {
1.6 ohara 246: oxf_mathcap_update(stack_oxfp, m);
1.4 ohara 247: }else {
248: push_error(-1, m);
249: /* an error object must be pushed */
250: }
1.1 ohara 251: }
1.2 ohara 252:
1.8 ! ohara 253: static void sm_control_kill()
1.2 ohara 254: {
1.8 ! ohara 255: pid_kill_all();
1.5 ohara 256: }
257:
1.8 ! ohara 258: static void sm_control_terminate()
1.5 ohara 259: {
1.4 ohara 260: cmo_int32 *m = (cmo_int32 *)pop();
1.5 ohara 261: pid_t pid = m->i;
262: if (m->tag != CMO_INT32 || !pid_kill(pid)) {
1.4 ohara 263: push_error(-1, m);
264: }
1.2 ohara 265: }
266:
1.8 ! ohara 267: static void sm_control_reset_pid()
1.2 ohara 268: {
1.4 ohara 269: cmo_int32 *m = (cmo_int32 *)pop();
1.5 ohara 270: pid_t pid = m->i;
271: if (m->tag != CMO_INT32 || !pid_reset(pid)) {
1.4 ohara 272: push_error(-1, m);
1.8 ! ohara 273: return;
1.4 ohara 274: }
1.8 ! ohara 275: /* ... */
1.1 ohara 276: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>