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