Exemple #1
0
/*
 * Forking is a relatively cheap way to create a new client.  The new
 * client record shares the IO descriptors.  To avoid interference, we
 * limit children to only produce output by closing the input-side.
 *
 * If the father itself is a temporary client, let the new child depend
 * on the grandfather.
 */
Client
MCforkClient(Client father)
{
	Client son = NULL;
	str prompt;

	if (father == NULL)
		return NULL;
	if (father->father != NULL)
		father = father->father;
	if((prompt = GDKstrdup(father->prompt)) == NULL)
		return NULL;
	if ((son = MCinitClient(father->user, father->fdin, father->fdout))) {
		son->fdin = NULL;
		son->fdout = father->fdout;
		son->bak = NULL;
		son->yycur = 0;
		son->father = father;
		son->scenario = father->scenario;
		if (son->prompt)
			GDKfree(son->prompt);
		son->prompt = prompt;
		son->promptlength = strlen(prompt);
		/* reuse the scopes wherever possible */
		if (son->usermodule == 0) {
			son->usermodule = userModule();
			if(son->usermodule == 0) {
				MCcloseClient(son);
				return NULL;
			}
		}
	} else {
		GDKfree(prompt);
	}
	return son;
}
Exemple #2
0
/*
 * This is a phtread started function.  Here we start the client. We
 * need to initialize and allocate space for the global variables.
 * Thereafter it is up to the scenario interpreter to process input.
 */
void
MSserveClient(void *dummy)
{
	MalBlkPtr mb;
	Client c = (Client) dummy;
	str msg = 0;

	if (!isAdministrator(c) && MCinitClientThread(c) < 0) {
		MCcloseClient(c);
		return;
	}
	/*
	 * A stack frame is initialized to keep track of global variables.
	 * The scenarios are run until we finally close the last one.
	 */
	mb = c->curprg->def;
	if (c->glb == NULL)
		c->glb = newGlobalStack(MAXGLOBALS + mb->vsize);
	if (c->glb == NULL) {
		showException(c->fdout, MAL, "serveClient", MAL_MALLOC_FAIL);
		c->mode = FINISHCLIENT + 1; /* == RUNCLIENT */
	} else {
		c->glb->stktop = mb->vtop;
		c->glb->blk = mb;
	}

	if (c->scenario == 0)
		msg = defaultScenario(c);
	if (msg) {
		showException(c->fdout, MAL, "serveClient", "could not initialize default scenario");
		c->mode = FINISHCLIENT + 1; /* == RUNCLIENT */
		GDKfree(msg);
	} else {
		do {
			do {
				runScenario(c);
				if (c->mode == FINISHCLIENT)
					break;
				resetScenario(c);
			} while (c->scenario && !GDKexiting());
		} while (c->scenario && c->mode != FINISHCLIENT && !GDKexiting());
	}
	/* pre announce our exiting: cleaning up may take a while and we
	 * don't want to get killed during that time for fear of
	 * deadlocks */
	MT_exiting_thread();
	/*
	 * At this stage we should clean out the MAL block
	 */
	freeMalBlk(c->curprg->def);
	c->curprg->def = 0;

	if (c->mode > FINISHCLIENT) {
		if (isAdministrator(c) /* && moreClients(0)==0 */) {
			if (c->scenario) {
				exitScenario(c);
			}
		}
	}
	if (!isAdministrator(c))
		MCcloseClient(c);
}