source: mainline/uspace/lib/posix/src/time.c@ eec201d

Last change on this file since eec201d was 9b8be79, checked in by Jiří Zárevúcky <jiri.zarevucky@…>, 7 years ago

libposix: Change header organization and remove passthrough headers

Posix headers now function like an overlay. The system include directories
are searched after posix directories. The headers don't need to be patched
for export now. libposix files now include headers using bracket notation
instead of quoted notation.

  • Property mode set to 100644
File size: 8.0 KB
RevLine 
[2fc5072]1/*
2 * Copyright (c) 2011 Petr Koupy
3 * Copyright (c) 2011 Jiri Zarevucky
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup libposix
31 * @{
32 */
[4cf8ca6]33/** @file Time measurement support.
[2fc5072]34 */
35
[9b1503e]36#include "internal/common.h"
[9b8be79]37#include <sys/types.h>
38#include <sys/time.h>
39#include <time.h>
[a6d908c1]40
[9b8be79]41#include <ctype.h>
[0d0b319]42
43#include <errno.h>
44
[9b8be79]45#include <signal.h>
[e8d3c6f5]46#include <assert.h>
[324d46b]47
[9b8be79]48#include <async.h>
49#include <malloc.h>
50#include <task.h>
51#include <stddef.h>
[2fc5072]52
[324d46b]53// TODO: test everything in this file
54
[7c3fb9b]55/*
56 * In some places in this file, phrase "normalized broken-down time" is used.
[e6165be]57 * This means time broken down to components (year, month, day, hour, min, sec),
58 * in which every component is in its proper bounds. Non-normalized time could
59 * e.g. be 2011-54-5 29:13:-5, which would semantically mean start of year 2011
60 * + 53 months + 4 days + 29 hours + 13 minutes - 5 seconds.
61 */
62
[324d46b]63int posix_daylight;
64long posix_timezone;
65char *posix_tzname[2];
66
[55b1efd]67/**
68 * Set timezone conversion information.
[4cf8ca6]69 */
[7f9df7b9]70void tzset(void)
[324d46b]71{
72 // TODO: read environment
73 posix_tzname[0] = (char *) "GMT";
74 posix_tzname[1] = (char *) "GMT";
75 posix_daylight = 0;
76 posix_timezone = 0;
77}
78
[55b1efd]79/**
80 * Converts a time value to a broken-down UTC time.
[1b20da0]81 *
[e6165be]82 * @param timer Time to convert.
83 * @param result Structure to store the result to.
84 * @return Value of result on success, NULL on overflow.
[4cf8ca6]85 */
[7f9df7b9]86struct tm *gmtime_r(const time_t *restrict timer,
[f8b6d34c]87 struct tm *restrict result)
[324d46b]88{
[0d0b319]89 if (failed(time_utc2tm(*timer, result))) {
[324d46b]90 return NULL;
91 }
92
93 return result;
[2fc5072]94}
95
[f7ea5400]96/**
97 * Converts a time value to a broken-down UTC time.
98 * (non reentrant version)
99 *
100 * @param timep Time to convert
101 * @return Pointer to a statically allocated structure that stores
102 * the result, NULL in case of error.
103 */
[7f9df7b9]104struct tm *gmtime(const time_t *restrict timep)
[f7ea5400]105{
106 static struct tm result;
107
[7f9df7b9]108 return gmtime_r(timep, &result);
[f7ea5400]109}
110
[55b1efd]111/**
112 * Converts a time value to a broken-down local time.
[1b20da0]113 *
[e6165be]114 * @param timer Time to convert.
115 * @param result Structure to store the result to.
116 * @return Value of result on success, NULL on overflow.
[4cf8ca6]117 */
[7f9df7b9]118struct tm *localtime_r(const time_t *restrict timer,
[f8b6d34c]119 struct tm *restrict result)
[3f466c33]120{
121 // TODO: deal with timezone
122 // currently assumes system and all times are in GMT
[7f9df7b9]123 return gmtime_r(timer, result);
[3f466c33]124}
125
[f7ea5400]126/**
127 * Converts a time value to a broken-down local time.
128 * (non reentrant version)
129 *
130 * @param timep Time to convert.
131 * @return Pointer to a statically allocated structure that stores
132 * the result, NULL in case of error.
133 */
[7f9df7b9]134struct tm *localtime(const time_t *restrict timep)
[f7ea5400]135{
136 static struct tm result;
137
[7f9df7b9]138 return localtime_r(timep, &result);
[f7ea5400]139}
140
[55b1efd]141/**
142 * Converts broken-down time to a string in format
143 * "Sun Jan 1 00:00:00 1970\n". (Obsolete)
[e6165be]144 *
145 * @param timeptr Broken-down time structure.
146 * @param buf Buffer to store string to, must be at least ASCTIME_BUF_LEN
147 * bytes long.
148 * @return Value of buf.
[4cf8ca6]149 */
[7f9df7b9]150char *asctime_r(const struct tm *restrict timeptr,
[324d46b]151 char *restrict buf)
152{
[664fc031]153 time_tm2str(timeptr, buf);
[f7ea5400]154 return buf;
155}
[324d46b]156
[f7ea5400]157/**
158 * Convers broken-down time to a string in format
159 * "Sun Jan 1 00:00:00 1970\n". (Obsolete)
160 * (non reentrant version)
161 *
162 * @param timeptr Broken-down time structure.
163 * @return Pointer to a statically allocated buffer that stores
164 * the result, NULL in case of error.
165 */
[7f9df7b9]166char *asctime(const struct tm *restrict timeptr)
[f7ea5400]167{
168 static char buf[ASCTIME_BUF_LEN];
[324d46b]169
[7f9df7b9]170 return asctime_r(timeptr, buf);
[2fc5072]171}
172
[55b1efd]173/**
[f7ea5400]174 * Converts the calendar time to a string in format
175 * "Sun Jan 1 00:00:00 1970\n" (Obsolete)
[1b20da0]176 *
[e6165be]177 * @param timer Time to convert.
178 * @param buf Buffer to store string to. Must be at least ASCTIME_BUF_LEN
179 * bytes long.
[f7ea5400]180 * @return Pointer to buf on success, NULL on failure.
[4cf8ca6]181 */
[7f9df7b9]182char *ctime_r(const time_t *timer, char *buf)
[3f466c33]183{
[0d0b319]184 if (failed(time_local2str(*timer, buf))) {
[3f466c33]185 return NULL;
186 }
[f7ea5400]187
188 return buf;
189}
190
191/**
192 * Converts the calendar time to a string in format
193 * "Sun Jan 1 00:00:00 1970\n" (Obsolete)
194 * (non reentrant version)
195 *
196 * @param timep Time to convert.
197 * @return Pointer to a statically allocated buffer that stores
198 * the result, NULL in case of error.
199 */
[7f9df7b9]200char *ctime(const time_t *timep)
[f7ea5400]201{
202 static char buf[ASCTIME_BUF_LEN];
203
[7f9df7b9]204 return ctime_r(timep, buf);
[2fc5072]205}
206
[55b1efd]207/**
208 * Get clock resolution. Only CLOCK_REALTIME is supported.
[4cf8ca6]209 *
[e6165be]210 * @param clock_id Clock ID.
211 * @param res Pointer to the variable where the resolution is to be written.
212 * @return 0 on success, -1 with errno set on failure.
[4cf8ca6]213 */
[7f9df7b9]214int clock_getres(clockid_t clock_id, struct timespec *res)
[3f466c33]215{
216 assert(res != NULL);
217
218 switch (clock_id) {
[3fafe5e0]219 case CLOCK_REALTIME:
220 res->tv_sec = 0;
[bd41ac52]221 res->tv_nsec = USEC2NSEC(1); /* Microsecond resolution. */
[3fafe5e0]222 return 0;
223 default:
224 errno = EINVAL;
225 return -1;
[3f466c33]226 }
227}
228
[55b1efd]229/**
230 * Get time. Only CLOCK_REALTIME is supported.
[1b20da0]231 *
[e6165be]232 * @param clock_id ID of the clock to query.
233 * @param tp Pointer to the variable where the time is to be written.
[55b1efd]234 * @return 0 on success, -1 with errno on failure.
[4cf8ca6]235 */
[7f9df7b9]236int clock_gettime(clockid_t clock_id, struct timespec *tp)
[3f466c33]237{
[013e5d32]238 struct timeval tv;
239
[3f466c33]240 assert(tp != NULL);
241
242 switch (clock_id) {
[3fafe5e0]243 case CLOCK_REALTIME:
244 gettimeofday(&tv, NULL);
245 tp->tv_sec = tv.tv_sec;
[bd41ac52]246 tp->tv_nsec = USEC2NSEC(tv.tv_usec);
[3fafe5e0]247 return 0;
248 default:
249 errno = EINVAL;
250 return -1;
[3f466c33]251 }
252}
253
[55b1efd]254/**
255 * Set time on a specified clock. As HelenOS doesn't support this yet,
256 * this function always fails.
[1b20da0]257 *
[e6165be]258 * @param clock_id ID of the clock to set.
259 * @param tp Time to set.
260 * @return 0 on success, -1 with errno on failure.
[4cf8ca6]261 */
[7f9df7b9]262int clock_settime(clockid_t clock_id,
263 const struct timespec *tp)
[3f466c33]264{
265 assert(tp != NULL);
266
267 switch (clock_id) {
[3fafe5e0]268 case CLOCK_REALTIME:
269 // TODO: setting clock
270 // FIXME: HelenOS doesn't actually support hardware
271 // clock yet
272 errno = EPERM;
273 return -1;
274 default:
275 errno = EINVAL;
276 return -1;
[3f466c33]277 }
278}
279
[55b1efd]280/**
281 * Sleep on a specified clock.
[1b20da0]282 *
[e6165be]283 * @param clock_id ID of the clock to sleep on (only CLOCK_REALTIME supported).
284 * @param flags Flags (none supported).
285 * @param rqtp Sleep time.
286 * @param rmtp Remaining time is written here if sleep is interrupted.
287 * @return 0 on success, -1 with errno set on failure.
[4cf8ca6]288 */
[7f9df7b9]289int clock_nanosleep(clockid_t clock_id, int flags,
290 const struct timespec *rqtp, struct timespec *rmtp)
[3f466c33]291{
292 assert(rqtp != NULL);
293 assert(rmtp != NULL);
294
295 switch (clock_id) {
[3fafe5e0]296 case CLOCK_REALTIME:
297 // TODO: interruptible sleep
298 if (rqtp->tv_sec != 0) {
[5f97ef44]299 fibril_sleep(rqtp->tv_sec);
[3fafe5e0]300 }
301 if (rqtp->tv_nsec != 0) {
[bd41ac52]302 fibril_usleep(NSEC2USEC(rqtp->tv_nsec));
[3fafe5e0]303 }
304 return 0;
305 default:
306 errno = EINVAL;
307 return -1;
[3f466c33]308 }
309}
310
[bd41ac52]311int gettimeofday(struct timeval *tv, void *tz)
[823a929]312{
[bd41ac52]313 struct timespec ts;
314
315 getrealtime(&ts);
316 tv->tv_sec = ts.tv_sec;
317 tv->tv_usec = NSEC2USEC(ts.tv_nsec);
[06cb827]318
[bd41ac52]319 return 0;
[823a929]320}
321
[2fc5072]322/** @}
323 */
Note: See TracBrowser for help on using the repository browser.