18c2ecf20Sopenharmony_ci/* Time bounds setting test
28c2ecf20Sopenharmony_ci *		by: john stultz (johnstul@us.ibm.com)
38c2ecf20Sopenharmony_ci *		(C) Copyright IBM 2012
48c2ecf20Sopenharmony_ci *		Licensed under the GPLv2
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci *  NOTE: This is a meta-test which sets the time to edge cases then
78c2ecf20Sopenharmony_ci *  uses other tests to detect problems. Thus this test requires that
88c2ecf20Sopenharmony_ci *  the inconsistency-check and nanosleep tests be present in the same
98c2ecf20Sopenharmony_ci *  directory it is run from.
108c2ecf20Sopenharmony_ci *
118c2ecf20Sopenharmony_ci *  To build:
128c2ecf20Sopenharmony_ci *	$ gcc set-2038.c -o set-2038 -lrt
138c2ecf20Sopenharmony_ci *
148c2ecf20Sopenharmony_ci *   This program is free software: you can redistribute it and/or modify
158c2ecf20Sopenharmony_ci *   it under the terms of the GNU General Public License as published by
168c2ecf20Sopenharmony_ci *   the Free Software Foundation, either version 2 of the License, or
178c2ecf20Sopenharmony_ci *   (at your option) any later version.
188c2ecf20Sopenharmony_ci *
198c2ecf20Sopenharmony_ci *   This program is distributed in the hope that it will be useful,
208c2ecf20Sopenharmony_ci *   but WITHOUT ANY WARRANTY; without even the implied warranty of
218c2ecf20Sopenharmony_ci *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
228c2ecf20Sopenharmony_ci *   GNU General Public License for more details.
238c2ecf20Sopenharmony_ci */
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci#include <stdio.h>
268c2ecf20Sopenharmony_ci#include <stdlib.h>
278c2ecf20Sopenharmony_ci#include <unistd.h>
288c2ecf20Sopenharmony_ci#include <time.h>
298c2ecf20Sopenharmony_ci#include <sys/time.h>
308c2ecf20Sopenharmony_ci#include "../kselftest.h"
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci#define NSEC_PER_SEC 1000000000LL
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci#define KTIME_MAX	((long long)~((unsigned long long)1 << 63))
358c2ecf20Sopenharmony_ci#define KTIME_SEC_MAX	(KTIME_MAX / NSEC_PER_SEC)
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci#define YEAR_1901 (-0x7fffffffL)
388c2ecf20Sopenharmony_ci#define YEAR_1970 1
398c2ecf20Sopenharmony_ci#define YEAR_2038 0x7fffffffL			/*overflows 32bit time_t */
408c2ecf20Sopenharmony_ci#define YEAR_2262 KTIME_SEC_MAX			/*overflows 64bit ktime_t */
418c2ecf20Sopenharmony_ci#define YEAR_MAX  ((long long)((1ULL<<63)-1))	/*overflows 64bit time_t */
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ciint is32bits(void)
448c2ecf20Sopenharmony_ci{
458c2ecf20Sopenharmony_ci	return (sizeof(long) == 4);
468c2ecf20Sopenharmony_ci}
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ciint settime(long long time)
498c2ecf20Sopenharmony_ci{
508c2ecf20Sopenharmony_ci	struct timeval now;
518c2ecf20Sopenharmony_ci	int ret;
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci	now.tv_sec = (time_t)time;
548c2ecf20Sopenharmony_ci	now.tv_usec  = 0;
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci	ret = settimeofday(&now, NULL);
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci	printf("Setting time to 0x%lx: %d\n", (long)time, ret);
598c2ecf20Sopenharmony_ci	return ret;
608c2ecf20Sopenharmony_ci}
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ciint do_tests(void)
638c2ecf20Sopenharmony_ci{
648c2ecf20Sopenharmony_ci	int ret;
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci	ret = system("date");
678c2ecf20Sopenharmony_ci	ret = system("./inconsistency-check -c 0 -t 20");
688c2ecf20Sopenharmony_ci	ret |= system("./nanosleep");
698c2ecf20Sopenharmony_ci	ret |= system("./nsleep-lat");
708c2ecf20Sopenharmony_ci	return ret;
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci}
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ciint main(int argc, char *argv[])
758c2ecf20Sopenharmony_ci{
768c2ecf20Sopenharmony_ci	int ret = 0;
778c2ecf20Sopenharmony_ci	int opt, dangerous = 0;
788c2ecf20Sopenharmony_ci	time_t start;
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci	/* Process arguments */
818c2ecf20Sopenharmony_ci	while ((opt = getopt(argc, argv, "d")) != -1) {
828c2ecf20Sopenharmony_ci		switch (opt) {
838c2ecf20Sopenharmony_ci		case 'd':
848c2ecf20Sopenharmony_ci			dangerous = 1;
858c2ecf20Sopenharmony_ci		}
868c2ecf20Sopenharmony_ci	}
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci	start = time(0);
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci	/* First test that crazy values don't work */
918c2ecf20Sopenharmony_ci	if (!settime(YEAR_1901)) {
928c2ecf20Sopenharmony_ci		ret = -1;
938c2ecf20Sopenharmony_ci		goto out;
948c2ecf20Sopenharmony_ci	}
958c2ecf20Sopenharmony_ci	if (!settime(YEAR_MAX)) {
968c2ecf20Sopenharmony_ci		ret = -1;
978c2ecf20Sopenharmony_ci		goto out;
988c2ecf20Sopenharmony_ci	}
998c2ecf20Sopenharmony_ci	if (!is32bits() && !settime(YEAR_2262)) {
1008c2ecf20Sopenharmony_ci		ret = -1;
1018c2ecf20Sopenharmony_ci		goto out;
1028c2ecf20Sopenharmony_ci	}
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ci	/* Now test behavior near edges */
1058c2ecf20Sopenharmony_ci	settime(YEAR_1970);
1068c2ecf20Sopenharmony_ci	ret = do_tests();
1078c2ecf20Sopenharmony_ci	if (ret)
1088c2ecf20Sopenharmony_ci		goto out;
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci	settime(YEAR_2038 - 600);
1118c2ecf20Sopenharmony_ci	ret = do_tests();
1128c2ecf20Sopenharmony_ci	if (ret)
1138c2ecf20Sopenharmony_ci		goto out;
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci	/* The rest of the tests can blowup on 32bit systems */
1168c2ecf20Sopenharmony_ci	if (is32bits() && !dangerous)
1178c2ecf20Sopenharmony_ci		goto out;
1188c2ecf20Sopenharmony_ci	/* Test rollover behavior 32bit edge */
1198c2ecf20Sopenharmony_ci	settime(YEAR_2038 - 10);
1208c2ecf20Sopenharmony_ci	ret = do_tests();
1218c2ecf20Sopenharmony_ci	if (ret)
1228c2ecf20Sopenharmony_ci		goto out;
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci	settime(YEAR_2262 - 600);
1258c2ecf20Sopenharmony_ci	ret = do_tests();
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ciout:
1288c2ecf20Sopenharmony_ci	/* restore clock */
1298c2ecf20Sopenharmony_ci	settime(start);
1308c2ecf20Sopenharmony_ci	if (ret)
1318c2ecf20Sopenharmony_ci		return ksft_exit_fail();
1328c2ecf20Sopenharmony_ci	return ksft_exit_pass();
1338c2ecf20Sopenharmony_ci}
134