// posix.cc -- Helper functions for POSIX-flavored OSs. /* Copyright (C) 2000 Free Software Foundation This file is part of libgcj. This software is copyrighted work licensed under the terms of the Libgcj License. Please consult the file "LIBGCJ_LICENSE" for details. */ #include #include "posix.h" #include #if defined (ECOS) extern "C" unsigned long long _clock (void); #endif // gettimeofday implementation. void _Jv_gettimeofday (struct timeval *tv) { #if defined (HAVE_GETTIMEOFDAY) gettimeofday (tv, NULL); #elif defined (HAVE_TIME) tv->tv_sec = time (NULL); tv->tv_usec = 0; #elif defined (HAVE_FTIME) struct timeb t; ftime (&t); tv->tv_sec = t.time; tv->tv_usec = t.millitm * 1000; #elif defined (ECOS) // FIXME. tv->tv_sec = _clock () / 1000; tv->tv_usec = 0; #else // In the absence of any function, time remains forever fixed. tv->tv_sec = 23; tv->tv_usec = 0; #endif } // A wrapper for select() which ignores EINTR. int _Jv_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { #ifdef HAVE_SELECT // If we have a timeout, compute the absolute ending time. struct timeval end, delay; if (timeout) { _Jv_gettimeofday (&end); end.tv_usec += timeout->tv_usec; if (end.tv_usec >= 1000000) { ++end.tv_sec; end.tv_usec -= 1000000; } end.tv_sec += timeout->tv_sec; delay = *timeout; } else { // Placate compiler. delay.tv_sec = delay.tv_usec = 0; } while (1) { int r = select (n, readfds, writefds, exceptfds, timeout ? &delay : NULL); if (r != -1 || errno != EINTR) return r; struct timeval after; if (timeout) { _Jv_gettimeofday (&after); // Now compute new timeout argument. delay.tv_usec = end.tv_usec - after.tv_usec; delay.tv_sec = end.tv_sec - after.tv_sec; if (delay.tv_usec < 0) { --delay.tv_sec; delay.tv_usec += 1000000; } if (delay.tv_sec < 0) { // We assume that the user wants a valid select() call // more than precise timing. So if we get a series of // EINTR we just keep trying with delay 0 until we get a // valid result. delay.tv_sec = 0; } } } #else /* HAVE_SELECT */ return 0; #endif }