Пример #1
0
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);
    }
}
Пример #2
0
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);
}
Пример #3
0
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;
}
Пример #4
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;
		}