[BACK]Return to oxserv.c CVS log [TXT][DIR] Up to [local] / OpenXM / src / ox_ntl

Annotation of OpenXM/src/ox_ntl/oxserv.c, Revision 1.9

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>