Add functions to load/set leap second table

This commit is contained in:
Laurence Withers 2009-01-03 19:21:46 +00:00
parent e908febba2
commit a0f747067d
2 changed files with 77 additions and 0 deletions

View File

@ -10,9 +10,12 @@
/* Below are all the includes used throughout the library. */ /* Below are all the includes used throughout the library. */
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/time.h> #include <sys/time.h>
/* Useful define to alleviate typos */ /* Useful define to alleviate typos */

View File

@ -73,6 +73,80 @@ int iso8601_leap_elapsed(const struct iso8601_date* start, const struct iso8601_
void iso8601_leap_table_set(int* new_table, int new_size)
{
leap_second_days = new_table;
leap_second_days_num = new_size;
}
static const char* leap_table_signature = "/O9PdPZI";
int iso8601_leap_table_load(const char* fname)
{
struct stat st;
int fd, saved_errno, i, new_size, * days = 0;
char buf[12];
if(stat(fname, &st)) return -1;
if(st.st_size < 12) {
errno = EINVAL;
return -1;
}
fd = open(fname, O_RDONLY);
if(fd == -1) return -1;
if(TEMP_FAILURE_RETRY( read(fd, buf, 12) ) != 12) goto outerr;
if(memcmp(buf, leap_table_signature, 8)) {
errno = EINVAL;
return -1;
}
#define GET_UINT32(_from) ( \
( ((uint8_t*)_from)[0] << 24 ) | \
( ((uint8_t*)_from)[1] << 16 ) | \
( ((uint8_t*)_from)[2] << 8 ) | \
( ((uint8_t*)_from)[3] ) \
)
new_size = GET_UINT32(buf + 8);
if((12 + new_size * 4) != st.st_size) {
errno = EINVAL;
goto outerr;
}
days = malloc(sizeof(int) * new_size);
if(!days) goto outerr;
for(i = 0; i < new_size; ++i) {
if(TEMP_FAILURE_RETRY( read(fd, buf, 4) ) != 4) goto outerr;
days[i] = GET_UINT32(buf);
if(i && days[i] <= days[i - 1]) {
errno = EINVAL;
goto outerr;
}
}
TEMP_FAILURE_RETRY( close(fd) );
iso8601_leap_table_set(days, new_size);
return 0;
#undef GET_UINT32
outerr:
saved_errno = errno;
free(days);
TEMP_FAILURE_RETRY( close(fd) );
errno = saved_errno;
return -1;
}
/* options for text editors /* options for text editors
kate: replace-trailing-space-save true; space-indent true; tab-width 4; kate: replace-trailing-space-save true; space-indent true; tab-width 4;
vim: expandtab:ts=4:sw=4 vim: expandtab:ts=4:sw=4