Annotation of OpenXM/src/ox_ntl/oxserv.c, Revision 1.8
1.8 ! iwane 1: /* $OpenXM: OpenXM/src/ox_ntl/oxserv.c,v 1.7 2004/07/11 00:32:17 iwane Exp $ */
1.1 iwane 2:
3: #include <stdio.h>
4: #include <stdlib.h>
5: #include <string.h>
6: #include <errno.h>
1.2 iwane 7: #include <signal.h>
1.3 iwane 8: #include <setjmp.h>
1.1 iwane 9:
10: #include "oxserv.h"
1.2 iwane 11: #include "oxstack.h"
1.1 iwane 12:
1.7 iwane 13: #include "gmp.h"
1.3 iwane 14: #include "gc/gc.h"
1.1 iwane 15:
1.7 iwane 16: #define DPRINTF(x) printf x; (void)fflush(stdout)
1.1 iwane 17:
1.3 iwane 18: #define FP stdout
1.7 iwane 19: #define EPRINTF(x) fprintf x; (void)fflush(FP)
1.3 iwane 20:
1.1 iwane 21:
1.8 ! iwane 22:
1.1 iwane 23: /*===========================================================================*
1.2 iwane 24: * MACRO
1.1 iwane 25: *===========================================================================*/
1.8 ! iwane 26: #define oxserv_get_cmo_tag(m) ((G_getCmoTag == NULL) ? (m)->tag : G_getCmoTag(m))
! 27:
1.1 iwane 28:
1.8 ! iwane 29: #define oxserv_delete_cmo(C) \
! 30: do { \
! 31: if (C != NULL) { \
! 32: if ((C)->c) { FREE((C)->c); } \
! 33: oxserv_delete_cmo_usr(((C)->p)); \
! 34: free(C); \
! 35: C = NULL; \
! 36: } \
! 37: } while (0)
1.1 iwane 38:
1.8 ! iwane 39: #define oxserv_delete_cmo_usr(c) \
1.2 iwane 40: do { \
1.3 iwane 41: if (c != NULL) { \
42: if (G_DeleteCmo != NULL) \
1.5 iwane 43: G_DeleteCmo((cmo *)c); \
1.3 iwane 44: else \
1.2 iwane 45: c = NULL; \
1.3 iwane 46: } \
1.2 iwane 47: } while (0)
48:
1.1 iwane 49:
50: /*===========================================================================*
1.2 iwane 51: * Global Variables.
1.1 iwane 52: *===========================================================================*/
1.2 iwane 53: /* ox */
54: static OXFILE *G_oxfilep = NULL;
55: static cmo_mathcap *G_oxserv_mathcap = NULL;
1.1 iwane 56:
1.3 iwane 57: /* signal */
1.4 iwane 58: int G_oxserv_sigusr1flag = 0;
59: int G_oxserv_sigusr1cnt = 0;
1.3 iwane 60: static jmp_buf G_jmpbuf;
61:
1.2 iwane 62: /* User Function */
1.8 ! iwane 63: static void (*G_userExecuteFunction)(const char *, oxstack_node **, int) = NULL;
1.2 iwane 64: static void (*G_userExecuteStringParser)(const char *) = NULL;
1.1 iwane 65:
1.8 ! iwane 66: static cmo *(*G_convertCmo)(void *) = NULL; /* convert user object ==> cmo */
! 67: static char *(*G_convertStr)(void *) = NULL; /* convert user object ==> string */
1.1 iwane 68:
1.2 iwane 69: static void (*G_DeleteCmo)(cmo *) = NULL;
1.1 iwane 70:
1.2 iwane 71: static int (*G_getCmoTag)(cmo *) = NULL;
1.1 iwane 72:
1.3 iwane 73:
74: /*===========================================================================*
75: * CMO_ERROR2
76: *===========================================================================*/
77: #define new_cmo_error2_string(msg) new_cmo_error2((cmo *)new_cmo_string(msg))
78:
79:
80: static void
81: oxserv_push_errormes(char *msg)
82: {
83: EPRINTF((FP, "%s\n", msg));
1.8 ! iwane 84: oxstack_push_cmo((cmo *)new_cmo_error2_string(msg));
1.3 iwane 85: }
86:
87: /*===========================================================================*
88: * synchronized malloc
89: *===========================================================================*/
90: void *
91: oxserv_malloc(size_t size)
92: {
93: void *ptr;
94:
95: BLOCK_INPUT();
96: ptr = GC_malloc(size);
97: UNBLOCK_INPUT();
98:
99: return (ptr);
100: }
101:
102: void
103: oxserv_free(void *ptr, size_t size)
104: {
105: /* nothing */
106: }
107:
108: void *
109: oxserv_realloc(void *org, size_t old, size_t size)
110: {
111: void *ptr;
112:
113: BLOCK_INPUT();
114: ptr = GC_realloc(org, size);
115: UNBLOCK_INPUT();
116:
117: return (ptr);
118: }
119:
120:
121:
1.1 iwane 122: /*===========================================================================*
123: * OX_SERVER
124: *===========================================================================*/
125:
126: /*****************************************************************************
1.2 iwane 127: * -- SM_popCMO --
128: * pop an object from the stack, convert it into a serialized from according
129: * to the standard CMO encoding scheme, and send it to the stream
130: *
1.1 iwane 131: * PARAM : fd : OXFILE
132: * RETURN: NONE
133: *****************************************************************************/
134: static void
135: oxserv_sm_popCMO(OXFILE *fd)
136: {
1.8 ! iwane 137: cmo *m;
! 138: oxstack_node *p;
! 139: int flag = 0;
! 140: p = oxstack_pop();
! 141: if (p == NULL) {
1.3 iwane 142: EPRINTF((FP, "stack underflow in popCMO\n"));
1.1 iwane 143: m = new_cmo_null();
1.8 ! iwane 144: /* asir $B$NF0$-$K=>$&(B */
! 145: } else {
! 146: if (p->c != NULL) {
! 147: m = p->c;
! 148: } else if (p->p != NULL) {
! 149: if (G_convertCmo) {
! 150: m = G_convertCmo(p->p);
! 151: } else {
! 152: m = NULL;
! 153: }
! 154: if (m == NULL) {
! 155: m = (cmo *)new_cmo_error2((cmo *)new_cmo_string("convert failed"));
! 156: flag = 1;
! 157:
! 158: }
! 159: } else {
! 160: EPRINTF((FP, "converter not defined\n"));
! 161: m = (cmo *)new_cmo_error2((cmo *)new_cmo_string("converter not defined"));
! 162: flag = 1;
! 163: }
! 164:
! 165: if (flag) {
! 166: /*
! 167: * $B$;$C$+$/7k2L$,$"$k$N$K>C$7$F$7$^$&$N$O(B
! 168: * $B$b$C$?$$$J$$$N$G;D$9$3$H$K$9$k(B.
! 169: */
! 170: oxstack_push(p);
! 171: } else {
! 172: oxserv_delete_cmo(p);
1.4 iwane 173: }
1.1 iwane 174: }
175:
1.8 ! iwane 176:
1.1 iwane 177: send_ox_cmo(fd, m);
178:
1.8 ! iwane 179: FREE(m);
1.1 iwane 180: }
181:
182: /*****************************************************************************
1.2 iwane 183: * -- SM_popString --
1.1 iwane 184: * pop an cmo from stack, convert it into a string according to the
185: * output format of the local system, and send the string.
1.2 iwane 186: *
1.1 iwane 187: * PARAM : fd : OXFILE
188: * RETURN: NONE
189: *****************************************************************************/
190: static void
191: oxserv_sm_popString(OXFILE *fd)
192: {
193: char *str;
1.8 ! iwane 194: oxstack_node *p;
! 195: cmo *m;
1.1 iwane 196: cmo_string *m_str;
197:
1.8 ! iwane 198: p = oxstack_pop();
! 199: if (p == NULL) {
! 200: /* @@TODO
! 201: * http://www.math.kobe-u.ac.jp/OpenXM/1.2.1/html/OpenXM-ja/OpenXM/node12.html
! 202: * $B%9%?%C%/$,6u$N>l9g$K$O(B (char *)NULL $B$rJV$9(B.
! 203: * CMO $B$NMQ8l$G=q$+$l$F$$$J$$$+$i2?$rJV$9$Y$-$+$o$+$i$J$$(B.
! 204: */
1.1 iwane 205: m = new_cmo_null();
1.8 ! iwane 206: str = new_string_set_cmo(m);
! 207: } else {
! 208: if (p->c) {
! 209: m = NULL;
! 210: str = new_string_set_cmo(p->c);
! 211: } else if (p->p) {
! 212: if (G_convertStr) {
! 213: str = G_convertStr(p->p);
! 214: m = NULL;
! 215: } else {
! 216: if (G_convertCmo) {
! 217: m = G_convertCmo(p->p);
! 218: } else {
! 219: /* @@TODO
! 220: * $BJQ49$G$-$J$$>l9g$O(B... CMO_ERROR2 $B$rLa$9$Y$-$G$"$k(B?
! 221: * $B$=$N$H$-$N(B stack $B$N>uBV$O$I$&$9$Y$-!)(B
! 222: */
! 223: m = NULL;
! 224: }
! 225: str = new_string_set_cmo(m);
! 226: }
! 227: } else {
! 228: m = new_cmo_null();
! 229: str = new_string_set_cmo(m);
! 230: }
! 231:
! 232: oxserv_delete_cmo(p);
1.3 iwane 233: }
1.1 iwane 234:
235: m_str = new_cmo_string(str);
236:
237: send_ox_cmo(fd, (cmo *)m_str);
238:
1.8 ! iwane 239: FREE(m);
! 240: FREE(m_str);
1.1 iwane 241:
1.2 iwane 242: /* free(str); */
1.1 iwane 243: }
244:
245: /*****************************************************************************
1.2 iwane 246: * -- SM_pops --
1.1 iwane 247: * pop n and to discard element from the stack
1.2 iwane 248: *
249: * PARAM : NONE
1.1 iwane 250: * RETURN: NONE
251: *****************************************************************************/
252: static void
253: oxserv_sm_pops()
254: {
1.8 ! iwane 255: oxstack_node *p, *m;
1.1 iwane 256: cmo_int32 *c;
1.2 iwane 257: int n;
258: int i;
259:
1.8 ! iwane 260: p = oxstack_pop();
! 261: if (p == NULL) {
! 262: EPRINTF((FP, "stack underflow in pops\n"));
! 263: return ;
! 264: }
! 265:
! 266: c = (cmo_int32 *)p->c; /* suppose */
1.3 iwane 267: if (c == NULL) {
268: EPRINTF((FP, "stack underflow in pops\n"));
269: return ;
270: }
1.1 iwane 271:
1.2 iwane 272: n = oxstack_get_stack_pointer();
273: if (c->i < n)
274: n = c->i;
1.1 iwane 275:
1.2 iwane 276: for (i = 0; i < n; i++) {
277: m = oxstack_pop();
278: oxserv_delete_cmo(m);
279: }
280:
1.8 ! iwane 281: oxserv_delete_cmo(p);
1.1 iwane 282:
283: }
284:
285: /*****************************************************************************
1.2 iwane 286: * -- SM_getsp --
287: * push the current stack pointer onto the stack.
1.1 iwane 288: *
289: * PARAM : fd : OXFILE
290: * RETURN: NONE
291: *****************************************************************************/
292: static void
293: oxserv_sm_getsp()
294: {
1.2 iwane 295: cmo_int32 *m = new_cmo_int32(oxstack_get_stack_pointer());
1.8 ! iwane 296: oxstack_push_cmo((cmo *)m);
1.1 iwane 297: }
298:
299: /*****************************************************************************
300: *
301: * PARAM : ver :
302: * : vstr :
303: * : sysname:
304: * : cmos :
305: * : sms :
306: * RETURN: NONE
307: * SEE : oxserv_set();
308: *****************************************************************************/
309: static void
310: oxserv_mathcap_init(int ver, char *vstr, char *sysname, int *cmos, int *sms)
311: {
312: int i;
313:
314: int local_sms[] = {
315: SM_popCMO,
316: SM_mathcap,
317: SM_setMathCap,
318: SM_pops,
319: SM_getsp,
320: SM_popString,
321: SM_pushCMOtag,
322: 0,
323: SM_executeFunction,
324: SM_dupErrors,
325: SM_executeStringByLocalParser,
326: SM_executeStringByLocalParserInBatchMode,
327: SM_shutdown,
328: 0,
329: };
330:
331: /* depend on ox_toolkit */
332: int local_cmos[] = {
333: CMO_ERROR2,
334: CMO_NULL,
335: CMO_INT32,
336: CMO_STRING,
337: CMO_MATHCAP,
338: CMO_LIST,
339: CMO_MONOMIAL32,
340: CMO_ZZ,
341: CMO_ZERO,
342: CMO_RECURSIVE_POLYNOMIAL,
343: CMO_DISTRIBUTED_POLYNOMIAL,
344: CMO_POLYNOMIAL_IN_ONE_VARIABLE,
345: CMO_DMS_GENERIC,
346: CMO_RING_BY_NAME,
347: CMO_INDETERMINATE,
348: CMO_TREE,
349: CMO_LAMBDA,
350: 0,
351: CMO_QQ,
352: CMO_ATTRIBUTE_LIST,
353: CMO_DMS,
354: CMO_DMS_OF_N_VARIABLES,
355: CMO_LIST_R,
356: CMO_INT32COEFF,
357: CMO_RATIONAL,
358: CMO_DATUM,
359: 0,
360: };
361:
362: if (sms == NULL) {
363: sms = local_sms;
364:
365: for (i = 0; sms[i] != 0; i++)
366: ;
367: if (G_userExecuteFunction != NULL)
368: sms[i++] = SM_executeFunction;
369:
370: if (G_userExecuteStringParser != NULL) {
371: sms[i++] = SM_executeStringByLocalParser;
372: sms[i++] = SM_executeStringByLocalParserInBatchMode;
373: }
374:
375: sms[i] = 0;
376: }
377: if (cmos == NULL)
378: cmos = local_cmos;
379:
380: mathcap_init(ver, vstr, sysname, cmos, sms);
381:
1.8 ! iwane 382: if (G_oxserv_mathcap) {
! 383: FREE(G_oxserv_mathcap);
! 384: }
1.1 iwane 385:
386: G_oxserv_mathcap = mathcap_get(new_mathcap());
387: }
388:
1.2 iwane 389: /*****************************************************************************
390: * -- SM_mathcap --
391: * push the mathcap of the server.
392: *
393: * PARAM : NONE
394: * RETURN: NONE
395: *****************************************************************************/
1.1 iwane 396: static void
397: oxserv_sm_mathcap()
398: {
399: if (G_oxserv_mathcap == NULL) {
400: oxserv_mathcap_init(0, "", "oxserv", NULL, NULL);
401: }
402:
1.8 ! iwane 403: oxstack_push_cmo((cmo *)G_oxserv_mathcap);
1.1 iwane 404: }
405:
1.2 iwane 406: /*****************************************************************************
407: * -- SM_executeStringByLocalParserInBatchMode --
408: * peek a character string s, parse it by the local parser of the stack machine,
409: * and interpret by the local interpreter.
410: *
411: * PARAM : NONE
412: * RETURN: NONE
413: *****************************************************************************/
1.1 iwane 414: static void
415: oxserv_sm_executeStringByLocalParserInBatchMode(void)
416: {
1.8 ! iwane 417: oxstack_node *p;
! 418: cmo_string *str;
! 419:
! 420: p = oxstack_peek();
! 421: if (p == NULL) {
! 422: oxserv_push_errormes("stack underflow in executeStringByLocalParserInBatchMode");
! 423: return ;
! 424: }
! 425:
! 426: str = (cmo_string *)p->c;
1.3 iwane 427: if (str == NULL) {
428: oxserv_push_errormes("stack underflow in executeStringByLocalParserInBatchMode");
429: return ;
430: }
1.2 iwane 431: G_userExecuteStringParser(str->s);
1.1 iwane 432: }
433:
1.2 iwane 434: /*****************************************************************************
435: * -- SM_executeStringByLocalParser --
436: * pop a character string s, parse it by the local parser of the stack machine,
437: * and interpret by the local interpreter.
438: *
439: * PARAM : NONE
440: * RETURN: NONE
441: *****************************************************************************/
1.1 iwane 442: static void
443: oxserv_sm_executeStringByLocalParser(void)
444: {
1.8 ! iwane 445: oxstack_node *p;
! 446: cmo_string *str;
! 447:
! 448: p = oxstack_pop();
! 449: if (p == NULL) {
! 450: oxserv_push_errormes("stack underflow in executeStringByLocalParserInBatchMode");
! 451: return ;
! 452: }
! 453:
! 454: str = (cmo_string *)p->c;
1.3 iwane 455: if (str == NULL) {
456: oxserv_push_errormes("stack underflow in executeStringByLocalParser");
457: return ;
458: }
1.2 iwane 459: G_userExecuteStringParser(str->s);
1.8 ! iwane 460: oxserv_delete_cmo(p);
1.1 iwane 461: }
462:
463:
464:
1.2 iwane 465: /*****************************************************************************
466: * -- SM_executeFunction --
467: * pop s as a function name, pop n as the number of arguments and to execute a
468: * local function s with n arguments poped from the stack.
469: *
1.4 iwane 470: * suppose G_userExecuteFunction not equal NULL
471: *
1.2 iwane 472: * PARAM : NONE
473: * RETURN: NONE
474: *****************************************************************************/
1.1 iwane 475: static void
476: oxserv_sm_executeFunction(void)
477: {
478: int i;
1.8 ! iwane 479: oxstack_node *p1, *p2;
! 480: cmo_string *name;
! 481: cmo_int32 *cnt;
! 482: int total;
! 483: oxstack_node **arg;
! 484:
! 485:
! 486: if (G_userExecuteFunction == NULL) {
! 487: oxserv_push_errormes("G_userExecuteFunction not defined");
! 488: return ;
! 489: }
! 490:
! 491:
! 492: p1 = oxstack_pop();
! 493: p2 = oxstack_pop();
! 494:
! 495: name = (cmo_string *)p1->c;
! 496: cnt = (cmo_int32 *)p2->c;
! 497:
1.3 iwane 498:
499:
500: if (name == NULL || cnt == NULL) {
1.8 ! iwane 501: oxserv_push_errormes("stack underflow in executeFunction[name,cnt]");
! 502: return ;
! 503: }
! 504: if (name->tag != CMO_STRING) {
! 505: oxstack_push(p2);
! 506: oxstack_push(p1);
! 507: oxserv_push_errormes("invalid parameter #1 not cmo_string");
! 508: return ;
! 509: }
! 510:
! 511: if (cnt->tag != CMO_INT32) {
! 512: oxstack_push(p2);
! 513: oxstack_push(p1);
! 514: printf("command name=%s\n", name->s);
! 515: oxserv_push_errormes("invalid parameter #2 not cmo_int32");
1.3 iwane 516: return ;
517: }
1.1 iwane 518:
1.8 ! iwane 519: total = cnt->i;
! 520:
! 521: printf("command name=%s, i=%d\n", name->s, total);
! 522: arg = (oxstack_node **)malloc(total * sizeof(oxstack_node *));
! 523: for (i = 0; i < total; i++) {
1.2 iwane 524: arg[i] = oxstack_pop();
1.3 iwane 525: if (arg[i] == NULL) {
526: oxserv_push_errormes("stack underflow in executeFunction");
1.4 iwane 527:
528: for (i--; i >= 0; i--)
529: oxserv_delete_cmo(arg[i]);
530: free(arg);
1.3 iwane 531: return ;
532: }
1.1 iwane 533: }
534:
535: /* user function */
1.8 ! iwane 536: G_userExecuteFunction(name->s, arg, total);
1.1 iwane 537:
538:
1.8 ! iwane 539: for (i = 0; i < total; i++) {
1.2 iwane 540: oxserv_delete_cmo(arg[i]);
1.1 iwane 541: }
542:
1.8 ! iwane 543: oxserv_delete_cmo(p1);
! 544: oxserv_delete_cmo(p2);
1.1 iwane 545: free(arg);
546: }
547:
1.2 iwane 548: /*****************************************************************************
549: * -- SM_pushCMOtag --
550: * push the CMO tag of the top object on the stack.
551: *
1.8 ! iwane 552: *
! 553: *
1.2 iwane 554: * PARAM : NONE
555: * RETURN: NONE
556: *****************************************************************************/
1.1 iwane 557: static void
558: oxserv_sm_pushCMOtag()
559: {
1.8 ! iwane 560: oxstack_node *p = oxstack_peek();
! 561: cmo *c = p->c;
! 562: cmo_int32 *tag;
! 563:
! 564: if (c == NULL) {
! 565: if (p->p != NULL && G_convertCmo) {
! 566: c = p->c = G_convertCmo(p->p);
! 567: }
! 568: }
! 569:
! 570: if (c == NULL) {
! 571: tag = new_cmo_int32(oxserv_get_cmo_tag(c));
! 572: } else {
! 573: tag = (cmo_int32 *)new_cmo_error2_string("convert from MathObj to CMO failed");
! 574: }
! 575: oxstack_push_cmo((cmo *)tag);
1.1 iwane 576: }
577:
578:
1.3 iwane 579: /*****************************************************************************
580: * -- SM_dupErrors --
581: *
582: * PARAM : NONE
583: * RETURN: NONE
584: *****************************************************************************/
1.1 iwane 585: static void
586: oxserv_sm_dupErrors()
587: {
1.8 ! iwane 588: oxstack_node *p;
1.1 iwane 589: cmo_list *list;
590: int i;
591:
592: list = new_cmo_list();
593:
1.2 iwane 594: for (i = 0; i < oxstack_get_stack_pointer(); i++) {
1.8 ! iwane 595: p = oxstack_get(i);
! 596: if (p->c && p->c->tag == CMO_ERROR2) {
! 597: list_append(list, p->c);
1.1 iwane 598: }
599: }
600:
1.8 ! iwane 601: oxstack_push_cmo((cmo *)list);
1.1 iwane 602: }
603:
1.3 iwane 604:
605:
606:
607: /*****************************************************************************
608: * -- SM_control_reset_connection -- signal handler for SIGUSR1 --
609: *
610: * PARAM : NONE
1.4 iwane 611: *
612: * : if (sig == 0) called UNBLOCK_INPUT()
1.3 iwane 613: * RETURN: NONE
614: *****************************************************************************/
1.4 iwane 615: void
1.2 iwane 616: oxserv_sm_control_reset_connection(int sig)
617: {
618: int tag;
619: OXFILE *fd = G_oxfilep;
620:
1.4 iwane 621: if (G_oxserv_sigusr1cnt > 0) {
622: G_oxserv_sigusr1flag = 1;
623: return ;
624: }
625:
626:
1.3 iwane 627: DPRINTF(("reset -- start ==> "));
1.4 iwane 628: G_oxserv_sigusr1flag = 0;
629:
1.2 iwane 630: send_ox_tag(fd, OX_SYNC_BALL);
631:
632: oxstack_init_stack();
633:
634: for (;;) {
635: tag = receive_ox_tag(fd);
1.3 iwane 636: DPRINTF(("[OX:%d=0x%x]", tag, tag));
1.2 iwane 637: if (tag == OX_SYNC_BALL)
638: break;
639: if (tag == OX_DATA)
640: receive_cmo(fd);
1.3 iwane 641: else
642: receive_int32(fd);
1.2 iwane 643: }
1.3 iwane 644: DPRINTF((" <== end.\n"));
645:
1.4 iwane 646:
1.3 iwane 647: longjmp(G_jmpbuf, sig);
1.2 iwane 648: }
1.1 iwane 649:
1.3 iwane 650: /*****************************************************************************
651: * execute sm command
652: *
653: * PARAM : NONE
654: * RETURN: NONE
655: *****************************************************************************/
1.1 iwane 656: static int
1.3 iwane 657: oxserv_execute_sm_command(OXFILE *fd, int code)
1.1 iwane 658: {
1.3 iwane 659:
660: DPRINTF(("[SM:%d=0x%x]", code, code));
1.1 iwane 661:
662: switch (code) {
1.3 iwane 663: case SM_popCMO: /* 262 */
1.1 iwane 664: oxserv_sm_popCMO(fd);
665: break;
1.3 iwane 666: case SM_executeStringByLocalParser: /* 268 */
1.1 iwane 667: if (G_userExecuteStringParser)
668: oxserv_sm_executeStringByLocalParser();
669: break;
1.3 iwane 670: case SM_executeStringByLocalParserInBatchMode: /* 274 */
1.1 iwane 671: if (G_userExecuteStringParser)
672: oxserv_sm_executeStringByLocalParserInBatchMode();
673: break;
1.3 iwane 674: case SM_pops: /* 265 */
1.1 iwane 675: oxserv_sm_pops();
676: break;
1.3 iwane 677: case SM_popString: /* 263 */
1.1 iwane 678: oxserv_sm_popString(fd);
679: break;
1.3 iwane 680: case SM_getsp: /* 275 */
1.1 iwane 681: oxserv_sm_getsp();
682: break;
1.3 iwane 683: case SM_mathcap: /* 264 */
1.1 iwane 684: oxserv_sm_mathcap();
685: break;
1.3 iwane 686: case SM_setMathCap: /* 273 */
1.1 iwane 687: /* dont support */
1.2 iwane 688: oxstack_pop();
1.1 iwane 689: break;
1.3 iwane 690: case SM_executeFunction: /* 269 */
1.1 iwane 691: if (G_userExecuteFunction)
692: oxserv_sm_executeFunction();
693: break;
1.3 iwane 694: case SM_pushCMOtag: /* 277 */
1.1 iwane 695: oxserv_sm_pushCMOtag();
696: break;
1.3 iwane 697: case SM_dupErrors: /* 276 */
1.1 iwane 698: oxserv_sm_dupErrors();
699: break;
1.3 iwane 700: case SM_popSerializedLocalObject:
701: case SM_setName:
702: case SM_evalName:
703: case SM_beginBlock:
704: case SM_endBlock:
705: case SM_shutdown:
706: case SM_executeFunctionAndPopCMO:
707: case SM_executeFunctionAndPopSerializedLocalObject:
1.2 iwane 708: case SM_control_reset_connection:
709: case SM_control_reset_connection_server:
1.1 iwane 710: default:
711: break;
712: }
713: return (OXSERV_SUCCESS);
714: }
715:
716:
1.2 iwane 717:
1.1 iwane 718: /*****************************************************************************
719: * reveice ox_data
1.2 iwane 720: *
1.1 iwane 721: * PARAM : fd : OXFILE
722: * RETURN: NONE
723: *****************************************************************************/
1.3 iwane 724: static int
725: oxserv_ox_receive(OXFILE *fd)
1.1 iwane 726: {
727: int tag;
728: cmo *c;
729: int ret = OXSERV_SUCCESS;
1.3 iwane 730: int code;
1.1 iwane 731:
732: tag = receive_ox_tag(fd);
1.8 ! iwane 733: printf("get ox=[%d=0x%x]\n", tag, tag); fflush(stdout);
1.1 iwane 734:
735: switch (tag) {
736: case OX_DATA:
1.4 iwane 737: BLOCK_INPUT();
1.1 iwane 738: c = receive_cmo(fd);
1.4 iwane 739: UNBLOCK_INPUT();
1.3 iwane 740: DPRINTF(("[CMO:%d=0x%x]", c->tag, c->tag));
1.8 ! iwane 741: oxstack_push_cmo(c);
1.1 iwane 742: break;
743:
744: case OX_COMMAND:
1.3 iwane 745: code = receive_int32(fd);
746: ret = oxserv_execute_sm_command(fd, code);
1.1 iwane 747: break;
748:
749: default:
750: DPRINTF(("receive unknown ox_tag: %d=0x%x\n", tag, tag));
751: return (OXSERV_FAILURE);
752: }
753:
754: return (ret);
755: }
756:
1.3 iwane 757: int
758: oxserv_receive(OXFILE *fd)
759: {
760: int i = 0;
761: int ret;
762:
1.8 ! iwane 763:
! 764: /*-----------------------------------------*
! 765: * initialize
! 766: *-----------------------------------------*/
! 767:
1.3 iwane 768: ret = setjmp(G_jmpbuf);
769: if (ret == 0) {
770: DPRINTF(("setjmp first time -- %d\n", ret));
771: } else {
772: DPRINTF(("setjmp return from longjmp() -- %d -- \n", ret));
773: }
774:
1.8 ! iwane 775: /*-----------------------------------------*
! 776: * main loop
! 777: *-----------------------------------------*/
1.3 iwane 778: for (;; i++) {
779: ret = oxserv_ox_receive(fd);
780: if (ret != OXSERV_SUCCESS)
781: break;
782: }
1.8 ! iwane 783:
1.3 iwane 784: return (ret);
785: }
786:
1.1 iwane 787:
788: /*****************************************************************************
789: * initialize oxserver
790: *
791: * PARAM : see oxserv_mathcap_init()
1.2 iwane 792: * RETURN: success : OXSERV_SUCCESS
793: * : failure : OXSERV_FAILURE
1.1 iwane 794: * SEE : oxserv_mathcap_init()
795: * : oxserv_set();
796: *****************************************************************************/
797: int
798: oxserv_init(OXFILE *oxfp, int ver, char *vstr, char *sysname, int *cmos, int *sms)
799: {
800: int ret;
801:
1.3 iwane 802: DPRINTF(("init start\n"));
803:
1.2 iwane 804: ret = oxstack_init_stack();
1.1 iwane 805: if (ret != OXSERV_SUCCESS)
806: return (ret);
807:
1.2 iwane 808: G_oxfilep = oxfp;
809:
1.1 iwane 810: oxserv_mathcap_init(ver, vstr, sysname, cmos, sms);
811:
1.2 iwane 812: signal(SIGUSR1, oxserv_sm_control_reset_connection);
813:
1.3 iwane 814: /* initialize GMP memory functions. */
815: mp_set_memory_functions(oxserv_malloc, oxserv_realloc, oxserv_free);
816:
817: /* session start */
1.1 iwane 818: oxf_determine_byteorder_server(oxfp);
819:
820: return (OXSERV_SUCCESS);
821: }
822:
823:
824: /*****************************************************************************
1.3 iwane 825: * set oxserver behavior
1.2 iwane 826: *
1.1 iwane 827: * PARAM : mode : mode
828: * :
829: * : ptr :
830: * : rsv : reserve space.
1.2 iwane 831: * RETURN: success : OXSERV_SUCCESS
832: * : failure : OXSERV_FAILURE
1.1 iwane 833: * SEE :
834: *****************************************************************************/
835: int
836: oxserv_set(int mode, void *ptr, void *rsv)
837: {
838: switch (mode) {
839: case OXSERV_SET_EXECUTE_FUNCTION:
1.8 ! iwane 840: G_userExecuteFunction = (void (*)(const char *, oxstack_node **, int))ptr;
1.1 iwane 841: break;
842: case OXSERV_SET_EXECUTE_STRING_PARSER:
1.2 iwane 843: G_userExecuteStringParser = (void (*)(const char *))ptr;
1.1 iwane 844: break;
845: case OXSERV_SET_CONVERT_CMO:
1.8 ! iwane 846: G_convertCmo = (cmo *(*)(void *))ptr;
! 847: break;
! 848: case OXSERV_SET_CONVERT_STR:
! 849: G_convertStr = (char *(*)(void *))ptr;
1.1 iwane 850: break;
1.2 iwane 851: case OXSERV_SET_DELETE_CMO:
852: G_DeleteCmo = (void (*)(cmo *))ptr;
853: break;
854: case OXSERV_SET_GET_CMOTAG:
855: G_getCmoTag = (int (*)(cmo *))ptr;
856: break;
1.1 iwane 857: default:
858: return (OXSERV_FAILURE);
859: }
860:
861:
862: return (OXSERV_SUCCESS);
863: }
864:
865:
866: /*****************************************************************************
867: * destroy
1.2 iwane 868: *
869: * PARAM : NONE
1.1 iwane 870: * RETURN: NONE
871: *****************************************************************************/
872: void
873: oxserv_dest()
874: {
1.8 ! iwane 875: FREE(G_oxserv_mathcap);
1.2 iwane 876: oxstack_dest();
1.1 iwane 877: }
878:
879:
1.2 iwane 880: #if __OXSERV_DEBUG
881: /*===========================================================================*
882: * DEBUG
883: *===========================================================================*/
884:
1.1 iwane 885:
1.4 iwane 886: void
1.1 iwane 887: oxserv_executeFunction(const char *func, cmo **arg, int argc)
888: {
889: int i;
890:
891: printf("%s()\n", func);
892:
893: for (i = 0; i < argc; i++) {
894: printf("\t%2d: %s\n", i, new_string_set_cmo(arg[i]));
895: }
896:
1.4 iwane 897: return ;
1.1 iwane 898: }
899:
1.2 iwane 900: /*****************************************************************************
901: * main
902: *
903: * PARAM : NONE
904: * RETURN: NONE
905: *****************************************************************************/
1.8 ! iwane 906: static FILE *dfp = NULL;
1.1 iwane 907: int
908: main(int argc, char *argv[])
909: {
1.8 ! iwane 910: int fd = 10;
1.1 iwane 911: int i;
912: int ret;
913:
1.8 ! iwane 914: dfp = fopen("/tmp/oxserv,log", "w");
1.1 iwane 915: OXFILE *oxfp = oxf_open(fd);
916:
1.8 ! iwane 917: fprintf(dfp, "stderr.init start\n"); fflush(dfp);
! 918: ox_stderr_init(dfp);
1.1 iwane 919:
1.8 ! iwane 920: fprintf(dfp, "set start\n"); fflush(dfp);
1.4 iwane 921: oxserv_set(OXSERV_SET_EXECUTE_FUNCTION, oxserv_executeFunction, NULL);
922:
1.8 ! iwane 923: fprintf(df10p, "init start\n"); fflush(dfp);
1.2 iwane 924: oxserv_init(oxfp, 0, "$Date: 2003/11/02 16:39:16 $", "oxserv", NULL, NULL);
1.1 iwane 925:
1.8 ! iwane 926: fprintf(dfp, "recv start\n"); fflush(dfp);
1.4 iwane 927: ret = oxserv_receive(oxfp);
1.1 iwane 928:
1.4 iwane 929: oxserv_dest();
1.2 iwane 930: oxf_close(oxfp);
1.1 iwane 931:
932: return (0);
933: }
934:
935: #endif
1.2 iwane 936:
937:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>