diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2005-08-05 11:31:33 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2005-08-05 11:31:33 +0000 |
commit | 8cba692063d085c2a5a3095d71c7bafc45722bf6 (patch) | |
tree | 01796bd0b304a710f13610cedafec924e44af0f0 /winsup | |
parent | d607be551d90ec42a5441b5a865a81b7db9f01d8 (diff) | |
download | cygnal-8cba692063d085c2a5a3095d71c7bafc45722bf6.tar.gz cygnal-8cba692063d085c2a5a3095d71c7bafc45722bf6.tar.bz2 cygnal-8cba692063d085c2a5a3095d71c7bafc45722bf6.zip |
* thread.cc (pthread_cond_timedwait): Check abstime for validity
according to SUSv3. Rewrite timeout check and waitlength calculation
to avoid overflow problems.
Diffstat (limited to 'winsup')
-rw-r--r-- | winsup/cygwin/ChangeLog | 6 | ||||
-rw-r--r-- | winsup/cygwin/thread.cc | 20 |
2 files changed, 22 insertions, 4 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index a8eec0fe8..bd28a343e 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,9 @@ +2005-08-05 Corinna Vinschen <corinna@vinschen.de> + + * thread.cc (pthread_cond_timedwait): Check abstime for validity + according to SUSv3. Rewrite timeout check and waitlength calculation + to avoid overflow problems. + 2005-08-02 Yitzchak Scott-Thoennes <sthoenna@efn.org> * include/sys/termios.h: Define TIOCMBIS and TIOCMBIC. diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index ea4f64930..03bebb1a3 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -2615,7 +2615,7 @@ pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime) { struct timeval tv; - long waitlength; + DWORD waitlength; myfault efault; if (efault.faulted ()) @@ -2623,11 +2623,23 @@ pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex, pthread_testcancel (); + /* According to SUSv3, the abstime value must be checked for validity. */ + if (abstime->tv_sec < 0 + || abstime->tv_nsec < 0 + || abstime->tv_nsec > 999999999) + return EINVAL; + gettimeofday (&tv, NULL); - waitlength = abstime->tv_sec * 1000 + abstime->tv_nsec / (1000 * 1000); - waitlength -= tv.tv_sec * 1000 + tv.tv_usec / 1000; - if (waitlength < 0) + /* Check for immediate timeout before converting to microseconds, since + the resulting value can easily overflow long. This also allows to + evaluate microseconds directly in DWORD. */ + if (tv.tv_sec > abstime->tv_sec + || (tv.tv_sec == abstime->tv_sec + && tv.tv_usec > abstime->tv_nsec / 1000)) return ETIMEDOUT; + + waitlength = (abstime->tv_sec - tv.tv_sec) * 1000; + waitlength += (abstime->tv_nsec / 1000 - tv.tv_usec) / 1000; return __pthread_cond_dowait (cond, mutex, waitlength); } |