Tag
Hash :
3ac95524
Author :
Date :
2007-02-12T18:49:19
New module 'time', so that apps can include <time.h> as per POSIX and GNU instead of separate include files like time_r.h and timegm.h. This implementation tries out a simpler approach for replacing decls in standard include files (as compared to the string module), somewhat as an experiment. * config/srclist.txt: Comment out mktime.c for now. * doc/gnulib-tool.texi (Initial import): Don't use time_r as an example since it doesn't apply any more. Use generic wording instead. * MODULES.html.sh (Support for systems lacking POSIX:2001): New module 'time'. * lib/time_.h, m4/time_h.m4, modules/time: New files. * lib/strptime.h, lib/time_r.h, lib/timegm.h: Remove. * lib/mktime.c: Include config.h depending on _LIBC, not HAVE_CONFIG_H. Don't include <sys/types.h>; no longer needed since we assume C89. * lib/mktime.c: Don't include "time_r.h"; no longer needed. * lib/strftime.c: Likewise. * lib/time_r.c: Likewise. * lib/nanosleep.c (nanosleep): #undef after include files, not before. * lib/nanosleep.c: Include <time.h> first, to check interface. * lib/strptime.c: Likewise. * lib/time_r.c: Likewise. * lib/timegm.c: Likewise. * lib/strptime.c: Don't include strptime.h or time_r.h; no longer needed. * lib/timegm.c: Don't include timegm.h; no longer needed. * lib/timespec.h: Don't include <sys/time.h> before <time.h>; time.h now handles any problems in that area. (struct timespec, nanosleep): Remove; time.h now arranges for these. * lib/xnanosleep.c: Don't include timespec.h; no longer needed now that time.h defines struct timespec. * m4/nanosleep.m4 (gl_FUNC_NANOSLEEP): Check that nanosleep is declared. Set REPLACE_NANOSLEEP. Don't AC_DEFINE nanosleep; the time module now handles that. * m4/strptime.m4 (gl_FUNC_STPRTIME): Set REPLACE_STRPTIME. * m4/time_r.m4 (gl_TIME_R): Don't define HAVE_TIME_R_POSIX; no longer needed. Set REPLACE_LOCALTIME. * m4/timegm.m4 (gl_FUNC_TIMEGM): Set REPLACE_TIMEGM. * m4/timespec.m4 (gl_CHECK_TYPE_STRUCT_TIMESPEC): Move to time_h.m4. (gl_TIMESPEC): Don't check for sys/time.h or struct timespec or nanosleep; time_h.m4 now does that. Don't require gl_USE_SYSTEM_EXTENSIONS; no longer needed directly, and the time module handles this now. * modules/getdate (Depends-on): Remove timespec. Add time. * modules/nanosleep (Depends-on): Likewise. * modules/stat-time (Depends-on): Likewise. * modules/nanosleep (Include): Include time.h, not timespec.h. * modules/strptime (Files): Remove lib/strptime.h. (Depends-on): Add extensions, time. (Include): Include time.h, not strptime.h. * modules/time_r (Files): Remove lib/time_r.h. (Depends-on): Add time. (Include): Include time.h, not time_r.h. * modules/timegm: Likewise. * modules/timespec (Description): Now does timespec-related decls of our own, instead of struct timespec itself. (Depends-on): Add time; remove extensions. (Maintainer): Add self. * modules/utimecmp (Depends-on): Add time; remove timespec. * modules/utimens (Depends-on): Likewise. * modules/xnanosleep (Depends-on): Likewise.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
/* Provide a replacement for the POSIX nanosleep function.
Copyright (C) 1999, 2000, 2002, 2004, 2005, 2006, 2007 Free
Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
/* written by Jim Meyering */
#include <config.h>
#include <time.h>
#include "timespec.h"
#include <stdbool.h>
#include <stdio.h>
#include <sys/types.h>
#if HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif
#include <signal.h>
#include <sys/time.h>
#include <errno.h>
#include <unistd.h>
#undef nanosleep
enum { BILLION = 1000 * 1000 * 1000 };
#if HAVE_BUG_BIG_NANOSLEEP
void
getnow (struct timespec *t)
{
# if defined CLOCK_MONOTONIC && HAVE_CLOCK_GETTIME
if (clock_gettime (CLOCK_MONOTONIC, t) == 0)
return;
# endif
gettime (t);
}
int
rpl_nanosleep (const struct timespec *requested_delay,
struct timespec *remaining_delay)
{
/* nanosleep mishandles large sleeps due to internal overflow
problems, so check that the proper amount of time has actually
elapsed. */
struct timespec delay = *requested_delay;
struct timespec t0;
getnow (&t0);
for (;;)
{
int r = nanosleep (&delay, remaining_delay);
if (r == 0)
{
time_t secs_sofar;
struct timespec now;
getnow (&now);
secs_sofar = now.tv_sec - t0.tv_sec;
if (requested_delay->tv_sec < secs_sofar)
return 0;
delay.tv_sec = requested_delay->tv_sec - secs_sofar;
delay.tv_nsec = requested_delay->tv_nsec - (now.tv_nsec - t0.tv_nsec);
if (delay.tv_nsec < 0)
{
if (delay.tv_sec == 0)
return 0;
delay.tv_nsec += BILLION;
delay.tv_sec--;
}
else if (BILLION <= delay.tv_nsec)
{
delay.tv_nsec -= BILLION;
delay.tv_sec++;
}
}
}
}
#else
/* Some systems (MSDOS) don't have SIGCONT.
Using SIGTERM here turns the signal-handling code below
into a no-op on such systems. */
# ifndef SIGCONT
# define SIGCONT SIGTERM
# endif
# if ! HAVE_SIGINTERRUPT
# define siginterrupt(sig, flag) /* empty */
# endif
static sig_atomic_t volatile suspended;
/* Handle SIGCONT. */
static void
sighandler (int sig)
{
suspended = 1;
}
/* Suspend execution for at least *TS_DELAY seconds. */
static void
my_usleep (const struct timespec *ts_delay)
{
struct timeval tv_delay;
tv_delay.tv_sec = ts_delay->tv_sec;
tv_delay.tv_usec = (ts_delay->tv_nsec + 999) / 1000;
if (tv_delay.tv_usec == 1000000)
{
time_t t1 = tv_delay.tv_sec + 1;
if (t1 < tv_delay.tv_sec)
tv_delay.tv_usec = 1000000 - 1; /* close enough */
else
{
tv_delay.tv_sec = t1;
tv_delay.tv_usec = 0;
}
}
select (0, NULL, NULL, NULL, &tv_delay);
}
/* Suspend execution for at least *REQUESTED_DELAY seconds. The
*REMAINING_DELAY part isn't implemented yet. */
int
rpl_nanosleep (const struct timespec *requested_delay,
struct timespec *remaining_delay)
{
static bool initialized;
/* set up sig handler */
if (! initialized)
{
# ifdef SA_NOCLDSTOP
struct sigaction oldact, newact;
newact.sa_handler = sighandler;
sigemptyset (&newact.sa_mask);
newact.sa_flags = 0;
sigaction (SIGCONT, NULL, &oldact);
if (oldact.sa_handler != SIG_IGN)
sigaction (SIGCONT, &newact, NULL);
# else
if (signal (SIGCONT, SIG_IGN) != SIG_IGN)
{
signal (SIGCONT, sighandler);
siginterrupt (SIGCONT, 1);
}
# endif
initialized = true;
}
suspended = 0;
my_usleep (requested_delay);
if (suspended)
{
/* Calculate time remaining. */
/* FIXME: the code in sleep doesn't use this, so there's no
rush to implement it. */
errno = EINTR;
}
/* FIXME: Restore sig handler? */
return suspended;
}
#endif