config: introduce a proper creation method.

Now that all of the legacy, open coded configuration fields are gone,
we can follow a normal create/destroy pattern for the configuration.
This patch add the new method and converts the programs to use it.

Signed-off-by: Richard Cochran <richardcochran@gmail.com>
master
Richard Cochran 2015-08-23 13:59:38 +02:00
parent 70ea3f3f32
commit 7b438defe5
5 changed files with 106 additions and 102 deletions

View File

@ -614,15 +614,23 @@ void config_init_interface(struct interface *iface, struct config *cfg)
sk_get_ts_info(iface->name, &iface->ts_info); sk_get_ts_info(iface->name, &iface->ts_info);
} }
int config_init(struct config *cfg) struct config *config_create(void)
{ {
char buf[CONFIG_LABEL_SIZE + 8]; char buf[CONFIG_LABEL_SIZE + 8];
struct config_item *ci; struct config_item *ci;
struct config *cfg;
int i; int i;
cfg = calloc(1, sizeof(*cfg));
if (!cfg) {
return NULL;
}
STAILQ_INIT(&cfg->interfaces);
cfg->htab = hash_create(); cfg->htab = hash_create();
if (!cfg->htab) { if (!cfg->htab) {
return -1; free(cfg);
return NULL;
} }
/* Populate the hash table with global defaults. */ /* Populate the hash table with global defaults. */
@ -646,10 +654,11 @@ int config_init(struct config *cfg)
goto fail; goto fail;
} }
} }
return 0; return cfg;
fail: fail:
hash_destroy(cfg->htab, NULL); hash_destroy(cfg->htab, NULL);
return -1; free(cfg);
return NULL;
} }
void config_destroy(struct config *cfg) void config_destroy(struct config *cfg)
@ -661,6 +670,7 @@ void config_destroy(struct config *cfg)
free(iface); free(iface);
} }
hash_destroy(cfg->htab, config_item_free); hash_destroy(cfg->htab, config_item_free);
free(cfg);
} }
double config_get_double(struct config *cfg, const char *section, double config_get_double(struct config *cfg, const char *section,

View File

@ -53,7 +53,7 @@ void config_destroy(struct config *cfg);
/* New, hash table based methods: */ /* New, hash table based methods: */
int config_init(struct config *cfg); struct config *config_create(void);
double config_get_double(struct config *cfg, const char *section, double config_get_double(struct config *cfg, const char *section,
const char *option); const char *option);

View File

@ -119,7 +119,7 @@ struct node {
struct clock *master; struct clock *master;
}; };
static struct config phc2sys_config; static struct config *phc2sys_config;
static int update_pmc(struct node *node, int subscribe); static int update_pmc(struct node *node, int subscribe);
static int clock_handle_leap(struct node *node, struct clock *clock, static int clock_handle_leap(struct node *node, struct clock *clock,
@ -224,7 +224,7 @@ static struct clock *clock_add(struct node *node, char *device)
} }
} }
c->servo = servo_create(&phc2sys_config, node->servo_type, c->servo = servo_create(phc2sys_config, node->servo_type,
-ppb, max_ppb, 0); -ppb, max_ppb, 0);
servo_sync_interval(c->servo, node->phc_interval); servo_sync_interval(c->servo, node->phc_interval);
@ -1225,7 +1225,7 @@ int main(int argc, char *argv[])
struct config *cfg; struct config *cfg;
int autocfg = 0, rt = 0; int autocfg = 0, rt = 0;
int c, domain_number = 0, pps_fd = -1; int c, domain_number = 0, pps_fd = -1;
int r, wait_sync = 0; int r = -1, wait_sync = 0;
int print_level = LOG_INFO, use_syslog = 1, verbose = 0; int print_level = LOG_INFO, use_syslog = 1, verbose = 0;
int ntpshm_segment; int ntpshm_segment;
double phc_rate, tmp; double phc_rate, tmp;
@ -1239,10 +1239,10 @@ int main(int argc, char *argv[])
handle_term_signals(); handle_term_signals();
if (config_init(&phc2sys_config)) { cfg = phc2sys_config = config_create();
if (!cfg) {
return -1; return -1;
} }
cfg = &phc2sys_config;
config_set_double(cfg, "pi_proportional_const", KP); config_set_double(cfg, "pi_proportional_const", KP);
config_set_double(cfg, "pi_integral_const", KI); config_set_double(cfg, "pi_integral_const", KI);
@ -1267,7 +1267,7 @@ int main(int argc, char *argv[])
if (pps_fd < 0) { if (pps_fd < 0) {
fprintf(stderr, fprintf(stderr,
"cannot open '%s': %m\n", optarg); "cannot open '%s': %m\n", optarg);
return -1; goto end;
} }
break; break;
case 'i': case 'i':
@ -1286,69 +1286,64 @@ int main(int argc, char *argv[])
} else { } else {
fprintf(stderr, fprintf(stderr,
"invalid servo name %s\n", optarg); "invalid servo name %s\n", optarg);
return -1; goto end;
} }
break; break;
case 'P': case 'P':
if (get_arg_val_d(c, optarg, &tmp, 0.0, DBL_MAX)) if (get_arg_val_d(c, optarg, &tmp, 0.0, DBL_MAX) ||
return -1; config_set_double(cfg, "pi_proportional_const", tmp))
if (config_set_double(cfg, "pi_proportional_const", tmp)) goto end;
return -1;
break; break;
case 'I': case 'I':
if (get_arg_val_d(c, optarg, &tmp, 0.0, DBL_MAX)) if (get_arg_val_d(c, optarg, &tmp, 0.0, DBL_MAX) ||
return -1; config_set_double(cfg, "pi_integral_const", tmp))
if (config_set_double(cfg, "pi_integral_const", tmp)) goto end;
return -1;
break; break;
case 'S': case 'S':
if (get_arg_val_d(c, optarg, &tmp, 0.0, DBL_MAX)) if (get_arg_val_d(c, optarg, &tmp, 0.0, DBL_MAX) ||
return -1; config_set_double(cfg, "step_threshold", tmp))
if (config_set_double(cfg, "step_threshold", tmp)) goto end;
return -1;
break; break;
case 'F': case 'F':
if (get_arg_val_d(c, optarg, &tmp, 0.0, DBL_MAX)) if (get_arg_val_d(c, optarg, &tmp, 0.0, DBL_MAX) ||
return -1; config_set_double(cfg, "first_step_threshold", tmp))
if (config_set_double(cfg, "first_step_threshold", tmp)) goto end;
return -1;
break; break;
case 'R': case 'R':
if (get_arg_val_d(c, optarg, &phc_rate, 1e-9, DBL_MAX)) if (get_arg_val_d(c, optarg, &phc_rate, 1e-9, DBL_MAX))
return -1; goto end;
node.phc_interval = 1.0 / phc_rate; node.phc_interval = 1.0 / phc_rate;
break; break;
case 'N': case 'N':
if (get_arg_val_i(c, optarg, &node.phc_readings, 1, INT_MAX)) if (get_arg_val_i(c, optarg, &node.phc_readings, 1, INT_MAX))
return -1; goto end;
break; break;
case 'O': case 'O':
if (get_arg_val_i(c, optarg, &node.sync_offset, if (get_arg_val_i(c, optarg, &node.sync_offset,
INT_MIN, INT_MAX)) INT_MIN, INT_MAX))
return -1; goto end;
node.forced_sync_offset = -1; node.forced_sync_offset = -1;
break; break;
case 'L': case 'L':
if (get_arg_val_i(c, optarg, &node.sanity_freq_limit, 0, INT_MAX)) if (get_arg_val_i(c, optarg, &node.sanity_freq_limit, 0, INT_MAX))
return -1; goto end;
break; break;
case 'M': case 'M':
if (get_arg_val_i(c, optarg, &ntpshm_segment, INT_MIN, INT_MAX)) if (get_arg_val_i(c, optarg, &ntpshm_segment, INT_MIN, INT_MAX) ||
return -1; config_set_int(cfg, "ntpshm_segment", ntpshm_segment))
if (config_set_int(cfg, "ntpshm_segment", ntpshm_segment)) goto end;
return -1;
break; break;
case 'u': case 'u':
if (get_arg_val_ui(c, optarg, &node.stats_max_count, if (get_arg_val_ui(c, optarg, &node.stats_max_count,
0, UINT_MAX)) 0, UINT_MAX))
return -1; goto end;
break; break;
case 'w': case 'w':
wait_sync = 1; wait_sync = 1;
break; break;
case 'n': case 'n':
if (get_arg_val_i(c, optarg, &domain_number, 0, 255)) if (get_arg_val_i(c, optarg, &domain_number, 0, 255))
return -1; goto end;
break; break;
case 'x': case 'x':
node.kernel_leap = 0; node.kernel_leap = 0;
@ -1357,17 +1352,16 @@ int main(int argc, char *argv[])
if (strlen(optarg) > MAX_IFNAME_SIZE) { if (strlen(optarg) > MAX_IFNAME_SIZE) {
fprintf(stderr, "path %s too long, max is %d\n", fprintf(stderr, "path %s too long, max is %d\n",
optarg, MAX_IFNAME_SIZE); optarg, MAX_IFNAME_SIZE);
return -1; goto end;
} }
if (config_set_string(&phc2sys_config, "uds_address", if (config_set_string(cfg, "uds_address", optarg)) {
optarg)) { goto end;
return -1;
} }
break; break;
case 'l': case 'l':
if (get_arg_val_i(c, optarg, &print_level, if (get_arg_val_i(c, optarg, &print_level,
PRINT_LEVEL_MIN, PRINT_LEVEL_MAX)) PRINT_LEVEL_MIN, PRINT_LEVEL_MAX))
return -1; goto end;
break; break;
case 'm': case 'm':
verbose = 1; verbose = 1;
@ -1377,9 +1371,11 @@ int main(int argc, char *argv[])
break; break;
case 'v': case 'v':
version_show(stdout); version_show(stdout);
config_destroy(cfg);
return 0; return 0;
case 'h': case 'h':
usage(progname); usage(progname);
config_destroy(cfg);
return 0; return 0;
default: default:
goto bad_usage; goto bad_usage;
@ -1414,10 +1410,10 @@ int main(int argc, char *argv[])
print_set_level(print_level); print_set_level(print_level);
if (autocfg) { if (autocfg) {
if (init_pmc(&phc2sys_config, &node, domain_number)) if (init_pmc(cfg, &node, domain_number))
return -1; goto end;
if (auto_init_ports(&node, rt) < 0) if (auto_init_ports(&node, rt) < 0)
return -1; goto end;
r = do_loop(&node, 1); r = do_loop(&node, 1);
goto end; goto end;
} }
@ -1450,7 +1446,7 @@ int main(int argc, char *argv[])
r = -1; r = -1;
if (wait_sync) { if (wait_sync) {
if (init_pmc(&phc2sys_config, &node, domain_number)) if (init_pmc(cfg, &node, domain_number))
goto end; goto end;
while (is_running()) { while (is_running()) {
@ -1489,9 +1485,10 @@ int main(int argc, char *argv[])
end: end:
if (node.pmc) if (node.pmc)
close_pmc(&node); close_pmc(&node);
config_destroy(cfg);
return r; return r;
bad_usage: bad_usage:
usage(progname); usage(progname);
config_destroy(cfg);
return -1; return -1;
} }

11
pmc.c
View File

@ -42,7 +42,6 @@
#define P41 ((double)(1ULL << 41)) #define P41 ((double)(1ULL << 41))
static struct pmc *pmc; static struct pmc *pmc;
static struct config pmc_config;
static void do_get_action(int action, int index, char *str); static void do_get_action(int action, int index, char *str);
static void do_set_action(int action, int index, char *str); static void do_set_action(int action, int index, char *str);
@ -739,13 +738,14 @@ int main(int argc, char *argv[])
enum transport_type transport_type = TRANS_UDP_IPV4; enum transport_type transport_type = TRANS_UDP_IPV4;
UInteger8 boundary_hops = 1, domain_number = 0, transport_specific = 0; UInteger8 boundary_hops = 1, domain_number = 0, transport_specific = 0;
struct ptp_message *msg; struct ptp_message *msg;
struct config *cfg = &pmc_config; struct config *cfg;
#define N_FD 2 #define N_FD 2
struct pollfd pollfd[N_FD]; struct pollfd pollfd[N_FD];
handle_term_signals(); handle_term_signals();
if (config_init(&pmc_config)) { cfg = config_create();
if (!cfg) {
return -1; return -1;
} }
@ -782,8 +782,7 @@ int main(int argc, char *argv[])
config_destroy(cfg); config_destroy(cfg);
return -1; return -1;
} }
if (config_set_string(&pmc_config, "uds_address", if (config_set_string(cfg, "uds_address", optarg)) {
optarg)) {
config_destroy(cfg); config_destroy(cfg);
return -1; return -1;
} }
@ -828,7 +827,7 @@ int main(int argc, char *argv[])
print_set_syslog(1); print_set_syslog(1);
print_set_verbose(1); print_set_verbose(1);
pmc = pmc_create(&pmc_config, transport_type, iface_name, boundary_hops, pmc = pmc_create(cfg, transport_type, iface_name, boundary_hops,
domain_number, transport_specific, zero_datalen); domain_number, transport_specific, zero_datalen);
if (!pmc) { if (!pmc) {
fprintf(stderr, "failed to create pmc\n"); fprintf(stderr, "failed to create pmc\n");

94
ptp4l.c
View File

@ -39,10 +39,6 @@
int assume_two_step = 0; int assume_two_step = 0;
static struct config cfg_settings = {
.interfaces = STAILQ_HEAD_INITIALIZER(cfg_settings.interfaces),
};
static struct default_ds ptp4l_dds; static struct default_ds ptp4l_dds;
static void usage(char *progname) static void usage(char *progname)
@ -80,10 +76,10 @@ static void usage(char *progname)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
char *config = NULL, *req_phc = NULL, *progname, *tmp; char *config = NULL, *req_phc = NULL, *progname, *tmp;
int c; int c, err = -1;
struct interface *iface; struct interface *iface;
struct clock *clock; struct clock *clock = NULL;
struct config *cfg = &cfg_settings; struct config *cfg;
struct default_ds *dds = &ptp4l_dds; struct default_ds *dds = &ptp4l_dds;
struct defaultDS *ds = &ptp4l_dds.dds; struct defaultDS *ds = &ptp4l_dds.dds;
int phc_index = -1, print_level, required_modes = 0; int phc_index = -1, print_level, required_modes = 0;
@ -92,7 +88,8 @@ int main(int argc, char *argv[])
if (handle_term_signals()) if (handle_term_signals())
return -1; return -1;
if (config_init(&cfg_settings)) { cfg = config_create();
if (!cfg) {
return -1; return -1;
} }
@ -103,62 +100,62 @@ int main(int argc, char *argv[])
switch (c) { switch (c) {
case 'A': case 'A':
if (config_set_int(cfg, "delay_mechanism", DM_AUTO)) if (config_set_int(cfg, "delay_mechanism", DM_AUTO))
return -1; goto out;
break; break;
case 'E': case 'E':
if (config_set_int(cfg, "delay_mechanism", DM_E2E)) if (config_set_int(cfg, "delay_mechanism", DM_E2E))
return -1; goto out;
break; break;
case 'P': case 'P':
if (config_set_int(cfg, "delay_mechanism", DM_P2P)) if (config_set_int(cfg, "delay_mechanism", DM_P2P))
return -1; goto out;
break; break;
case '2': case '2':
if (config_set_int(cfg, "network_transport", if (config_set_int(cfg, "network_transport",
TRANS_IEEE_802_3)) TRANS_IEEE_802_3))
return -1; goto out;
break; break;
case '4': case '4':
if (config_set_int(cfg, "network_transport", if (config_set_int(cfg, "network_transport",
TRANS_UDP_IPV4)) TRANS_UDP_IPV4))
return -1; goto out;
break; break;
case '6': case '6':
if (config_set_int(cfg, "network_transport", if (config_set_int(cfg, "network_transport",
TRANS_UDP_IPV6)) TRANS_UDP_IPV6))
return -1; goto out;
break; break;
case 'H': case 'H':
if (config_set_int(cfg, "time_stamping", TS_HARDWARE)) if (config_set_int(cfg, "time_stamping", TS_HARDWARE))
return -1; goto out;
break; break;
case 'S': case 'S':
if (config_set_int(cfg, "time_stamping", TS_SOFTWARE)) if (config_set_int(cfg, "time_stamping", TS_SOFTWARE))
return -1; goto out;
break; break;
case 'L': case 'L':
if (config_set_int(cfg, "time_stamping", TS_LEGACY_HW)) if (config_set_int(cfg, "time_stamping", TS_LEGACY_HW))
return -1; goto out;
break; break;
case 'f': case 'f':
config = optarg; config = optarg;
break; break;
case 'i': case 'i':
if (!config_create_interface(optarg, &cfg_settings)) if (!config_create_interface(optarg, cfg))
return -1; goto out;
break; break;
case 'p': case 'p':
req_phc = optarg; req_phc = optarg;
break; break;
case 's': case 's':
if (config_set_int(cfg, "slaveOnly", 1)) { if (config_set_int(cfg, "slaveOnly", 1)) {
return -1; goto out;
} }
break; break;
case 'l': case 'l':
if (get_arg_val_i(c, optarg, &print_level, if (get_arg_val_i(c, optarg, &print_level,
PRINT_LEVEL_MIN, PRINT_LEVEL_MAX)) PRINT_LEVEL_MIN, PRINT_LEVEL_MAX))
return -1; goto out;
config_set_int(cfg, "logging_level", print_level); config_set_int(cfg, "logging_level", print_level);
break; break;
case 'm': case 'm':
@ -175,14 +172,14 @@ int main(int argc, char *argv[])
return 0; return 0;
case '?': case '?':
usage(progname); usage(progname);
return -1; goto out;
default: default:
usage(progname); usage(progname);
return -1; goto out;
} }
} }
if (config && (c = config_read(config, &cfg_settings))) { if (config && (c = config_read(config, cfg))) {
return c; return c;
} }
@ -208,23 +205,23 @@ int main(int argc, char *argv[])
if (count_char(tmp, ';') != 2 || if (count_char(tmp, ';') != 2 ||
static_ptp_text_set(&dds->clock_desc.productDescription, tmp)) { static_ptp_text_set(&dds->clock_desc.productDescription, tmp)) {
fprintf(stderr, "invalid productDescription '%s'.\n", tmp); fprintf(stderr, "invalid productDescription '%s'.\n", tmp);
return -1; goto out;
} }
tmp = config_get_string(cfg, NULL, "revisionData"); tmp = config_get_string(cfg, NULL, "revisionData");
if (count_char(tmp, ';') != 2 || if (count_char(tmp, ';') != 2 ||
static_ptp_text_set(&dds->clock_desc.revisionData, tmp)) { static_ptp_text_set(&dds->clock_desc.revisionData, tmp)) {
fprintf(stderr, "invalid revisionData '%s'.\n", tmp); fprintf(stderr, "invalid revisionData '%s'.\n", tmp);
return -1; goto out;
} }
tmp = config_get_string(cfg, NULL, "userDescription"); tmp = config_get_string(cfg, NULL, "userDescription");
if (static_ptp_text_set(&dds->clock_desc.userDescription, tmp)) { if (static_ptp_text_set(&dds->clock_desc.userDescription, tmp)) {
fprintf(stderr, "invalid userDescription '%s'.\n", tmp); fprintf(stderr, "invalid userDescription '%s'.\n", tmp);
return -1; goto out;
} }
tmp = config_get_string(cfg, NULL, "manufacturerIdentity"); tmp = config_get_string(cfg, NULL, "manufacturerIdentity");
if (OUI_LEN != sscanf(tmp, "%hhx:%hhx:%hhx", &oui[0], &oui[1], &oui[2])) { if (OUI_LEN != sscanf(tmp, "%hhx:%hhx:%hhx", &oui[0], &oui[1], &oui[2])) {
fprintf(stderr, "invalid manufacturerIdentity '%s'.\n", tmp); fprintf(stderr, "invalid manufacturerIdentity '%s'.\n", tmp);
return -1; goto out;
} }
memcpy(dds->clock_desc.manufacturerIdentity, oui, OUI_LEN); memcpy(dds->clock_desc.manufacturerIdentity, oui, OUI_LEN);
@ -244,7 +241,7 @@ int main(int argc, char *argv[])
ds->flags & DDS_SLAVE_ONLY) { ds->flags & DDS_SLAVE_ONLY) {
fprintf(stderr, fprintf(stderr,
"Cannot mix 1588 slaveOnly with 802.1AS !gmCapable.\n"); "Cannot mix 1588 slaveOnly with 802.1AS !gmCapable.\n");
return -1; goto out;
} }
if (!config_get_int(cfg, NULL, "gmCapable") || if (!config_get_int(cfg, NULL, "gmCapable") ||
ds->flags & DDS_SLAVE_ONLY) { ds->flags & DDS_SLAVE_ONLY) {
@ -255,10 +252,10 @@ int main(int argc, char *argv[])
config_set_int(cfg, "sanity_freq_limit", 0); config_set_int(cfg, "sanity_freq_limit", 0);
} }
if (STAILQ_EMPTY(&cfg_settings.interfaces)) { if (STAILQ_EMPTY(&cfg->interfaces)) {
fprintf(stderr, "no interface specified\n"); fprintf(stderr, "no interface specified\n");
usage(progname); usage(progname);
return -1; goto out;
} }
if (!(ds->flags & DDS_TWO_STEP_FLAG)) { if (!(ds->flags & DDS_TWO_STEP_FLAG)) {
@ -267,10 +264,10 @@ int main(int argc, char *argv[])
case TS_LEGACY_HW: case TS_LEGACY_HW:
fprintf(stderr, "one step is only possible " fprintf(stderr, "one step is only possible "
"with hardware time stamping\n"); "with hardware time stamping\n");
return -1; goto out;
case TS_HARDWARE: case TS_HARDWARE:
if (config_set_int(cfg, "time_stamping", TS_ONESTEP)) if (config_set_int(cfg, "time_stamping", TS_ONESTEP))
return -1; goto out;
break; break;
case TS_ONESTEP: case TS_ONESTEP:
break; break;
@ -298,19 +295,19 @@ int main(int argc, char *argv[])
/* Init interface configs and check whether timestamping mode is /* Init interface configs and check whether timestamping mode is
* supported. */ * supported. */
STAILQ_FOREACH(iface, &cfg_settings.interfaces, list) { STAILQ_FOREACH(iface, &cfg->interfaces, list) {
config_init_interface(iface, &cfg_settings); config_init_interface(iface, cfg);
if (iface->ts_info.valid && if (iface->ts_info.valid &&
((iface->ts_info.so_timestamping & required_modes) != required_modes)) { ((iface->ts_info.so_timestamping & required_modes) != required_modes)) {
fprintf(stderr, "interface '%s' does not support " fprintf(stderr, "interface '%s' does not support "
"requested timestamping mode.\n", "requested timestamping mode.\n",
iface->name); iface->name);
return -1; goto out;
} }
} }
/* determine PHC Clock index */ /* determine PHC Clock index */
iface = STAILQ_FIRST(&cfg_settings.interfaces); iface = STAILQ_FIRST(&cfg->interfaces);
if (config_get_int(cfg, NULL, "free_running")) { if (config_get_int(cfg, NULL, "free_running")) {
phc_index = -1; phc_index = -1;
} else if (config_get_int(cfg, NULL, "time_stamping") == TS_SOFTWARE || } else if (config_get_int(cfg, NULL, "time_stamping") == TS_SOFTWARE ||
@ -319,7 +316,7 @@ int main(int argc, char *argv[])
} else if (req_phc) { } else if (req_phc) {
if (1 != sscanf(req_phc, "/dev/ptp%d", &phc_index)) { if (1 != sscanf(req_phc, "/dev/ptp%d", &phc_index)) {
fprintf(stderr, "bad ptp device string\n"); fprintf(stderr, "bad ptp device string\n");
return -1; goto out;
} }
} else if (iface->ts_info.valid) { } else if (iface->ts_info.valid) {
phc_index = iface->ts_info.phc_index; phc_index = iface->ts_info.phc_index;
@ -327,7 +324,7 @@ int main(int argc, char *argv[])
fprintf(stderr, "ptp device not specified and\n" fprintf(stderr, "ptp device not specified and\n"
"automatic determination is not\n" "automatic determination is not\n"
"supported. please specify ptp device\n"); "supported. please specify ptp device\n");
return -1; goto out;
} }
if (phc_index >= 0) { if (phc_index >= 0) {
@ -336,23 +333,24 @@ int main(int argc, char *argv[])
if (generate_clock_identity(&ds->clockIdentity, iface->name)) { if (generate_clock_identity(&ds->clockIdentity, iface->name)) {
fprintf(stderr, "failed to generate a clock identity\n"); fprintf(stderr, "failed to generate a clock identity\n");
return -1; goto out;
} }
clock = clock_create(&cfg_settings, clock = clock_create(cfg, phc_index, &cfg->interfaces, &ptp4l_dds);
phc_index, &cfg_settings.interfaces,
&ptp4l_dds);
if (!clock) { if (!clock) {
fprintf(stderr, "failed to create a clock\n"); fprintf(stderr, "failed to create a clock\n");
return -1; goto out;
} }
err = 0;
while (is_running()) { while (is_running()) {
if (clock_poll(clock)) if (clock_poll(clock))
break; break;
} }
out:
clock_destroy(clock); if (clock)
config_destroy(&cfg_settings); clock_destroy(clock);
return 0; config_destroy(cfg);
return err;
} }