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