Add functions to load/set leap second table
This commit is contained in:
parent
e908febba2
commit
a0f747067d
|
@ -10,9 +10,12 @@
|
|||
/* Below are all the includes used throughout the library. */
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
/* Useful define to alleviate typos */
|
||||
|
|
|
@ -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
|
||||
kate: replace-trailing-space-save true; space-indent true; tab-width 4;
|
||||
vim: expandtab:ts=4:sw=4
|
||||
|
|
Loading…
Reference in New Issue