static void child_died(struct context *ctx, int cur __attribute__ ((unused))) { if (ctx->ac) { // might be called multiple times else int i = ctx->index; DebugIn(DEBUG_PROC); if (ctx->mcx->cx[i]->counter < 2) { logmsg("%s: %lu: terminated before finishing first request", ctx->mcx->argv[0], (u_long) ctx->pid); ctx->mcx->reaphist[ctx->mcx->reapcur] = io_now.tv_sec + REAPINT; ctx->mcx->reapcur++; ctx->mcx->reapcur %= REAPMAX; ctx->mcx->usage--; } else logmsg("%s: %lu: terminated after processing %llu requests", ctx->mcx->argv[0], (u_long) ctx->pid, ctx->mcx->cx[i]->counter); ctx->mcx->cx[i]->counter = 0; io_child_set(ctx->pid, NULL, NULL); if (ctx->fd_in > -1) { io_close(ctx->mcx->io, ctx->fd_in); ctx->fd_in = -1; } if (ctx->fd_out > -1) { io_close(ctx->mcx->io, ctx->fd_out); ctx->fd_out = -1; } ctx->index = -1; RB_insert(ctx->mcx->junkcontexts, ctx); #ifdef DEBUG_RB fprintf(stderr, "EXT insert junkcontexts %p\n", ctx); #endif ctx->mcx->cx[i] = NULL; ctx->mcx->child_cur--; fork_child(ctx->mcx, i); if (ctx->mcx->cx[i]) { ctx->mcx->cx[i]->ac = ctx->ac; ctx->ac = NULL; ctx->mcx->cx_stat[i].counter++; ctx->mcx->cx_stat[i].counter_p++; start_query(ctx->mcx->cx[i]); } DebugOut(DEBUG_PROC); } }
int main(int argc, const char *argv[]) { for (unsigned i=0; i<(unsigned)argc; i++) { if (stricmp(argv[i], "--help")==0 || stricmp(argv[i], "-h")==0) { roxie_server_usage(); return EXIT_SUCCESS; } } return start_query(argc, argv); }
int main(int argc, char **argv) { LOGINREC *login; DBPROCESS *dbproc; int i; char teststr[1024]; DBINT testint; DBVARYBIN testvbin; DBVARYCHAR testvstr; int failed = 0; int expected_error; set_malloc_options(); read_login_info(argc, argv); fprintf(stdout, "Starting %s\n", argv[0]); dbinit(); dberrhandle(syb_err_handler); dbmsghandle(syb_msg_handler); fprintf(stdout, "About to logon\n"); login = dblogin(); DBSETLPWD(login, PASSWORD); DBSETLUSER(login, USER); DBSETLAPP(login, "t0007"); fprintf(stdout, "About to open\n"); dbproc = dbopen(login, SERVER); if (strlen(DATABASE)) dbuse(dbproc, DATABASE); dbloginfree(login); create_tables(dbproc, 10); if (!start_query(dbproc)) { fprintf(stderr, "%s:%d: start_query failed\n", __FILE__, __LINE__); failed = 1; } dbbind(dbproc, 1, INTBIND, 0, (BYTE *) & testint); dbbind(dbproc, 2, STRINGBIND, 0, (BYTE *) teststr); for (i = 1; i <= 2; i++) { char expected[1024]; sprintf(expected, "row %07d", i); if (i % 5 == 0) { dbclrbuf(dbproc, 5); } testint = -1; strcpy(teststr, "bogus"); if (REG_ROW != dbnextrow(dbproc)) { fprintf(stderr, "Failed. Expected a row\n"); abort(); } if (testint != i) { fprintf(stderr, "Failed. Expected i to be %d, was %d\n", i, (int) testint); abort(); } if (0 != strncmp(teststr, expected, strlen(expected))) { fprintf(stdout, "Failed. Expected s to be |%s|, was |%s|\n", expected, teststr); abort(); } printf("Read a row of data -> %d %s\n", (int) testint, teststr); } fprintf(stdout, "second select. Should fail.\n"); expected_error = 20019; dbsetuserdata(dbproc, (BYTE*) &expected_error); if (start_query(dbproc)) { fprintf(stderr, "%s:%d: start_query should have failed but didn't\n", __FILE__, __LINE__); failed = 1; } dbcancel(dbproc); /* * Test Binary binding */ if (!start_query(dbproc)) { fprintf(stderr, "%s:%d: start_query failed\n", __FILE__, __LINE__); failed = 1; } dbbind(dbproc, 1, VARYBINBIND, sizeof(testvbin), (BYTE *) &testvbin); dbbind(dbproc, 2, VARYCHARBIND, sizeof(testvstr), (BYTE *) &testvstr); dbbind(dbproc, 3, BINARYBIND, sizeof(testint), (BYTE *) &testint); for (i = 1; i <= 2; i++) { char expected[1024]; sprintf(expected, "row %07d ", i); testint = -1; memset(&testvbin, '*', sizeof(testvbin)); memset(&testvstr, '*', sizeof(testvstr)); if (REG_ROW != dbnextrow(dbproc)) { fprintf(stderr, "Failed. Expected a row\n"); abort(); } if (testint != i) { fprintf(stderr, "Failed, line %d. Expected i to be %d, was %d (0x%x)\n", __LINE__, i, (int) testint, (int) testint); abort(); } if (testvbin.len != sizeof(testint)) { fprintf(stderr, "Failed, line %d. Expected bin lenght to be %d, was %d\n", __LINE__, (int) sizeof(testint), (int) testvbin.len); abort(); } memcpy(&testint, testvbin.array, sizeof(testint)); if (testint != i) { fprintf(stderr, "Failed, line %d. Expected i to be %d, was %d (0x%x)\n", __LINE__, i, (int) testint, (int) testint); abort(); } if (testvstr.len != strlen(expected) || 0 != strncmp(testvstr.str, expected, strlen(expected))) { fprintf(stdout, "Failed, line %d. Expected s to be |%s|, was |%s|\n", __LINE__, expected, testvstr.str); abort(); } testvstr.str[testvstr.len] = 0; printf("Read a row of data -> %d %s\n", (int) testint, testvstr.str); } dbexit(); fprintf(stdout, "%s %s\n", __FILE__, (failed ? "failed!" : "OK")); return failed ? 1 : 0; }
static void read_from_child(struct context *ctx, int cur) { ssize_t len; DebugIn(DEBUG_MAVIS); len = Read(ctx->fd_in, ctx->b_in + ctx->b_in_len, sizeof(ctx->b_in) - ctx->b_in_len - 1); if (len > 0) { char *t; int matchlevel = 0; Debug((DEBUG_PROC, "%s:%d %s\n", __FILE__, __LINE__, ctx->mcx->path)); ctx->b_in_len += len; ctx->b_in[ctx->b_in_len] = 0; for (t = ctx->b_in + ctx->b_in_len - 1; t > ctx->b_in; t--) switch (matchlevel) { case 0: if (*t != '\n') { DebugOut(DEBUG_MAVIS); return; } matchlevel++; break; case 1: if (!isdigit((int) *t)) { DebugOut(DEBUG_MAVIS); return; } matchlevel++; break; case 2: if (!isdigit((int) *t) && *t != '-' && *t != '=') { DebugOut(DEBUG_MAVIS); return; } if (*t == '=') matchlevel++; break; case 3: if (*t == '\n') { rb_node_t *r; struct query *q; char *serial = av_get(ctx->ac, AV_A_SERIAL); char *serial_old = alloca(strlen(serial) + 1); int result; strcpy(serial_old, serial); io_clr_i(ctx->mcx->io, ctx->fd_in); av_clear(ctx->ac); *++t = 0; av_char_to_array(ctx->ac, ctx->b_in, NULL); result = atoi(++t); ctx->in_use = 0; ctx->mcx->usage--; serial = av_get(ctx->ac, AV_A_SERIAL); if (!serial || strcmp(serial, serial_old)) { if (serial) logmsg("%s: %lu: out of sync: " "got %s, expected %s. Terminating.", ctx->mcx->argv[0], (u_long) ctx->pid, serial, serial_old); else logmsg("%s: %lu: missing serial. Terminating.", ctx->mcx->argv[0], (u_long) ctx->pid); av_free(ctx->ac); ctx->ac = NULL; kill(ctx->pid, SIGTERM); child_died(ctx, ctx->fd_in); DebugOut(DEBUG_MAVIS); return; } q = Xcalloc(1, sizeof(struct context)); q->ac = ctx->ac; ctx->ac = NULL; q->result = result; q->canceled = ctx->canceled; ctx->canceled = 0; RB_insert(ctx->mcx->outgoing, q); #ifdef DEBUG_RB fprintf(stderr, "EXT insert outgoing %p\n", q); #endif if (ctx->mcx->io_context_parent) { if (!RB_empty(ctx->mcx->backlog_fifo)) { rb_node_t *rbn = RB_first(ctx->mcx->backlog_fifo); struct query *qp = RB_payload(rbn, struct query *); Debug((DEBUG_PROC, "%s:%d\n", __FILE__, __LINE__)); RB_search_and_delete(ctx->mcx->backlog_app_ctx, qp); RB_search_and_delete(ctx->mcx->backlog_serial, qp); ctx->ac = qp->ac; qp->ac = NULL; RB_delete(ctx->mcx->backlog_fifo, rbn); #ifdef DEBUG_RB fprintf(stderr, "EXT remove backlog_fifo %p\n", RB_payload(rbn, void *)); #endif ctx->mcx->backlog_cur--; ctx->mcx->usage++; ctx->mcx->cx_stat[ctx->index].counter++; ctx->mcx->cx_stat[ctx->index].counter_p++; start_query(ctx); } while ((r = RB_first(ctx->mcx->outgoing))) { struct query *qp = RB_payload(r, struct query *); if (ctx->mcx->ac_bak) av_free(ctx->mcx->ac_bak); ctx->mcx->ac_bak = qp->ac_bak; qp->ac_bak = NULL; if (q->canceled) { av_free(ctx->mcx->ac_bak); ctx->mcx->ac_bak = NULL; RB_delete(ctx->mcx->outgoing, r); } else ((void (*)(void *)) qp->ac->app_cb) (qp->ac->app_ctx); } } DebugOut(DEBUG_MAVIS); return; }