예제 #1
0
파일: config.c 프로젝트: RWTH-OS/rumprun
static char *
token2cstr(jsmntok_t *t, char *data)
{

	*(T_STR(t, data) + T_SIZE(t)) = '\0';
	return T_STR(t, data);
}
예제 #2
0
파일: config.c 프로젝트: RWTH-OS/rumprun
/*
 * "rc": [
 *	{ "bin" : "binname",
 *	  "argv" : [ "arg1", "arg2", ... ], (optional)
 *	  "runmode" : "& OR |" (optional)
 *	},
 *      ....
 * ]
 */
static int
addbin(jsmntok_t *t, char *data)
{
	jsmntok_t *t_bin, *t_argv, *t_runmode;
	struct rumprun_exec *rre;
	jsmntok_t *key, *value;
	char *binname;
	int binsize = 1;
	int objleft = t->size;
	int rreflags, i;

	T_CHECKTYPE(t, data, JSMN_OBJECT, __func__);
	t++;

	/* process and validate data */
	t_bin = t_argv = t_runmode = NULL;
	while (objleft--) {
		int mysize;

		key = t;
		value = t+1;

		T_CHECKTYPE(key, data, JSMN_STRING, __func__);

		if (T_STREQ(key, data, "bin")) {
			t_bin = value;

			T_CHECKSIZE(key, data, 1, __func__);
			T_CHECKTYPE(value, data, JSMN_STRING, __func__);
			T_CHECKSIZE(value, data, 0, __func__);

			mysize = 1 + 1;
		} else if (T_STREQ(key, data, "argv")) {
			T_CHECKTYPE(value, data, JSMN_ARRAY, __func__);

			t_argv = value;

			/* key + array + array contents */
			mysize = 1 + 1 + value->size;
		} else if (T_STREQ(key, data, "runmode")) {
			t_runmode = value;

			T_CHECKSIZE(key, data, 1, __func__);
			T_CHECKTYPE(value, data, JSMN_STRING, __func__);
			T_CHECKSIZE(value, data, 0, __func__);

			mysize = 1 + 1;
		} else {
			errx(1, "unexpected key \"%.*s\" in \"%s\"",
			    T_PRINTFSTAR(key, data), __func__);
		}

		t += mysize;
		binsize += mysize;
	}

	if (!t_bin)
		errx(1, "missing \"bin\" for rc entry");
	binname = token2cstr(t_bin, data);

	if (t_runmode) {
		bool sizeok = T_SIZE(t_runmode) == 1;

		if (sizeok && *T_STR(t_runmode,data) == '&') {
			rreflags = RUMPRUN_EXEC_BACKGROUND;
		} else if (sizeok && *T_STR(t_runmode,data) == '|') {
			rreflags = RUMPRUN_EXEC_PIPE;
		} else {
			errx(1, "invalid runmode \"%.*s\" for bin \"%.*s\"",
			    T_PRINTFSTAR(t_runmode, data),
			    T_PRINTFSTAR(t_bin, data));
		}
	} else {
		rreflags = 0;
	}

	/* ok, we got everything.  save into rumprun_exec structure */
	rre = malloc(sizeof(*rre) + (2+t_argv->size) * sizeof(char *));
	if (rre == NULL)
		err(1, "allocate rumprun_exec");
	rre->rre_flags = rreflags;
	rre->rre_argc = 1+t_argv->size;
	rre->rre_argv[0] = binname;
	for (i = 1, t = t_argv+1; i <= t_argv->size; i++, t++) {
		T_CHECKTYPE(t, data, JSMN_STRING, __func__);
		rre->rre_argv[i] = token2cstr(t, data);
	}
	rre->rre_argv[rre->rre_argc] = NULL;

	TAILQ_INSERT_TAIL(&rumprun_execs, rre, rre_entries);

	return binsize;
}
예제 #3
0
int test_str(void)
{
	STR_DEFINE( s3, 10 );
	Str *s4, *s5;
	STR_DEFINE(s6, 10);
	STR_DEFINE(s7, 10);

	dump_str( s1, "s1" );
	dump_str( s2, "s2" );
	dump_str( s3, "s3" );

	/* check static strings keep their value */
	mu_assert_str( static_str(4),  ==, "4" );
	mu_assert_str( static_str(-1), ==, "4" );
	mu_assert_str( static_str(-1), ==, "4" );

	mu_assert_str( static_str(7),  ==, "7" );
	mu_assert_str( static_str(-1), ==, "7" );
	mu_assert_str( static_str(-1), ==, "7" );

	T_STR(s4, s4 = str_new(6));		/* alloc, keep memory leak */

	T_STR(s5, s5 = str_new(6));
	
	/* expand */
	T_STR(s3, str_clear(s3));
	T_STR(s3, str_reserve(s3, 9));
	T_STR(s3, str_reserve(s3, 10));
	T_STR(s3, str_reserve(s3, 11));
	T_STR(s3, str_clear(s3));

	/* char */
	T_STR(s4, str_set(s4, "xxxx"));
	T_STR(s4, str_set_char(s4, 0));
	T_STR(s4, str_append_char(s4, 1));
	T_STR(s4, str_append_char(s4, 2));
	T_STR(s4, str_append_char(s4, 3));
	T_STR(s4, str_append_char(s4, 4));
	T_STR(s4, str_append_char(s4, 5));
	T_STR(s4, str_append_char(s4, 6));
	T_STR(s4, str_append_char(s4, 7));
	T_STR(s4, str_append_char(s4, 8));
	T_STR(s4, str_append_char(s4, 9));
	T_STR(s4, str_append_char(s4, 10));
	T_STR(s4, str_clear(s4));

	/* string */
	T_STR(s5, str_set(s5, "1234"));
	T_STR(s5, str_append(s5, "56789"));
	T_STR(s5, str_append(s5, "0"));
	T_STR(s5, str_clear(s5));

	/* substring */
	T_STR(s5, str_set_n(s5, "1234xx", 4));
	T_STR(s5, str_append_n(s5, "56789xx", 5));
	T_STR(s5, str_append_n(s5, "01234567890xx", 11));
	T_STR(s5, str_clear(s5));

	/* bytes */
	T_STR(s5, str_set_bytes(s5, "\0\1\2\3x", 3));
	T_STR(s5, str_append_bytes(s5, "\4\5\6x", 3));
	T_STR(s5, str_clear(s5));

	/* sprintf - test repeated call to vsprintf when buffer grows, needs va_copy in MacOS */
	T_STR(s6, str_set(s6, "xxxx"));
	T_STR(s6, str_sprintf(s6, "%s %d", "hello", 123));
	T_STR(s6, str_sprintf(s6, "%s %d", "hello", 1234));
	T_STR(s6, str_append_sprintf(s6, "%s %d", "hello", 12345));
	T_STR(s6, str_clear(s6));

	/* vsprintf - test repeated call to vsprintf when buffer grows, needs va_copy in MacOS */
	T_STR(s7, str_set(s7, "xxxx"));
	T_STR(s7, call_vsprintf(s7, "%s %d", "hello", 123));
	T_STR(s7, call_vsprintf(s7, "%s %d", "hello", 1234));
	T_STR(s7, call_append_vsprintf(s7, "%s %d", "hello", 12345));
	T_STR(s7, str_clear(s7));

	str_delete(s5);
	mu_assert_ptr_null(s5);

	STR_DELETE(s3);
	mu_assert_ptr_null(s3);

	STR_DELETE(s6);
	mu_assert_ptr_null(s6);

	STR_DELETE(s7);
	mu_assert_ptr_null(s7);

	return MU_PASS;
}