Esempio n. 1
0
/*
 * Call an internal dcmd directly: this code is used by module API functions
 * that need to execute dcmds, and by mdb_call() above.
 */
int
mdb_call_idcmd(mdb_idcmd_t *idcp, uintmax_t addr, uintmax_t count,
    uint_t flags, mdb_argvec_t *avp, mdb_addrvec_t *adp, mdb_vcb_t *vcbs)
{
	int is_exec = (strcmp(idcp->idc_name, "$<") == 0);
	mdb_arg_t *argv;
	int argc;
	uintmax_t i;
	int status;

	/*
	 * Update the values of dot and the most recent address and count
	 * to the values of our input parameters.
	 */
	mdb_nv_set_value(mdb.m_dot, addr);
	mdb.m_raddr = addr;
	mdb.m_dcount = count;

	/*
	 * Here the adb(1) man page lies: '9' is only set to count
	 * when the command is $<, not when it's $<<.
	 */
	if (is_exec)
		mdb_nv_set_value(mdb.m_rcount, count);

	/*
	 * We can now return if the repeat count is zero.
	 */
	if (count == 0)
		return (DCMD_OK);

	/*
	 * To guard against bad dcmds, we avoid passing the actual argv that
	 * we will use to free argument strings directly to the dcmd.  Instead,
	 * we pass a copy that will be garbage collected automatically.
	 */
	argc = avp->a_nelems;
	argv = mdb_alloc(sizeof (mdb_arg_t) * argc, UM_SLEEP | UM_GC);
	bcopy(avp->a_data, argv, sizeof (mdb_arg_t) * argc);

	if (mdb_addrvec_length(adp) != 0) {
		flags |= DCMD_PIPE | DCMD_LOOP | DCMD_LOOPFIRST | DCMD_ADDRSPEC;
		addr = mdb_addrvec_shift(adp);
		mdb_nv_set_value(mdb.m_dot, addr);
		mdb_vcb_propagate(vcbs);
		count = 1;
	}

	status = dcmd_invoke(idcp, addr, flags, argc, argv, vcbs);
	if (DCMD_ABORTED(status))
		goto done;

	/*
	 * If the command is $< and we're not receiving input from a pipe, we
	 * ignore the repeat count and just return since the macro file is now
	 * pushed on to the input stack.
	 */
	if (is_exec && mdb_addrvec_length(adp) == 0)
		goto done;

	/*
	 * If we're going to loop, we've already executed the dcmd once,
	 * so clear the LOOPFIRST flag before proceeding.
	 */
	if (flags & DCMD_LOOP)
		flags &= ~DCMD_LOOPFIRST;

	for (i = 1; i < count; i++) {
		addr = mdb_dot_incr(",");
		mdb_nv_set_value(mdb.m_dot, addr);
		status = dcmd_invoke(idcp, addr, flags, argc, argv, vcbs);
		if (DCMD_ABORTED(status))
			goto done;
	}

	while (mdb_addrvec_length(adp) != 0) {
		addr = mdb_addrvec_shift(adp);
		mdb_nv_set_value(mdb.m_dot, addr);
		mdb_vcb_propagate(vcbs);
		status = dcmd_invoke(idcp, addr, flags, argc, argv, vcbs);
		if (DCMD_ABORTED(status))
			goto done;
	}
done:
	mdb_iob_nlflush(mdb.m_out);
	return (status);
}
Esempio n. 2
0
static void
roff_disc_set(mdb_var_t *v, uintmax_t value)
{
	mdb_nv_set_value(mdb.m_proffset, MDB_NV_VALUE(v));
	MDB_NV_VALUE(v) = value;
}
Esempio n. 3
0
void
mdb_set_dot(uintmax_t addr)
{
	mdb_nv_set_value(mdb.m_dot, addr);
	mdb.m_incr = 0;
}