tvsleep.c revision 34f9b3eef6fdadbda0a846aa4d68691ac40eace5
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1985-2009 AT&T Intellectual Property *
* and is licensed under the *
* Common Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* http://www.opensource.org/licenses/cpl1.0.txt *
* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* David Korn <dgk@research.att.com> *
* Phong Vo <kpv@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
#include <tv.h>
#include <tm.h>
#include "FEATURE/tvlib"
#if !_lib_nanosleep
# 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
# endif
#endif
/*
* sleep for tv
* non-zero exit if sleep did not complete
* with remaining time in rv
*/
int
tvsleep(register const Tv_t* tv, register Tv_t* rv)
{
#if _lib_nanosleep
struct timespec stv;
struct timespec srv;
int r;
stv.tv_sec = tv->tv_sec;
stv.tv_nsec = tv->tv_nsec;
if ((r = nanosleep(&stv, &srv)) && rv)
{
rv->tv_sec = srv.tv_sec;
rv->tv_nsec = srv.tv_nsec;
}
return r;
#else
#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;
#else
unsigned int s = tv->tv_sec;
uint32_t n = tv->tv_nsec;
#if _lib_usleep
unsigned long t;
if (t = (n + 999L) / 1000L)
{
usleep(t);
s -= t / 1000000L;
n = 0;
}
#else
#if _lib_poll
struct pollfd pfd;
int t;
if ((t = (n + 999999L) / 1000000L) > 0)
{
poll(&pfd, 0, t);
s -= t / 1000L;
n = 0;
}
#endif
#endif
if ((s += (n + 999999999L) / 1000000000L) && (s = sleep(s)))
{
if (rv)
{
rv->tv_sec = s;
rv->tv_nsec = 0;
}
return -1;
}
return 0;
#endif
#endif
}