1272343Sngie/* $NetBSD: t_mktime.c,v 1.5 2012/03/18 07:33:58 jruoho Exp $ */ 2272343Sngie 3272343Sngie/*- 4272343Sngie * Copyright (c) 2011 The NetBSD Foundation, Inc. 5272343Sngie * All rights reserved. 6272343Sngie * 7272343Sngie * Redistribution and use in source and binary forms, with or without 8272343Sngie * modification, are permitted provided that the following conditions 9272343Sngie * are met: 10272343Sngie * 1. Redistributions of source code must retain the above copyright 11272343Sngie * notice, this list of conditions and the following disclaimer. 12272343Sngie * 2. Redistributions in binary form must reproduce the above copyright 13272343Sngie * notice, this list of conditions and the following disclaimer in the 14272343Sngie * documentation and/or other materials provided with the distribution. 15272343Sngie * 16272343Sngie * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17272343Sngie * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18272343Sngie * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19272343Sngie * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20272343Sngie * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21272343Sngie * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22272343Sngie * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23272343Sngie * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24272343Sngie * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25272343Sngie * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26272343Sngie * POSSIBILITY OF SUCH DAMAGE. 27272343Sngie */ 28272343Sngie 29272343Sngie#include <atf-c.h> 30272343Sngie 31272343Sngie#include <err.h> 32272343Sngie#include <errno.h> 33272343Sngie#include <string.h> 34272343Sngie#include <time.h> 35272343Sngie 36272343SngieATF_TC(localtime_r_gmt); 37272343SngieATF_TC_HEAD(localtime_r_gmt, tc) 38272343Sngie{ 39272343Sngie atf_tc_set_md_var(tc, "descr", "Test that localtime_r(3) " 40272343Sngie "returns localtime, not GMT (PR lib/28324)"); 41272343Sngie} 42272343Sngie 43272343SngieATF_TC_BODY(localtime_r_gmt, tc) 44272343Sngie{ 45272343Sngie struct tm *t; 46272343Sngie struct tm tt; 47272343Sngie time_t x; 48272343Sngie 49272343Sngie x = time(NULL); 50272343Sngie localtime_r(&x, &tt); 51272343Sngie t = localtime(&x); 52272343Sngie 53272343Sngie if (t->tm_sec != tt.tm_sec || t->tm_min != tt.tm_min || 54272343Sngie t->tm_hour != tt.tm_hour || t->tm_mday != tt.tm_mday) 55272343Sngie atf_tc_fail("inconsistencies between " 56272343Sngie "localtime(3) and localtime_r(3)"); 57272343Sngie} 58272343Sngie 59272343SngieATF_TC(mktime_negyear); 60272343SngieATF_TC_HEAD(mktime_negyear, tc) 61272343Sngie{ 62272343Sngie atf_tc_set_md_var(tc, "descr", "Test mktime(3) with negative year"); 63272343Sngie} 64272343Sngie 65272343SngieATF_TC_BODY(mktime_negyear, tc) 66272343Sngie{ 67272343Sngie struct tm tms; 68272343Sngie time_t t; 69272343Sngie 70272343Sngie (void)memset(&tms, 0, sizeof(tms)); 71272343Sngie tms.tm_year = ~0; 72272343Sngie 73272343Sngie errno = 0; 74272343Sngie t = mktime(&tms); 75272343Sngie ATF_REQUIRE_ERRNO(0, t != (time_t)-1); 76272343Sngie} 77272343Sngie 78272343SngieATF_TC(timegm_epoch); 79272343SngieATF_TC_HEAD(timegm_epoch, tc) 80272343Sngie{ 81272343Sngie atf_tc_set_md_var(tc, "descr", "Test timegm(3) close to the epoch"); 82272343Sngie} 83272343Sngie 84272343SngieATF_TC_BODY(timegm_epoch, tc) 85272343Sngie{ 86272343Sngie struct tm tms; 87272343Sngie time_t t; 88272343Sngie 89272343Sngie /* midnight on 1 Jan 1970 */ 90272343Sngie (void)memset(&tms, 0, sizeof(tms)); 91272343Sngie errno = 0; 92272343Sngie tms.tm_year = 1970 - 1900; 93272343Sngie tms.tm_mday = 1; 94272343Sngie t = timegm(&tms); 95272343Sngie ATF_REQUIRE_ERRNO(0, t == (time_t)0); 96272343Sngie 97272343Sngie /* one second after midnight on 1 Jan 1970 */ 98272343Sngie (void)memset(&tms, 0, sizeof(tms)); 99272343Sngie errno = 0; 100272343Sngie tms.tm_year = 1970 - 1900; 101272343Sngie tms.tm_mday = 1; 102272343Sngie tms.tm_sec = 1; 103272343Sngie t = timegm(&tms); 104272343Sngie ATF_REQUIRE_ERRNO(0, t == (time_t)1); 105272343Sngie 106272343Sngie /* 107272343Sngie * 1969-12-31 23:59:59 = one second before the epoch. 108272343Sngie * Result should be -1 with errno = 0. 109272343Sngie */ 110272343Sngie (void)memset(&tms, 0, sizeof(tms)); 111272343Sngie errno = 0; 112272343Sngie tms.tm_year = 1969 - 1900; 113272343Sngie tms.tm_mon = 12 - 1; 114272343Sngie tms.tm_mday = 31; 115272343Sngie tms.tm_hour = 23; 116272343Sngie tms.tm_min = 59; 117272343Sngie tms.tm_sec = 59; 118272343Sngie t = timegm(&tms); 119272343Sngie ATF_REQUIRE_ERRNO(0, t == (time_t)-1); 120272343Sngie 121272343Sngie /* 122272343Sngie * Another way of getting one second before the epoch: 123272343Sngie * Set date to 1 Jan 1970, and time to -1 second. 124272343Sngie */ 125272343Sngie (void)memset(&tms, 0, sizeof(tms)); 126272343Sngie errno = 0; 127272343Sngie tms.tm_year = 1970 - 1900; 128272343Sngie tms.tm_mday = 1; 129272343Sngie tms.tm_sec = -1; 130272343Sngie t = timegm(&tms); 131272343Sngie ATF_REQUIRE_ERRNO(0, t == (time_t)-1); 132272343Sngie 133272343Sngie /* 134272343Sngie * Two seconds before the epoch. 135272343Sngie */ 136272343Sngie (void)memset(&tms, 0, sizeof(tms)); 137272343Sngie errno = 0; 138272343Sngie tms.tm_year = 1970 - 1900; 139272343Sngie tms.tm_mday = 1; 140272343Sngie tms.tm_sec = -2; 141272343Sngie t = timegm(&tms); 142272343Sngie ATF_REQUIRE_ERRNO(0, t == (time_t)-2); 143272343Sngie 144272343Sngie} 145272343Sngie 146272343Sngie 147272343SngieATF_TP_ADD_TCS(tp) 148272343Sngie{ 149272343Sngie 150272343Sngie ATF_TP_ADD_TC(tp, localtime_r_gmt); 151272343Sngie ATF_TP_ADD_TC(tp, mktime_negyear); 152272343Sngie ATF_TP_ADD_TC(tp, timegm_epoch); 153272343Sngie 154272343Sngie return atf_no_error(); 155272343Sngie} 156