コード例 #1
0
ファイル: main.c プロジェクト: MIPS/external-mksh
static mksh_uari_t
rndsetup(void)
{
	register uint32_t h;
	struct {
		ALLOC_ITEM alloc_INT;
		void *dataptr, *stkptr, *mallocptr;
#if defined(__GLIBC__) && (__GLIBC__ >= 2)
		sigjmp_buf jbuf;
#endif
		struct timeval tv;
	} *bufptr;
	char *cp;

	cp = alloc(sizeof(*bufptr) - sizeof(ALLOC_ITEM), APERM);
	/* clear the allocated space, for valgrind and to avoid UB */
	memset(cp, 0, sizeof(*bufptr) - sizeof(ALLOC_ITEM));
	/* undo what alloc() did to the malloc result address */
	bufptr = (void *)(cp - sizeof(ALLOC_ITEM));
	/* PIE or something similar provides us with deltas here */
	bufptr->dataptr = &rndsetupstate;
	/* ASLR in at least Windows, Linux, some BSDs */
	bufptr->stkptr = &bufptr;
	/* randomised malloc in BSD (and possibly others) */
	bufptr->mallocptr = bufptr;
#if defined(__GLIBC__) && (__GLIBC__ >= 2)
	/* glibc pointer guard */
	sigsetjmp(bufptr->jbuf, 1);
#endif
	/* introduce variation (and yes, second arg MBZ for portability) */
	mksh_TIME(bufptr->tv);

#ifdef MKSH_ALLOC_CATCH_UNDERRUNS
	mprotect(((char *)bufptr) + 4096, 4096, PROT_READ | PROT_WRITE);
#endif
	h = chvt_rndsetup(bufptr, sizeof(*bufptr));

	afree(cp, APERM);
	return ((mksh_uari_t)h);
}
コード例 #2
0
ファイル: var.c プロジェクト: rovaughn/distro
static void
setspec(struct tbl *vp)
{
	mksh_ari_u num;
	char *s;
	int st;

	switch ((st = special(vp->name))) {
#if HAVE_PERSISTENT_HISTORY
	case V_HISTFILE:
		sethistfile(str_val(vp));
		return;
#endif
	case V_IFS:
		setctypes(s = str_val(vp), C_IFS);
		ifs0 = *s;
		return;
	case V_PATH:
		if (path)
			afree(path, APERM);
		s = str_val(vp);
		strdupx(path, s, APERM);
		/* clear tracked aliases */
		flushcom(true);
		return;
	case V_TMPDIR:
		if (tmpdir) {
			afree(tmpdir, APERM);
			tmpdir = NULL;
		}
		/*
		 * Use tmpdir iff it is an absolute path, is writable
		 * and searchable and is a directory...
		 */
		{
			struct stat statb;

			s = str_val(vp);
			/* LINTED use of access */
			if (mksh_abspath(s) && access(s, W_OK|X_OK) == 0 &&
			    stat(s, &statb) == 0 && S_ISDIR(statb.st_mode))
				strdupx(tmpdir, s, APERM);
		}
		return;
	/* common sub-cases */
	case V_COLUMNS:
	case V_LINES:
		if (vp->flag & IMPORT) {
			/* do not touch */
			unspecial(vp->name);
			vp->flag &= ~SPECIAL;
			return;
		}
		/* FALLTHROUGH */
	case V_HISTSIZE:
	case V_LINENO:
	case V_OPTIND:
	case V_RANDOM:
	case V_SECONDS:
	case V_TMOUT:
		vp->flag &= ~SPECIAL;
		if (getint(vp, &num, false) == -1) {
			s = str_val(vp);
			if (st != V_RANDOM)
				errorf("%s: %s: %s", vp->name, "bad number", s);
			num.u = hash(s);
		}
		vp->flag |= SPECIAL;
		break;
	default:
		/* do nothing, do not touch vp at all */
		return;
	}

	/* process the singular parts of the common cases */

	switch (st) {
	case V_COLUMNS:
		if (num.i >= MIN_COLS)
			x_cols = num.i;
		break;
	case V_HISTSIZE:
		sethistsize(num.i);
		break;
	case V_LINENO:
		/* The -1 is because line numbering starts at 1. */
		user_lineno = num.u - (mksh_uari_t)current_lineno - 1;
		break;
	case V_LINES:
		if (num.i >= MIN_LINS)
			x_lins = num.i;
		break;
	case V_OPTIND:
		getopts_reset((int)num.i);
		break;
	case V_RANDOM:
		/*
		 * mksh R39d+ no longer has the traditional repeatability
		 * of $RANDOM sequences, but always retains state
		 */
		rndset((unsigned long)num.u);
		break;
	case V_SECONDS:
		{
			struct timeval tv;

			mksh_TIME(tv);
			seconds = tv.tv_sec - num.i;
		}
		break;
	case V_TMOUT:
		ksh_tmout = num.i >= 0 ? num.i : 0;
		break;
	}
}
コード例 #3
0
ファイル: var.c プロジェクト: rovaughn/distro
static void
getspec(struct tbl *vp)
{
	mksh_ari_u num;
	int st;
	struct timeval tv;

	switch ((st = special(vp->name))) {
	case V_COLUMNS:
	case V_LINES:
		/*
		 * Do NOT export COLUMNS/LINES. Many applications
		 * check COLUMNS/LINES before checking ws.ws_col/row,
		 * so if the app is started with C/L in the environ
		 * and the window is then resized, the app won't
		 * see the change cause the environ doesn't change.
		 */
		if (got_winch)
			change_winsz();
		break;
	}
	switch (st) {
	case V_BASHPID:
		num.u = (mksh_uari_t)procpid;
		break;
	case V_COLUMNS:
		num.i = x_cols;
		break;
	case V_HISTSIZE:
		num.i = histsize;
		break;
	case V_LINENO:
		num.u = (mksh_uari_t)current_lineno + user_lineno;
		break;
	case V_LINES:
		num.i = x_lins;
		break;
	case V_EPOCHREALTIME: {
		/* 10(%u) + 1(.) + 6 + NUL */
		char buf[18];

		vp->flag &= ~SPECIAL;
		mksh_TIME(tv);
		shf_snprintf(buf, sizeof(buf), "%u.%06u",
		    (unsigned)tv.tv_sec, (unsigned)tv.tv_usec);
		setstr(vp, buf, KSH_RETURN_ERROR | 0x4);
		vp->flag |= SPECIAL;
		return;
	}
	case V_OPTIND:
		num.i = user_opt.uoptind;
		break;
	case V_RANDOM:
		num.i = rndget();
		break;
	case V_SECONDS:
		/*
		 * On start up the value of SECONDS is used before
		 * it has been set - don't do anything in this case
		 * (see initcoms[] in main.c).
		 */
		if (vp->flag & ISSET) {
			mksh_TIME(tv);
			num.i = tv.tv_sec - seconds;
		} else
			return;
		break;
	default:
		/* do nothing, do not touch vp at all */
		return;
	}
	vp->flag &= ~SPECIAL;
	setint_n(vp, num.i, 0);
	vp->flag |= SPECIAL;
}