[PATCH] select: fix returned timeval
With David Woodhouse <dwmw2@infradead.org> select() presently has a habit of increasing the value of the user's `timeout' argument on return. We were writing back a timeout larger than the original. We _deliberately_ round up, since we know we must wait at _least_ as long as the caller asks us to. The patch adds a couple of helper functions for magnitude comparison of timespecs and of timevals, and uses them to prevent the various poll and select functions from returning a timeout which is larger than the one which was passed in. The patch also fixes a bug in compat_sys_pselect7(): it was adding the new timeout value to the old one and was returning that. It should just return the new timeout value. (We have various handy timespec/timeval-to-from-nsec conversion functions in time.h. But this code open-codes it all). Cc: "David S. Miller" <davem@davemloft.net> Cc: Andi Kleen <ak@muc.de> Cc: Ulrich Drepper <drepper@redhat.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: george anzinger <george@mvista.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:

committed by
Linus Torvalds

parent
33042a9ff4
commit
643a654540
@@ -33,11 +33,34 @@ struct timezone {
|
||||
#define NSEC_PER_SEC 1000000000L
|
||||
#define NSEC_PER_USEC 1000L
|
||||
|
||||
static __inline__ int timespec_equal(struct timespec *a, struct timespec *b)
|
||||
static inline int timespec_equal(struct timespec *a, struct timespec *b)
|
||||
{
|
||||
return (a->tv_sec == b->tv_sec) && (a->tv_nsec == b->tv_nsec);
|
||||
}
|
||||
|
||||
/*
|
||||
* lhs < rhs: return <0
|
||||
* lhs == rhs: return 0
|
||||
* lhs > rhs: return >0
|
||||
*/
|
||||
static inline int timespec_compare(struct timespec *lhs, struct timespec *rhs)
|
||||
{
|
||||
if (lhs->tv_sec < rhs->tv_sec)
|
||||
return -1;
|
||||
if (lhs->tv_sec > rhs->tv_sec)
|
||||
return 1;
|
||||
return lhs->tv_nsec - rhs->tv_nsec;
|
||||
}
|
||||
|
||||
static inline int timeval_compare(struct timeval *lhs, struct timeval *rhs)
|
||||
{
|
||||
if (lhs->tv_sec < rhs->tv_sec)
|
||||
return -1;
|
||||
if (lhs->tv_sec > rhs->tv_sec)
|
||||
return 1;
|
||||
return lhs->tv_usec - rhs->tv_usec;
|
||||
}
|
||||
|
||||
extern unsigned long mktime(const unsigned int year, const unsigned int mon,
|
||||
const unsigned int day, const unsigned int hour,
|
||||
const unsigned int min, const unsigned int sec);
|
||||
|
Reference in New Issue
Block a user