ОБЗОР
#define _BSD_SOURCE /* Смотрите feature_test_macros(7) */
#include <sys/timex.h>
int adjtimex(struct timex *buf);
ОПИСАНИЕ
В Linux для подстройки часов используется алгоритм Дэвида Л. Миллса (David
L. Mills) (см. RFC 5905). Системный вызов adjtimex() читает и
(необязательно) устанавливает параметры подстройки для этого алгоритма. В
качестве аргумента используется указатель на структуру timex, по
значениям в полях которой осуществляется обновление параметров ядра и в этой
же структуре происходит возврат текущих значений параметров ядра. Данная
структура объявлена так:
struct timex { int modes; /* выбор режима */ long offset; /* смещение по времени; в наносекундах, если флаг установлен состояния STA_NANO, иначе в микросекундах */ long freq; /* частота смещения, в единицах 2^-16 ppm (частей на миллион, смотрите
ЗАМЕЧАНИЯ далее) */ long maxerror; /* максимальная ошибка (микросекунды) */ long esterror; /* ожидаемая ошибка (микросекунды) */ int status; /* команда/состояние для часов */ long constant; /* временная константа PLL (phase-locked loop) */ long precision; /* точность часов (микросекунды, только чтение) */ long tolerance; /* допуск тактовой частоты (ppm, только чтение) */ struct timeval time; /* текущее время (только чтение, кроме ADJ_SETOFFSET); при возврате в time.tv_usec содержатся наносекунды, если установлен флаг состояния STA_NANO, иначе микросекунды */ long tick; /* микросекунд между тиками часов */ long ppsfreq; /* частота PPS (импульсов в секунду) (в единицах 2^-16 ppm, смотрите
ЗАМЕЧАНИЯ далее, только чтение) */ long jitter; /* искажение PPS (только чтение); в наносекундах, если установлен флаг состояния STA_NANO, иначе микросекунды */ int shift; /* длительность интервала PPS (секунды, только чтение) */ long stabil; /* устойчивость PPS (2^-16 ppm; смотрите
ЗАМЕЧАНИЯ, только чтение) */ long jitcnt; /* превышение ограничения искажения PPS (только чтение) */ long calcnt; /* интервалы калибровки PPS (только чтение) */ long errcnt; /* ошибки калибровки PPS (только чтение) */ long stbcnt; /* превышение ограничения устойчивости PPS (только чтение) */ int tai; /* смещение TAI, задаваемое предыдущей операцией ADJ_TAI (секунды, только чтение, начиная с Linux 2.6.26) */ /* далее идут байты заполнения, для расширения структуры в будущем */ };
Поле modes определяет какие параметры, если это необходимо, устанавливаются. Является битовой маской, содержащей комбинации (or) нуля или более следующих бит:
ADJ_OFFSET Установить смещение по времени из buf.offset.
ADJ_FREQUENCY Установить смещение частоты из buf.freq.
ADJ_MAXERROR Установить максимальную ошибку времени из buf.maxerror.
ADJ_ESTERROR Установить ожидаемую ошибку времени из buf.esterror.
ADJ_STATUS Установить состояние часов из buf.status.
ADJ_TIMECONST Установить константу времени PLL из buf.constant. Если не задан флаг состояния STA_NANO (смотрите ниже), то ядро добавляет к этому значению 4.
ADJ_SETOFFSET (начиная с Linux 2.6.29) Добавить buf.time к текущему времени. Если в buf.status указан флаг ADJ_NANO, то значение buf.time.tv_usec считается заданным в наносекундах; в противном случае это микросекунды.
ADJ_MICRO (начиная с Linux 2.6.36) Выбрать микросекундной разрешение.
ADJ_NANO (начиная с Linux 2.6.36) Выбрать наносекундной разрешение. Должно быть указано что-то одно: ADJ_MICRO или ADJ_NANO.
ADJ_TAI (начиная с Linux 2.6.26) Установить смещение TAI (атомное международное время) из buf->константы.
ADJ_TAI не должно использоваться вместе с ADJ_TIMECONST, так как последний режим также использует поле buf->константа.
Подробное описание TAI и различия между TAI и UTC смотрите в BIPM
ADJ_TICK Установить значение тика из buf.tick.
Также в modes можно указывать любое из следующих значений (многобитовая маска), биты которых нельзя указать в modes:
ADJ_OFFSET_SINGLESHOT Старый вариант adjtime(): (постепенно) корректировать время значением, указанным в buf.offset, которое задаётся в микросекундах.
ADJ_OFFSET_SS_READ (работает, начиная с Linux 2.6.28) Получить (в buf.offset) остаток необходимого откорректированного времени после выполнения операции ADJ_OFFSET_SINGLESHOT. Это возможность была добавлена в Linux 2.6.24, но работала неправильно до Linux 2.6.28.
Обычные пользователи могут задавать в modes значение ноль или ADJ_OFFSET_SS_READ. Только суперпользователь может задавать любые параметры.
Поле buf.status представляет собой битовую маску, используется для установки/получения битов состояния, связанных с реализацией NTP. Одни биты в маске можно и читать, и изменять, другие — только читать.
STA_PLL Включить обновление фазовой подстройки частоты (PLL) (чтение/запись) через ADJ_OFFSET.
STA_PPSFREQ Включить частотную дисциплину обслуживания PPS (чтение/запись).
STA_PPSTIME Включить временную дисциплину обслуживания PPS (чтение/запись).
STA_FLL Выбрать режим частотной подстройки частоты (FLL) (чтение/запись).
STA_INS Вставить високосную секунду (чтение/запись).
STA_DEL Удалить високосную секунду (чтение/запись).
STA_UNSYNC Часы не синхронизированы (чтение/запись).
STA_FREQHOLD Зафиксировать частоту (чтение/запись).
STA_PPSSIGNAL Присутствует сигнал PPS (только чтение).
STA_PPSJITTER Превышено искажение сигнала PPS (только чтение).
STA_PPSWANDER Превышено отклонение сигнала PPS (только чтение).
STA_PPSERROR Ошибка калибровки сигнала PPS (только чтение).
STA_CLOCKERR Проблема с аппаратурой часов (только чтение).
STA_NANO (начиная с Linux 2.6.26) Единица данных (0 = микросекунды, 1 = наносекунды; только чтение). Устанавливается с помощью ADJ_NANO, очищается с помощью ADJ_MICRO.
STA_MODE (начиная с Linux 2.6.26) Режим (0 = фазовая подстройка частоты, 1 = частотная подстройка частоты; только чтение).
STA_CLK (начиная с Linux 2.6.26) Источник часов (0 = A, 1 = B; только чтение).
Попытки установить биты status, помеченные только для чтения, просто игнорируются.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении adjtimex() возвращает состояние часов; то есть
одно из следующих значений:
TIME_OK Часы синхронизированы.
TIME_INS Вставлена високосная секунда.
TIME_DEL Удалена високосная секунда.
TIME_OOP Происходит учёт високосной секунды.
TIME_WAIT Прошла високосная секунда.
TIME_ERROR Часы не синхронизированы. Символическое имя TIME_BAD — синоним TIME_ERROR, предоставляется для обратной совместимости.
При ошибке adjtimex() возвращается -1 и изменяется errno.
ОШИБКИ
EFAULT buf не является указателем на доступную для записи область памяти.
EINVAL Предпринята попытка установить buf.offset в значение, выходящее за диапазон от -131071 до +131071, или установить buf.status в значение отличное от перечисленных выше, или установить buf.tick в значение за пределами диапазона от 900000/HZ до 1100000/HZ, где HZ — частота прерываний системного таймера.
EPERM Значение buf.modes не равно 0 или ADJ_OFFSET_SS_READ и вызывающий не имеет необходимых прав. В Linux для этого требуется мандат CAP_SYS_TIME.