mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-02-15 04:32:24 +00:00
libast: backport tvsleep(3) from ksh 93v- (re: 2db9953a
)
src/lib/libast/tm/tvsleep.c: - Since the 'sleep' builtin was backported/fixed from ksh93v- and ksh2020, it makes sense to use the latest/last tvsleep(3), too. Looks like this added an interrupt check (errno == EINTR). Also, new fallback versions for systems without nanosleep(2). Documentation: src/lib/libast/man/tv.3 (unchanged)
This commit is contained in:
parent
a3f4ef7adf
commit
2f7918deec
1 changed files with 126 additions and 57 deletions
|
@ -1,7 +1,7 @@
|
|||
/***********************************************************************
|
||||
* *
|
||||
* This software is part of the ast package *
|
||||
* Copyright (c) 1985-2011 AT&T Intellectual Property *
|
||||
* Copyright (c) 1985-2013 AT&T Intellectual Property *
|
||||
* and is licensed under the *
|
||||
* Eclipse Public License, Version 1.0 *
|
||||
* by AT&T Intellectual Property *
|
||||
|
@ -14,34 +14,30 @@
|
|||
* AT&T Research *
|
||||
* Florham Park NJ *
|
||||
* *
|
||||
* Glenn Fowler <gsf@research.att.com> *
|
||||
* David Korn <dgk@research.att.com> *
|
||||
* Phong Vo <kpv@research.att.com> *
|
||||
* Glenn Fowler <glenn.s.fowler@gmail.com> *
|
||||
* David Korn <dgkorn@gmail.com> *
|
||||
* Phong Vo <phongvo@gmail.com> *
|
||||
* *
|
||||
***********************************************************************/
|
||||
#pragma prototyped
|
||||
|
||||
#include <tv.h>
|
||||
#include <tm.h>
|
||||
#include <error.h>
|
||||
|
||||
#include "FEATURE/tvlib"
|
||||
|
||||
#if !_lib_nanosleep
|
||||
#if !_lib_nanosleep && !_lib_usleep
|
||||
# if _lib_select
|
||||
# if _sys_select
|
||||
# include <sys/select.h>
|
||||
# else
|
||||
# include <sys/socket.h>
|
||||
# endif
|
||||
# else
|
||||
# if !_lib_usleep
|
||||
# if _lib_poll_notimer
|
||||
# undef _lib_poll
|
||||
# endif
|
||||
# if _lib_poll
|
||||
# include <poll.h>
|
||||
# endif
|
||||
# endif
|
||||
# elif _lib_poll_notimer
|
||||
# undef _lib_poll
|
||||
# elif _lib_poll
|
||||
# include <poll.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
@ -49,6 +45,8 @@
|
|||
* sleep for tv
|
||||
* non-zero exit if sleep did not complete
|
||||
* with remaining time in rv
|
||||
*
|
||||
* NOTE: some systems hide nanosleep() outside of libc
|
||||
*/
|
||||
|
||||
int
|
||||
|
@ -63,7 +61,7 @@ tvsleep(register const Tv_t* tv, register Tv_t* rv)
|
|||
|
||||
stv.tv_sec = tv->tv_sec;
|
||||
stv.tv_nsec = tv->tv_nsec;
|
||||
if ((r = nanosleep(&stv, &srv)) && rv)
|
||||
if ((r = nanosleep(&stv, &srv)) && errno == EINTR && rv)
|
||||
{
|
||||
rv->tv_sec = srv.tv_sec;
|
||||
rv->tv_nsec = srv.tv_nsec;
|
||||
|
@ -72,72 +70,143 @@ tvsleep(register const Tv_t* tv, register Tv_t* rv)
|
|||
|
||||
#else
|
||||
|
||||
Tv_t bv;
|
||||
|
||||
tvgettime(&bv);
|
||||
{
|
||||
|
||||
#if _lib_select
|
||||
|
||||
struct timeval stv;
|
||||
|
||||
stv.tv_sec = tv->tv_sec;
|
||||
stv.tv_usec = tv->tv_nsec / 1000;
|
||||
if (select(0, NiL, NiL, NiL, &stv) < 0)
|
||||
{
|
||||
if (rv)
|
||||
*rv = *tv;
|
||||
return -1;
|
||||
}
|
||||
if (rv)
|
||||
{
|
||||
rv->tv_sec = stv.tv_sec;
|
||||
rv->tv_nsec = stv.tv_usec * 1000;
|
||||
}
|
||||
return 0;
|
||||
if (!(stv.tv_usec = tv->tv_nsec / 1000))
|
||||
stv.tv_usec = 1;
|
||||
if (select(0, NiL, NiL, NiL, &stv) >= 0)
|
||||
return 0;
|
||||
|
||||
#else
|
||||
|
||||
unsigned int s = tv->tv_sec;
|
||||
uint32_t n = tv->tv_nsec;
|
||||
uint32_t s = tv->tv_sec;
|
||||
uint32_t n = tv->tv_nsec;
|
||||
unsigned int t;
|
||||
|
||||
#if _lib_usleep
|
||||
|
||||
|
||||
unsigned long t;
|
||||
|
||||
if (t = (n + 999L) / 1000L)
|
||||
if (s < (0x7fffffff / 1000000))
|
||||
{
|
||||
usleep(t);
|
||||
s -= t / 1000000L;
|
||||
n = 0;
|
||||
int oerrno;
|
||||
|
||||
oerrno = errno;
|
||||
errno = 0;
|
||||
usleep(s * 1000000 + n / 1000);
|
||||
if (!errno)
|
||||
{
|
||||
errno = oerrno;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
#endif
|
||||
|
||||
if (s += (n + 999999999L) / 1000000000L)
|
||||
{
|
||||
while (s)
|
||||
{
|
||||
if (s > UINT_MAX)
|
||||
{
|
||||
t = UINT_MAX;
|
||||
s -= UINT_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
t = s;
|
||||
s = 0;
|
||||
}
|
||||
if (t = sleep(t))
|
||||
{
|
||||
if (rv)
|
||||
{
|
||||
rv->tv_sec = s + t;
|
||||
rv->tv_nsec = 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if _lib_usleep
|
||||
|
||||
if (t = (n + 999L) / 1000L)
|
||||
{
|
||||
int oerrno;
|
||||
|
||||
oerrno = errno;
|
||||
errno = 0;
|
||||
usleep(t);
|
||||
if (!errno)
|
||||
{
|
||||
errno = oerrno;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#if _lib_poll
|
||||
#elif _lib_poll
|
||||
|
||||
struct pollfd pfd;
|
||||
int t;
|
||||
|
||||
if ((t = (n + 999999L) / 1000000L) > 0)
|
||||
{
|
||||
poll(&pfd, 0, t);
|
||||
s -= t / 1000L;
|
||||
n = 0;
|
||||
if (!(t = (n + 999999L) / 1000000L))
|
||||
t = 1;
|
||||
if (poll(&pfd, 0, t) >= 0)
|
||||
return 0;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
if ((s += (n + 999999999L) / 1000000000L) && (s = sleep(s)))
|
||||
bad:
|
||||
if (errno == EINTR && rv)
|
||||
{
|
||||
if (rv)
|
||||
tvgettime(rv);
|
||||
if (rv->tv_nsec < bv.tv_nsec)
|
||||
{
|
||||
rv->tv_sec = s;
|
||||
rv->tv_nsec += 1000000000L;
|
||||
rv->tv_sec--;
|
||||
}
|
||||
rv->tv_nsec -= bv.tv_nsec;
|
||||
rv->tv_sec -= bv.tv_sec;
|
||||
if (rv->tv_sec > tv->tv_sec)
|
||||
{
|
||||
rv->tv_sec = 0;
|
||||
rv->tv_nsec = 0;
|
||||
}
|
||||
return -1;
|
||||
else
|
||||
{
|
||||
rv->tv_sec = tv->tv_sec - rv->tv_sec;
|
||||
if (rv->tv_nsec > tv->tv_nsec)
|
||||
{
|
||||
if (!rv->tv_sec)
|
||||
{
|
||||
rv->tv_sec = 0;
|
||||
rv->tv_nsec = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rv->tv_sec--;
|
||||
rv->tv_nsec = 1000000000L - rv->tv_nsec + tv->tv_nsec;
|
||||
}
|
||||
}
|
||||
else
|
||||
rv->tv_nsec = tv->tv_nsec - rv->tv_nsec;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
#endif
|
||||
return -1;
|
||||
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in a new issue