Annotation of OpenXM/src/oxc/sm_ext.c, Revision 1.11
1.1 ohara 1: /* -*- mode: C; coding: euc-japan -*- */
1.11 ! ohara 2: /* $OpenXM: OpenXM/src/oxc/sm_ext.c,v 1.10 2003/05/07 04:00:30 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);
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.11 ! ohara 44: {NULL, 0}
1.1 ohara 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;
1.11 ! ohara 52: for (i=0; tbl_smcmd[i].key != 0; i++) {
1.8 ohara 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.11 ! ohara 76: int 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.11 ! ohara 85: return 0;
1.4 ohara 86: }
1.1 ohara 87: }
88: }
1.4 ohara 89: push_error(retcode, ob);
1.11 ! ohara 90: return 0;
1.1 ohara 91: }
92:
93: /* getargs() set number of popped objects to argc. */
94: static int getargs(cmo ***args)
95: {
96: cmo **argv;
97: int i;
98: int argc = -1;
1.4 ohara 99: cmo_int32 *m = (cmo_int32 *)pop();
1.1 ohara 100:
101: if (m->tag != CMO_INT32 || (argc = m->i) < 0) {
1.10 ohara 102: ox_printf("oxc: invalid arguments\n");
1.1 ohara 103: }else {
104: argv = (cmo **)malloc(sizeof(cmo *)*argc);
105: for(i=0; i<argc; i++) {
106: argv[i] = pop();
107: }
108: *args = argv;
109: }
1.4 ohara 110: return argc;
1.1 ohara 111: }
112:
1.5 ohara 113: #define MAX_PROCESS 1024
114:
1.6 ohara 115: /* Process Table */
1.5 ohara 116: static pid_t *pids = NULL;
1.1 ohara 117: static int pid_ptr = 0;
1.5 ohara 118: static int pid_size = 0;
119:
1.6 ohara 120: static void pids_extend()
1.5 ohara 121: {
122: int size2 = pid_size + MAX_PROCESS;
123: pid_t *pids2 = (pid_t *)malloc(sizeof(pid_t)*size2);
124: if (pids != NULL) {
125: memcpy(pids2, pids, sizeof(pid_t)*pid_size);
126: free(pids);
127: }
128: pid_size = size2;
129: pids = pids2;
130: }
1.1 ohara 131:
1.8 ohara 132: static int pid_lookup(pid_t pid)
1.2 ohara 133: {
1.4 ohara 134: int i;
135: for(i=0; i<pid_ptr; i++) {
136: if (pids[i] == pid) {
137: return i;
138: }
139: }
140: return -1;
1.2 ohara 141: }
142:
1.8 ohara 143: static int pid_registed(pid_t pid)
1.2 ohara 144: {
1.4 ohara 145: return pid_lookup(pid)+1;
1.2 ohara 146: }
147:
1.8 ohara 148: static void pid_regist(pid_t pid)
1.1 ohara 149: {
1.5 ohara 150: if (pid_ptr >= pid_size) {
1.8 ohara 151: pids_extend();
1.4 ohara 152: }
1.8 ohara 153: pids[pid_ptr++] = pid;
1.1 ohara 154: }
155:
1.8 ohara 156: static void pid_delete(pid_t pid)
1.2 ohara 157: {
1.4 ohara 158: int i = pid_lookup(pid);
159: if (i >= 0 && i != --pid_ptr) {
160: pids[i] = pids[pid_ptr];
161: }
1.2 ohara 162: }
163:
1.8 ohara 164: static int pid_reset(pid_t pid)
165: {
166: if (pid_registed(pid)) {
167: kill(pid, SIGUSR1);
168: return 1;
169: }
170: return 0;
171: }
172:
173: static int pid_kill(pid_t pid)
1.5 ohara 174: {
1.8 ohara 175: if (pid_registed(pid)) {
176: kill(pid, SIGKILL);
177: pid_delete(pid);
178: return 1;
179: }
180: return 0;
1.5 ohara 181: }
182:
183: /* Killing all child processes */
1.8 ohara 184: static void pid_kill_all()
1.5 ohara 185: {
1.8 ohara 186: while(pid_ptr > 0) {
1.5 ohara 187: kill(pids[--pid_ptr], SIGKILL);
1.8 ohara 188: }
1.5 ohara 189: }
190:
1.6 ohara 191: cmo_error2 *type_checker(cmo *ob, int type)
192: {
1.8 ohara 193: /* cmo_error2 *err_ob; */
194: if (ob->tag != type) {
195: /* push and return an error object */
196: }
197: return NULL;
1.6 ohara 198: }
199:
1.1 ohara 200: int lf_oxc_open()
201: {
1.11 ! ohara 202: cmo_int32 *argc = (cmo_int32 *)pop();
1.9 ohara 203: if (argc->tag == CMO_INT32 && argc->i == 1) {
204: return sm_control_spawn();
205: }
1.11 ! ohara 206: push_error(-1, (cmo *)argc);
1.9 ohara 207: return -1;
208: }
209:
210: int sm_control_spawn_typecheck(cmo_list *args, cmo_list *ports, cmo_int32 *port, cmo_string *sname)
211: {
212: char *cmd = sname->s;
213:
214: return args->tag == CMO_LIST
215: && list_length(args) > 1
216: && ports->tag == CMO_LIST
217: && list_length(ports) > 0
218: && port->tag == CMO_INT32
219: && sname->tag == CMO_STRING
220: && cmd != NULL
221: && which(cmd, getenv("PATH")) != NULL;
1.6 ohara 222: }
223:
1.8 ohara 224: static int sm_control_spawn()
1.6 ohara 225: {
1.11 ! ohara 226: cmo_list *args = (cmo_list *)pop();
! 227: cmo_list *ports = (cmo_list *)list_first_cmo(args);
! 228: cmo_int32 *port = (cmo_int32 *)list_first_cmo(ports);
! 229: cmo_string *sname = (cmo_string *)list_nth(args, 1);
1.9 ohara 230: pid_t pid;
231:
232: if (sm_control_spawn_typecheck(args, ports, port, sname)) {
1.11 ! ohara 233: pid = lf_oxc_open_main(sname->s, (short)port->i);
1.9 ohara 234: if (pid > 0) {
1.11 ! ohara 235: push((cmo *)new_cmo_int32(pid));
1.9 ohara 236: pid_regist(pid);
1.10 ohara 237: ox_printf("oxc: spawns %s\n", sname->s);
1.9 ohara 238: return pid;
239: }
240: }
1.11 ! ohara 241: push_error(-1, (cmo *)args);
1.9 ohara 242: return 0;
1.1 ohara 243:
244: }
245:
1.11 ! ohara 246: int sm_mathcap()
1.1 ohara 247: {
1.6 ohara 248: push((cmo *)oxf_cmo_mathcap(stack_oxfp));
1.11 ! ohara 249: return 0;
1.4 ohara 250: }
251:
1.11 ! ohara 252: int sm_set_mathcap()
1.4 ohara 253: {
254: cmo_mathcap *m = (cmo_mathcap *)pop();
255: if (m->tag == CMO_MATHCAP) {
1.6 ohara 256: oxf_mathcap_update(stack_oxfp, m);
1.4 ohara 257: }else {
1.11 ! ohara 258: push_error(-1, (cmo *)m);
1.4 ohara 259: /* an error object must be pushed */
260: }
1.11 ! ohara 261: return 0;
1.1 ohara 262: }
1.2 ohara 263:
1.11 ! ohara 264: static int sm_control_kill()
1.2 ohara 265: {
1.8 ohara 266: pid_kill_all();
1.11 ! ohara 267: return 0;
1.5 ohara 268: }
269:
1.11 ! ohara 270: static int sm_control_terminate()
1.5 ohara 271: {
1.4 ohara 272: cmo_int32 *m = (cmo_int32 *)pop();
1.5 ohara 273: pid_t pid = m->i;
274: if (m->tag != CMO_INT32 || !pid_kill(pid)) {
1.11 ! ohara 275: push_error(-1, (cmo *)m);
1.4 ohara 276: }
1.11 ! ohara 277: return 0;
1.2 ohara 278: }
279:
1.11 ! ohara 280: static int sm_control_reset_pid()
1.2 ohara 281: {
1.4 ohara 282: cmo_int32 *m = (cmo_int32 *)pop();
1.5 ohara 283: pid_t pid = m->i;
284: if (m->tag != CMO_INT32 || !pid_reset(pid)) {
1.11 ! ohara 285: push_error(-1, (cmo *)m);
! 286: return 0;
1.4 ohara 287: }
1.8 ohara 288: /* ... */
1.11 ! ohara 289: return 0;
1.1 ohara 290: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>