Clamp maximum adjustment to numerical limit.

On 32 bit platforms, a PHC driver might allow a larger adjustment than
can fit into the 'long' type used in the clock_adjtime interface. This
patch fixes the issue by using the smaller of the two maxima.

Signed-off-by: Richard Cochran <richardcochran@gmail.com>
master
Richard Cochran 2012-05-05 12:48:48 +02:00
parent f2aae280b3
commit d7bcdca7a9
1 changed files with 16 additions and 2 deletions

18
phc.c
View File

@ -27,6 +27,15 @@
#include "phc.h" #include "phc.h"
/*
* On 32 bit platforms, the PHC driver's maximum adjustment (type
* 'int' in units of ppb) can overflow the timex.freq field (type
* 'long'). So in this case we clamp the maximum to the largest
* possible adjustment that fits into a 32 bit long.
*/
#define BITS_PER_LONG (sizeof(long)*8)
#define MAX_PPB_32 32767999 /* 2^31 - 1 / 65.536 */
clockid_t phc_open(char *phc) clockid_t phc_open(char *phc)
{ {
int fd = open(phc, O_RDWR); int fd = open(phc, O_RDWR);
@ -44,7 +53,7 @@ void phc_close(clockid_t clkid)
int phc_max_adj(clockid_t clkid) int phc_max_adj(clockid_t clkid)
{ {
int fd = CLOCKID_TO_FD(clkid); int fd = CLOCKID_TO_FD(clkid), max;
struct ptp_clock_caps caps; struct ptp_clock_caps caps;
if (ioctl(fd, PTP_CLOCK_GETCAPS, &caps)) { if (ioctl(fd, PTP_CLOCK_GETCAPS, &caps)) {
@ -52,5 +61,10 @@ int phc_max_adj(clockid_t clkid)
return 0; return 0;
} }
return caps.max_adj; max = caps.max_adj;
if (BITS_PER_LONG == 32 && max > MAX_PPB_32)
max = MAX_PPB_32;
return max;
} }