Ejemplo n.º 1
0
static void cmj_accept_ast(struct CLB *lnk)
{
	struct NTD	*tsk;
	uint4	status;

	tsk = lnk->ntd;
	status = lnk->ios.status;
	if ((status & 1) == 0)
	{
		if (cmj_unit2clb(tsk, lnk->mun) == 0)
		{
			lib$free_vm(&SIZEOF(*lnk), &lnk, 0);
			lnk = 0;
		}
		cmj_mbx_err(status, tsk, lnk);
	}else
	{
		insqhi(lnk, tsk);
		(*tsk->crq)(lnk);
	}

	status = cmj_mbx_read_start(tsk);
	if ((status & 1) == 0)
		cmj_mbx_err(status, tsk, lnk);
}
Ejemplo n.º 2
0
/*
**++
**  ROUTINE:	exit_handler
**
**  FUNCTIONAL DESCRIPTION:
**
**  	Exit handler for the sp_mgr routines.  Closes down the
**  subprocesses and cleans up their SPB context blocks.
**
**  RETURNS:	cond_value, longword (unsigned), write only, by value
**
**  PROTOTYPE:
**
**  	exit_handler(unsigned int *stat, struct QUE *spq)
**
**  IMPLICIT INPUTS:	None.
**
**  IMPLICIT OUTPUTS:	None.
**
**  COMPLETION CODES:
**
**
**  SIDE EFFECTS:   	None.
**
**--
*/
static unsigned int exit_handler (unsigned int *stat, struct QUE *spq) {

    SPHANDLE ctx;

    while(queue_remove(spq->head, &ctx)) {
    	sys$delprc(&ctx->pid, 0);
    	lib$free_ef(&ctx->termefn);
    	lib$free_ef(&ctx->inefn);
    	lib$free_ef(&ctx->outefn);
    	sys$dassgn(ctx->inchn);
    	sys$dassgn(ctx->outchn);
    	lib$free_vm(&ctx->bufsiz, &ctx->bufptr);
    	lib$free_vm(&spb_size, &ctx);
    }

    return SS$_NORMAL;

} /* exit_handler */
Ejemplo n.º 3
0
/*
**++
**  ROUTINE:	free_spd
**
**  FUNCTIONAL DESCRIPTION:
**
**  	Frees an SPD data cell.
**
**  RETURNS:	void
**
**  PROTOTYPE:
**
**  	free_spd(struct SPD *spd)
**
**  IMPLICIT INPUTS:	None.
**
**  IMPLICIT OUTPUTS:	None.
**
**  COMPLETION CODES:	None.
**
**  SIDE EFFECTS:   	None.
**
**--
*/
static void free_spd (struct SPD *spd) {

    unsigned int cellsize;

    cellsize = spd->len + sizeof(struct SPD);
    lib$free_vm(&cellsize, &spd);

    return;

} /* free_spd */
Ejemplo n.º 4
0
/*
**++
**  ROUTINE:	netlib___free_ctx
**
**  FUNCTIONAL DESCRIPTION:
**
**  	Frees a block of memory.
**
**  RETURNS:	void
**
**  PROTOTYPE:
**
**  	netlib___free_ctx(struct CMD *c)
**
**  IMPLICIT INPUTS:	None.
**
**  IMPLICIT OUTPUTS:	None.
**
**  COMPLETION CODES:	None.
**
**  SIDE EFFECTS:   	None.
**
**--
*/
unsigned int netlib___free_ctx (struct CTX *ctx) {

    unsigned int fullsize;

    if (ctx->linebuf != 0) {
    	fullsize = CTX_S_LINEBUF;
    	lib$free_vm(&fullsize, &ctx->linebuf);
    }

    if (ctx->wlinebuf != 0 && ctx->wlinesize != 0) {
    	lib$free_vm(&ctx->wlinesize, &ctx->wlinebuf);
    }

    netlib___free_dns_context(ctx);

    fullsize = ctx->specctx_size + CTX_S_CTXDEF;
    return lib$free_vm(&fullsize, &ctx, &ctxzone);

} /* netlib___free_ctx */
Ejemplo n.º 5
0
/*
**++
**  ROUTINE:	netlib___free_dns_context
**
**  FUNCTIONAL DESCRIPTION:
**
**  	Deallocates the resolver context.
**
**  RETURNS:	cond_value, longword (unsigned), write only, by value
**
**  PROTOTYPE:
**
**  	netlib___free_dns_context(struct CTX *ctx)
**
**  IMPLICIT INPUTS:	None.
**
**  IMPLICIT OUTPUTS:	None.
**
**  COMPLETION CODES:	See code.
**
**  SIDE EFFECTS:   	None.
**
**--
*/
void netlib___free_dns_context (struct CTX *ctx) {

    struct NAMESERVER *ns;
    struct DOMAIN *d;
    unsigned int size;

    if (ctx->dnsctx == 0) return;

    size = sizeof(struct NAMESERVER);
    while (queue_remove(ctx->dnsctx->nsq.head, &ns)) lib$free_vm(&size, &ns);
    while (queue_remove(ctx->dnsctx->domq.head, &d)) {
    	size = sizeof(struct DOMAIN) + d->length;
    	lib$free_vm(&size, &d);
    }

    size = sizeof(struct DNSCTX);
    lib$free_vm(&size, &ctx->dnsctx);
    ctx->dnsctx = 0;

} /* netlib___free_dns_context */
Ejemplo n.º 6
0
/*
**++
**  ROUTINE:	sp_close
**
**  FUNCTIONAL DESCRIPTION:
**
**  	Close down a subprocess.
**
**  RETURNS:	cond_value, longword (unsigned), write only, by value
**
**  PROTOTYPE:
**
**  	sp_close(SPHANDLE *ctxpp)
**
**  IMPLICIT INPUTS:	None.
**
**  IMPLICIT OUTPUTS:	None.
**
**  COMPLETION CODES:
**  	    SS$_NORMAL:	    Normal successful completion.
**
**  SIDE EFFECTS:   	None.
**
**--
*/
unsigned int sp_close (SPHANDLE *ctxpp) {

    SPHANDLE ctx;
    struct SPD *spd;
    unsigned int status;

    ctx = *ctxpp;
/*
** Unlink the context block from our tracking queue
*/
    status = sys$setast(0);
    queue_remove(ctx, &ctx);
    while (queue_remove(ctx->sendque.head, &spd)) free_spd(spd);
    if (status == SS$_WASSET) sys$setast(1);

/*
** Delete the subprocess
*/
    sys$forcex(&ctx->pid, 0, SS$_NORMAL);
    sys$delprc(&ctx->pid, 0);

/*
** Wait till it actually dies
*/
    sys$waitfr(ctx->termefn);

/*
** Clean up and return
*/
    lib$free_ef(&ctx->termefn);
    lib$free_ef(&ctx->inefn);
    lib$free_ef(&ctx->outefn);
    sys$dassgn(ctx->inchn);
    sys$dassgn(ctx->outchn);
    lib$free_vm(&ctx->bufsiz, &ctx->bufptr);
    lib$free_vm(&spb_size, &ctx);
    return SS$_NORMAL;
} /* sp_close */
Ejemplo n.º 7
0
int main() {
    unsigned int initial_values[4] = { 0, 0, 500, 600 };
    URMVM *vm = new_vm();
    URMProgram *program = preconfigure_program_loop((unsigned int*)&initial_values, 4, 1);
    unsigned int results = 0;
    unsigned int *result_registers = NULL;
    FILE *file = fopen("misc/program.txt", "r");
    
    if(file == NULL) {
        printf("Unable to open file!\n");
    }

    parse(program, file);
#if 0
    unsigned int i = 0;
    for(; i < program->instructions; ++i) {
        printf("instruction %u: %d\n", i, program->instruction_list[i]->instruction);
        unsigned int j = 0;
        for(; j < program->instruction_list[i]->args; ++j) {
            printf("arg %u: %d\n", j, program->instruction_list[i]->arg_list[j]);
        }
    }
    
    for(i = 0; i < program->errors; ++i) {
        printf("error: %s\n", program->error_list[i]);
    }
#endif
    if(start_program(vm, program, &result_registers, &results)) {
        printf("Results:\n");
        int i = 0;
        for(; i < results; ++i) {
            printf ("Register %u, result %u\n", i, result_registers[i]);
        }
    } else {
        printf("Error in execution!\n");
    }

    fclose(file);
    free(result_registers);
    free_program(program);
    free(program);
    free_vm(vm);
    free(vm);

    return 0;
}
Ejemplo n.º 8
0
/*
**++
**  ROUTINE:	netlib___alloc_ctx
**
**  FUNCTIONAL DESCRIPTION:
**
**  	Allocates some memory.
**
**  RETURNS:	cond_value
**
**  PROTOTYPE:
**
**  	netlib___alloc_ctx(unsigned int size, void *ptr)
**
**  IMPLICIT INPUTS:	None.
**
**  IMPLICIT OUTPUTS:	None.
**
**  COMPLETION CODES:	None.
**
**  SIDE EFFECTS:   	None.
**
**--
*/
unsigned int netlib___alloc_ctx (struct CTX **ctxp, unsigned int specsize) {

    struct CTX *ctx;
    unsigned int status, fullsize, aststat;

    BLOCK_ASTS(aststat);
    if (netlib_synch_efn == 0xffffffff) {
    	status = lib$get_ef(&netlib_synch_efn);
    	if (!OK(status)) {
    	    UNBLOCK_ASTS(aststat);
    	    return status;
    	}
    }
    if (netlib_asynch_efn == 0xffffffff) {
    	status = lib$get_ef(&netlib_asynch_efn);
    	if (!OK(status)) {
    	    UNBLOCK_ASTS(aststat);
    	    return status;
    	}
    }

    fullsize = specsize + CTX_S_CTXDEF;
    if (ctxzone == 0) {
    	unsigned int algorithm=LIB$K_VM_FIXED;
    	unsigned int flags=LIB$M_VM_GET_FILL0|LIB$M_VM_EXTEND_AREA;
    	status = lib$create_vm_zone(&ctxzone, &algorithm, &fullsize, &flags);
    	if (!OK(status)) {
    	    UNBLOCK_ASTS(aststat);
    	    return status;
    	}
    }

    status = lib$get_vm(&fullsize, &ctx, &ctxzone);
    if (OK(status)) {
    	ctx->specctx = ctx + 1;
    	ctx->specctx_size = specsize;
    	if (!OK(status)) lib$free_vm(&fullsize, &ctx, &ctxzone);
    	*ctxp = ctx;

    }

    UNBLOCK_ASTS(aststat);

    return status;

} /* netlib___alloc_ctx */
Ejemplo n.º 9
0
Archivo: main.c Proyecto: lerno/coil
int main(int argc, const char *argv[])
{
	init_vm();

	switch (argc)
	{
		case 1:
			repl();
			break;
		case 2:
			runFile(argv[1]);
			break;
		default:
			fprintf(stderr, "Usage: coil [path]\n");
			exit(64);
	}
	free_vm();
	return 0;
}
Ejemplo n.º 10
0
int		main(int argc, char **argv)
{
	t_vm	*vm;
	int		dump;

	if (argc > 1)
	{
		if (!(vm = init_vm()))
			exit(write(2, "No memory\n", 10));
		dump = -1;
		parse_args(argc, argv, vm, &dump);
		if (vm->nb_players < 1)
			exit(write(2, "No players\n", 11));
		vm->last_player = vm->players[vm->nb_players - 1]->number;
		load_players_in_memory(vm);
		run_vm(vm, dump);
		print_winner(vm);
		free_vm(vm);
	}
	return (0);
}
Ejemplo n.º 11
0
static void sqlite3MemFree(void *pPrior){
  long *pOld = ((long *)pPrior) - 1, szOld = *pOld + sizeof(int);

  lib$free_vm(&szOld, &pOld, &_sqliteZone_);
}
Ejemplo n.º 12
0
/*
**++
**  ROUTINE:	netlib_connect_by_name
**
**  FUNCTIONAL DESCRIPTION:
**
**  	Connects to a remote host/port by name.  The name is looked up,
**  then a connection is tried to each address until a connection is
**  established, or we run out of addresses.
**
**  RETURNS:	cond_value, longword (unsigned), write only, by value
**
**  PROTOTYPE:
**
**  	NETLIB_CONNECT_BY_NAME  ctxptr, namdsc, port [,iosb] [,astadr] [,astprm]
**
**  ctxptr: 	NETLIB context, longword (unsigned), read only, by reference
**  namdsc: 	char_string, character string, read only, by descriptor
**  port:   	word_unsigned, word (unsigned), read only, by reference
**  iosb:   	io_status_block, quadword (unsigned), write only, by reference
**  astadr: 	ast_procedure, procedure value, call, by reference
**  astprm: 	user_arg, longword (unsigned), read only, by value
**
**  IMPLICIT INPUTS:	None.
**
**  IMPLICIT OUTPUTS:	None.
**
**  COMPLETION CODES:
**  	SS$_NORMAL: 	    normal successful completion
**  	SS$_INSFARG:	    not enough arguments
**  	SS$_BADPARAM:	    invalid argument
**  	Codes from LIB$GET_VM, LIB$ANALYZE_SDESC, and
**  	other NETLIB network status codes.
**
**  SIDE EFFECTS:   	None.
**
**--
*/
unsigned int netlib_connect_by_name (struct CTX **xctx,
    	    	    struct dsc$descriptor *dsc, unsigned short *port,
    	    	    struct NETLIBIOSBDEF *iosb, void (*astadr)(), void *astprm) {

    struct Connect_Context *con;
    struct CTX *ctx;
    struct INADDRDEF addr;
    unsigned int status, size;
    unsigned short namlen;
    char *namp;
    int argc;

/*
**  Verify the arguments
*/
    VERIFY_CTX(xctx, ctx);
    SETARGCOUNT(argc);

    if (argc < 3) return SS$_INSFARG;
    if (dsc == 0 || port == 0) return SS$_BADPARAM;

/*
**  Allocate and fill in the connection context
*/
    status = lib$analyze_sdesc(dsc, &namlen, &namp);
    if (!OK(status)) return status;
    size = namlen + sizeof(struct Connect_Context);
    status = lib$get_vm(&size, &con);
    if (!OK(status)) return status;
    memset(con, 0, size);
    con->name = (char *) (con + 1);
    memcpy(con->name, namp, namlen);
    INIT_SDESC(con->dsc, namlen, con->name);
    con->ctx = ctx;
    con->sin.sin_w_family = NETLIB_K_AF_INET;
    con->sin.sin_w_port = netlib_word_swap(*port);
    con->ctxsize = size;

    size = sizeof(con->htadrlst)/sizeof(con->htadrlst[0]);
    if (argc > 3 && iosb != 0) con->user_iosb = iosb;

    if (argc > 4 && astadr != 0) {
    	con->astadr = astadr;
    	if (argc > 5) con->astprm = astprm;
    }
/*
**  If they provided us with a dotted-decimal IP address, fake
**  out do_connect to make it look like we looked up the address
**  via DNS.
*/
    if (OK(netlib_strtoaddr(&con->dsc, &addr))) {
    	con->iosb.iosb_w_status = SS$_NORMAL;
    	con->nsadrcnt = 1;
    	con->nsadrlst[0] = addr;
    	if (con->astadr != 0) return sys$dclast(do_connect, con, 0);
    	return do_connect(con);
    }

/*
**  Make lookup via host table synchronous and in main-line thread
**  because we can't call it from AST level for all packages
*/
    status = netlib_name_to_address(&con->ctx, &useht, &con->dsc,
    	    	    con->htadrlst, &size, &con->htadrcnt, &con->iosb);
    if (!OK(status)) con->htadrcnt = 0;
    size = sizeof(con->nsadrlst)/sizeof(con->nsadrlst[0]);

/*
**  For an asynch call, do the DNS lookup and have DO_CONNECT invoked
**  as the AST routine
*/
    if (argc > 4 && astadr != 0) {
    	status = netlib_name_to_address(&con->ctx, &usedns, &con->dsc,
    	    	    con->nsadrlst, &size, &con->nsadrcnt, &con->iosb,
    	    	    do_connect, con);
    	if (!OK(status)) lib$free_vm(&con->ctxsize, &con);
    	return status;
    }

/*
**  Synchronous call: do the DNS lookup...
*/
    status = netlib_name_to_address(&con->ctx, &usedns, &con->dsc,
    	    	    con->nsadrlst, &size, &con->nsadrcnt, &con->iosb);

/*
**  ... if it failed, fall back on the host table lookup info we got
*/
    if (!OK(status)) {
    	con->iosb.iosb_w_status = SS$_ENDOFFILE;
    	con->nsadrcnt = 0;
    }

/*
**  Just call DO_CONNECT to complete this for us
*/
    return do_connect(con);

} /* netlib_connect_by_name */
Ejemplo n.º 13
0
/*
**++
**  ROUTINE:	do_connect
**
**  FUNCTIONAL DESCRIPTION:
**
**  	Completion routine for NETLIB_CONNECT_BY_NAME.  Can be
**  invoked as a regular main-line routine or an AST completion.
**
**  RETURNS:	cond_value, longword (unsigned), write only, by value
**
**  PROTOTYPE:
**
**  	DO_CONNECT  connection-context
**
**  IMPLICIT INPUTS:	None.
**
**  IMPLICIT OUTPUTS:	None.
**
**  COMPLETION CODES:	Any NETLIB network status code.
**
**  SIDE EFFECTS:   	None.
**
**--
*/
static unsigned int do_connect (struct Connect_Context *con) {

    unsigned int status;
    int done;

/*
**  We implement our FSM as a loop for the synchronous case
*/
    done = 0;
    while (!done) {

    	status = con->iosb.iosb_w_status;

    	switch (con->state) {

/*
**  Initial state -- if the DNS lookup failed, fall back on host table
**  entry.  Otherwise, start trying the connections.
*/
    	    case 0:
    	    	if (con->nsadrcnt == 0) {
    	    	    if (con->htadrcnt == 0) {
    	    	    	con->iosb.iosb_w_status = SS$_ENDOFFILE;
    	    	    	done = 1;
    	    	    	break;
    	    	    }
    	    	    con->adrlst = con->htadrlst;
    	    	    con->adrcnt = con->htadrcnt;
    	    	} else {
    	    	    con->adrlst = con->nsadrlst;
    	    	    con->adrcnt = con->nsadrcnt;
    	    	}
    	    	con->state = 1;
    	    	/* and fall through */
/*
**  State 1: Attempt a connection
*/
    	    case 1:
    	    	con->sin.sin_x_addr = con->adrlst[con->curadr++];
    	    	con->state = 2;
    	    	status = netlib_connect(&con->ctx, &con->sin, &sinsize,
    	    	    	    &con->iosb, (con->astadr == 0) ? 0 : do_connect,
    	    	    	    	    	(con->astadr == 0) ? 0 : con);
    	    	if (!OK(status)) done = 1;
    	    	else if (con->astadr != 0) return status;
    	    	break;

/*
**  State 2: connect() completion status check.  If we're successful
**  or we've run out of addresses, we're done.  Otherwise, we loop
**  back up and try again.
*/
    	    case 2:
    	    	if (OK(status) || con->curadr >= con->adrcnt) done = 1;
    	    	con->state = 1;
    	    	break;
    	}

    }

/*
**  We're done, one way or another.  Fill in the caller's IOSB and
**  call back the AST, if there was one.
*/
    if (con->user_iosb != 0)
    	memcpy(con->user_iosb, &con->iosb, sizeof(con->iosb));
    if (con->astadr != 0) (*con->astadr)(con->astprm);

/*
**  We're done with this context -- free it
*/
    lib$free_vm(&con->ctxsize, &con);

/*
**  Synchronous completion occurs here.
*/
    return status;

} /* do_connect */
Ejemplo n.º 14
0
/*
**++
**  ROUTINE:	netlib___dns_init
**
**  FUNCTIONAL DESCRIPTION:
**
**  	Initializes an internal DNS resolver context.
**
**  RETURNS:	cond_value, longword (unsigned), write only, by value
**
**  PROTOTYPE:
**
**  	netlib___dns_init(struct CTX *ctx)
**
**  ctx:    NETLIB context, modify, by reference.
**
**  IMPLICIT INPUTS:	None.
**
**  IMPLICIT OUTPUTS:	None.
**
**  COMPLETION CODES:	See code.
**
**  SIDE EFFECTS:   	None.
**
**--
*/
unsigned int netlib___dns_init (struct CTX *ctx) {

    struct DOMAIN *dom;
    unsigned int status;
    ITMLST lnmlst[3];
    int i, maxidx;
    unsigned int size;
    unsigned short buflen;
    char buf[256];
    int did_tmo;

    static unsigned int socktype = NETLIB_K_TYPE_DGRAM;
    static unsigned int ctxsize = sizeof(struct DNSCTX);
    static $DESCRIPTOR(tabnam, "LNM$FILE_DEV");
    static $DESCRIPTOR(lognam, "NETLIB_SEARCH_DOMAIN");
    static $DESCRIPTOR(tmolnm, "NETLIB_DNS_QUERY_TIMEOUT");

/*
**  Allocate the DNS resolver context
*/
    status = lib$get_vm(&ctxsize, &ctx->dnsctx);
    if (!OK(status)) return status;

    INIT_QUEUE(ctx->dnsctx->nsq);
    INIT_QUEUE(ctx->dnsctx->domq);

/*
**  Get the list of name servers we're supposed to contact
*/
    if (netlib___get_nameservers(&ctx->dnsctx->nsq) == 0) {
    	lib$free_vm(&ctxsize, &ctx->dnsctx);
    	ctx->dnsctx = 0;
    	ctx->flags |= CTX_M_NO_DNS;
    	return SS$_UNSUPPORTED;
    }

/*
**  Get the list of NETLIB search domains, or the package-specific
**  ones.
*/
    ITMLST_INIT(lnmlst[0], LNM$_MAX_INDEX, sizeof(maxidx), &maxidx, 0);
    ITMLST_INIT(lnmlst[1], 0, 0, 0, 0);
    if (OK(sys$trnlnm(0, &tabnam, &lognam, 0, lnmlst))) {
    	ITMLST_INIT(lnmlst[0], LNM$_INDEX, sizeof(i), &i, 0);
    	ITMLST_INIT(lnmlst[1], LNM$_STRING, sizeof(buf), buf, &buflen);
    	ITMLST_INIT(lnmlst[2], 0, 0, 0, 0);
    	for (i = 0; i <= maxidx; i++) {
    	    if (OK(sys$trnlnm(0, &tabnam, &lognam, 0, lnmlst)) && buflen != 0) {
    	    	size = buflen + sizeof(struct DOMAIN);
    	    	if (OK(lib$get_vm(&size, &dom))) {
    	    	    dom->length = buflen;
    	    	    memcpy(dom->name, buf, buflen);
    	    	    dom->name[buflen] = '\0';
    	    	    queue_insert(dom, ctx->dnsctx->domq.tail);
    	    	}
    	    }
    	}
    } else if (netlib___get_domain(buf, sizeof(buf), &buflen)) {
    	char *cp, *cp1;
    	int remain;

    	cp = buf;
    	remain = buflen;
/*
**  A search domain must have at least two parts, to avoid the ".com.edu"
**  problem, which is why we check to make sure that the remaining domain
**  string has at least one dot.
*/
    	while (remain > 0) {
    	    cp1 = memchr(cp, '.', remain);
    	    if (cp1 == 0) break;
    	    size = remain + sizeof(struct DOMAIN);
    	    if (OK(lib$get_vm(&size, &dom))) {
    	    	dom->length = remain;
    	    	memcpy(dom->name, cp, remain);
    	    	dom->name[remain] = '\0';
    	    	queue_insert(dom, ctx->dnsctx->domq.tail);
    	    }
    	    remain -= (cp1 - cp) + 1;
    	    cp = cp1 + 1;
    	}
    }

    did_tmo = 0;
    ITMLST_INIT(lnmlst[0], LNM$_STRING, sizeof(buf), buf, &buflen);
    ITMLST_INIT(lnmlst[1], 0, 0, 0, 0);
    if (OK(sys$trnlnm(0, &tabnam, &tmolnm, 0, lnmlst))) {
        struct dsc$descriptor dsc;
        INIT_SDESC(dsc, buflen, buf);
        /*
         *  Make sure it's a delta time value
         */
        if (OK(sys$bintim(&dsc, &ctx->dnsctx->timeout)))
            did_tmo = (int) ctx->dnsctx->timeout.long2 < 0;
    }
    if (!did_tmo)
        sys$bintim(&default_timeout, &ctx->dnsctx->timeout);
            
    ctx->dnsctx->retry_count = 4;

    return SS$_NORMAL;

} /* netlib___dns_init */    
Ejemplo n.º 15
0
/*
**++
**  ROUTINE:	io_completion
**
**  FUNCTIONAL DESCRIPTION:
**
**  	tbs
**
**  RETURNS:	cond_value, longword (unsigned), write only, by value
**
**  PROTOTYPE:
**
**  	tbs
**
**  IMPLICIT INPUTS:	None.
**
**  IMPLICIT OUTPUTS:	None.
**
**  COMPLETION CODES:
**
**
**  SIDE EFFECTS:   	None.
**
**--
*/
static unsigned int io_completion (struct IOR *ior) {

    struct CTX *ctx = ior->ctx;

    ior->iorflags |= IOR_M_IO_COMPLETED;

    if (ior->iorflags & IOR_M_IO_TIMED) sys$cantim(ior, 0);

    if (ior->iosb.iosb_w_status == SS$_CANCEL && (ior->iorflags & IOR_M_IO_TIMEOUT))
    	ior->iosb.iosb_w_status = SS$_TIMEOUT;

    if (ior->iosbp != 0) netlib___cvt_iosb(ior->iosbp, &ior->iosb);


    if (ior->iorflags & IOR_M_COPY_LENGTH) {
    	if (OK(ior->iosb.iosb_w_status) && ior->spec_retlen != 0)
    	    	*(unsigned int *) ior->spec_retlen = ior->spec_length;
    	ior->iorflags &= ~IOR_M_COPY_LENGTH;
    }

    if (ior->iorflags & IOR_M_COPY_FROM) {
    	if (OK(ior->iosb.iosb_w_status) && ior->spec_userfrom != 0) {
    	    unsigned int len;
    	    len = ior->specior.fromlen;
    	    if (len > ior->spec_length) len = ior->spec_length;
    	    memcpy(ior->spec_userfrom, &ior->specior.from, len);
    	    if (ior->spec_retlen != 0) *(unsigned int *)ior->spec_retlen = len;
    	 }
    	 ior->iorflags &= ~IOR_M_COPY_FROM;
    }

    if (ior->iorflags & IOR_M_COPY_ADDRS) {
    	struct HOSTENT *h;

    	h = ior->spec_hostent;
    	if (OK(ior->iosb.iosb_w_status)) {
    	    char *base;
    	    unsigned int *offlst;
    	    int i;
    	    base = (char *) h;
    	    i = 0;
    	    if (h->addrlist_offset != 0) {
    	    	struct INADDRDEF *alist = ior->spec_useralist;
    	    	offlst = (unsigned int *) (base+h->addrlist_offset);
    	    	while (i < ior->spec_length && offlst[i] != 0) {
    	    	    alist[i] = *(struct INADDRDEF *) (base + offlst[i]);
    	    	    i++;
    	    	}
    	    }
    	    if (ior->spec_retlen != 0) *(unsigned int *)ior->spec_retlen = i;
    	}
    	lib$free_vm(&hostent_size, &h);
    	ior->iorflags &= ~IOR_M_COPY_ADDRS;
    }

    if (ior->iorflags & IOR_M_COPY_HOSTNAME) {
    	struct HOSTENT *h;
    	h = ior->spec_hostent;
    	if (OK(ior->iosb.iosb_w_status)) {
    	    str$copy_r(ior->spec_usrdsc, &ior->specior.fromlen,
    	    	    	    	    	h->buffer);
    	    if (ior->spec_retlen != 0)
    	    	*(unsigned short *)ior->spec_retlen =
    	    	    	    	    	    	ior->specior.fromlen;
    	}
    	lib$free_vm(&hostent_size, &h);
    	ior->iorflags &= ~IOR_M_COPY_HOSTNAME;
    }

    if (ior->iorflags & IOR_M_NEW_CONTEXT) {
    	if (OK(ior->iosb.iosb_w_status)) {
    	    *(struct CTX **) ior->spec_xnewctx = ior->spec_newctx;
    	} else {
    	    sys$dassgn(((struct CTX *)ior->spec_newctx)->chan);
    	    netlib___free_ctx((struct CTX *) ior->spec_newctx);
    	}
    	   ior->iorflags &= ~IOR_M_NEW_CONTEXT;
    }

    if (ior->astadr != 0) (*(ior->astadr))(ior->astprm);

    FREE_IOR(ior);

    return SS$_NORMAL;

} /* io_completion */
Ejemplo n.º 16
0
/*
**++
**  ROUTINE:	sp_open
**
**  FUNCTIONAL DESCRIPTION:
**
**  	Spawns a subprocess, possibly passing it an initial command.
**
**  RETURNS:	cond_value, longword (unsigned), write only, by value
**
**  PROTOTYPE:
**
**  	sp_open(SPHANDLE *ctxpp, struct dsc$descriptor *inicmd,
**  	    	    unsigned int (*rcvast)(void *), void *rcvastprm);
**
**  IMPLICIT INPUTS:	None.
**
**  IMPLICIT OUTPUTS:	None.
**
**  COMPLETION CODES:
**  	    SS$_NORMAL:	    Normal successful completion.
**
**  SIDE EFFECTS:   	None.
**
**--
*/
unsigned int sp_open (SPHANDLE *ctxpp, void *inicmd, unsigned int (*rcvast)(void *), void *rcvastprm) {

    SPHANDLE ctx;
    unsigned int dvi_devnam = DVI$_DEVNAM, dvi_devbufsiz = DVI$_DEVBUFSIZ;
    unsigned int spawn_flags = CLI$M_NOWAIT|CLI$M_NOKEYPAD;
    unsigned int status;
    struct dsc$descriptor inbox, outbox;

    status = lib$get_vm(&spb_size, &ctx);
    if (!OK(status)) return status;

/*
** Assign the SPHANDLE address for the caller immediately to avoid timing issues with
** WRTATTN AST that passes the ctx as rcvastprm (which sp_once does).
*/
    *ctxpp = ctx;
    ctx->sendque.head = ctx->sendque.tail = &ctx->sendque;
    ctx->ok_to_send = 0;

/*
** Create the mailboxes we'll be using for I/O with the subprocess
*/
    status = sys$crembx(0, &ctx->inchn, 1024, 1024, 0xff00, 0, 0, 0);
    if (!OK(status)) {
    	lib$free_vm(&spb_size, &ctx);
    	return status;
    }
    status = sys$crembx(0, &ctx->outchn, 1024, 1024, 0xff00, 0, 0, 0);
    if (!OK(status)) {
    	sys$dassgn(ctx->inchn);
    	lib$free_vm(&spb_size, &ctx);
    	return status;
    }

/*
** Now that they're created, let's find out what they're called so we
** can tell LIB$SPAWN
*/
    INIT_DYNDESC(inbox);
    INIT_DYNDESC(outbox);
    lib$getdvi(&dvi_devnam, &ctx->inchn, 0, 0, &inbox);
    lib$getdvi(&dvi_devnam, &ctx->outchn, 0, 0, &outbox);
    lib$getdvi(&dvi_devbufsiz, &ctx->outchn, 0, &ctx->bufsiz);

/*
** Create the output buffer for the subprocess.
*/
    status = lib$get_vm(&ctx->bufsiz, &ctx->bufptr);
    if (!OK(status)) {
    	sys$dassgn(ctx->outchn);
    	sys$dassgn(ctx->inchn);
    	str$free1_dx(&inbox);
    	str$free1_dx(&outbox);
    	lib$free_vm(&spb_size, &ctx);
    	return status;
    }

/*
** Set the "receive AST" routine to be invoked by SP_WRTATTN_AST
*/
    ctx->rcvast = rcvast;
    ctx->astprm = rcvastprm;
    sys$qiow(0, ctx->outchn, IO$_SETMODE|IO$M_WRTATTN, 0, 0, 0,
    	sp_wrtattn_ast, ctx, 0, 0, 0, 0);
    sys$qiow(0, ctx->inchn, IO$_SETMODE|IO$M_READATTN, 0, 0, 0,
    	sp_readattn_ast, ctx, 0, 0, 0, 0);

/*
** Get us a termination event flag
*/
    status = lib$get_ef(&ctx->termefn);
    if (OK(status)) lib$get_ef(&ctx->inefn);
    if (OK(status)) lib$get_ef(&ctx->outefn);
    if (!OK(status)) {
    	sys$dassgn(ctx->outchn);
    	sys$dassgn(ctx->inchn);
    	str$free1_dx(&inbox);
    	str$free1_dx(&outbox);
    	lib$free_vm(&ctx->bufsiz, &ctx->bufptr);
    	lib$free_vm(&spb_size, &ctx);
    	return status;
    }

/*
** Now create the subprocess
*/
    status = lib$spawn(inicmd, &inbox, &outbox, &spawn_flags, 0, &ctx->pid,
    	    0, &ctx->termefn);
    if (!OK(status)) {
    	lib$free_ef(&ctx->termefn);
    	lib$free_ef(&ctx->outefn);
    	lib$free_ef(&ctx->inefn);
    	sys$dassgn(ctx->outchn);
    	sys$dassgn(ctx->inchn);
    	str$free1_dx(&inbox);
    	str$free1_dx(&outbox);
    	lib$free_vm(&ctx->bufsiz, &ctx->bufptr);
    	lib$free_vm(&spb_size, &ctx);
    	return status;
    }

/*
** Set up the exit handler, if we haven't done so already
*/
    status = sys$setast(0);
    if (!exh_declared) {
    	sys$dclexh(&exhblk);
    	exh_declared = 1;
    }
    if (status == SS$_WASSET) sys$setast(1);

/*
** Save the SPB in our private queue
*/
    queue_insert(ctx, spque.tail);

/*
** Clean up and return
*/
    str$free1_dx(&inbox);
    str$free1_dx(&outbox);

    return SS$_NORMAL;

} /* sp_open */
Ejemplo n.º 17
0
void cmj_mbx_ast(struct NTD *tsk)
{
	struct CLB *cmu_makclb();
	struct dsc$descriptor_s ncb_desc;
	uint4 status, unit;
	cm_mbx *mp;
	struct CLB *lnk;
	bool newclb;
	void cmj_ast();

	status = 0;
	mp = tsk->mbx.dsc$a_pointer;
	assert(mp->netnum == 3 && mp->netnam[0] == 'N' && mp->netnam[1] == 'E' && mp->netnam[2] == 'T');
	switch(mp->msg)
	{
	case MSG$_CONNECT:
		lnk = cmj_unit2clb(tsk, mp->unit);
		if (lnk == 0)
		{
			newclb = TRUE;
			lnk = cmu_makclb();
			lnk->dch = tsk->dch;
			lnk->ntd = tsk;
		}else
		{
			newclb = FALSE;
			assert(lnk->sta == CM_CLB_IDLE);
		}
		ncb_desc.dsc$w_length = mp->len;
		ncb_desc.dsc$b_dtype = DSC$K_DTYPE_T;
		ncb_desc.dsc$b_class = DSC$K_CLASS_S;
		ncb_desc.dsc$a_pointer = mp->text;
		lnk->mbf = 0;
	/* the statement below and the 3 qio's emulate cmj_iostart which could be used if lnk->clb were a int4 */
		lnk->sta = CM_CLB_WRITE;
		if (tsk->crq == 0)
		{
			lnk->ast = cmj_reject_ast;
                        status = sys$qio(efn_ignore, lnk->dch, IO$_ACCESS | IO$M_ABORT,
				&lnk->ios, cmj_ast, lnk,
				lnk->mbf, &ncb_desc, 0, 0, 0, 0);
		} else
		{	if (tsk->acc && !(*tsk->acc)(lnk))
			{
				lnk->ast = cmj_reject_ast;
                                status = sys$qio(efn_ignore, lnk->dch, IO$_ACCESS | IO$M_ABORT,
					&lnk->ios, cmj_ast, lnk,
					lnk->mbf, &ncb_desc, 0, 0, 0, 0);
			}else
			{
				status = sys$assign(&cm_netname, &lnk->dch, 0, &tsk->mnm);
				if (status & 1)
				{
					status = lib$getdvi(&DVI$_UNIT, &lnk->dch, 0, &unit, 0, 0);
					if (status & 1)
					{
						lnk->mun = (unsigned short)unit;
						lnk->ast = cmj_accept_ast;
                                                status = sys$qio(efn_ignore, lnk->dch, IO$_ACCESS,
							&lnk->ios, cmj_ast, lnk,
							lnk->mbf, &ncb_desc, 0, 0, 0, 0);
					}
				}
			}
		}
		if ((status & 1) == 0)
		{
			if (newclb)
			{
				lib$free_vm(&SIZEOF(*lnk), &lnk, 0);
				lnk = 0;
			}
			cmj_mbx_err(status, tsk, lnk);
			break;
		}
		return;

	case MSG$_INTMSG:
		if (tsk->mbx_ast != 0)
		{	(*tsk->mbx_ast)(tsk);
			break;
		}
	/* CAUTION:  FALLTHROUGH */
	case MSG$_DISCON:
	case MSG$_ABORT:
	case MSG$_EXIT:
	case MSG$_PATHLOST:
	case MSG$_PROTOCOL:
	case MSG$_THIRDPARTY:
	case MSG$_TIMEOUT:
	case MSG$_NETSHUT:
	case MSG$_REJECT:
	case MSG$_CONFIRM:
		if (tsk->err)
		{
			lnk = cmj_unit2clb(tsk, mp->unit);
			(*tsk->err)(tsk, lnk, mp->msg);
		}else
			rts_error(CMI_NETFAIL,0,status);	/* condition handler would need to close the connection */
	/* CAUTION:  FALLTHROUGH */
	default:
		break;
	}

	status = cmj_mbx_read_start(tsk);
	if ((status & 1) == 0)
	{
		lnk = cmj_unit2clb(tsk, mp->unit);
		cmj_mbx_err(status, tsk, lnk);
	}
}