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