libcyaml库使用问题
network:
ethernets:
eth0:
dhcp4: false
addresses:
- 192.168.0.123/24
#gateway4: 192.168.0.1
nameservers:
addresses:
- 114.114.114.114
- 8.8.8.8
eth1:
dhcp4: false
addresses:
- 192.168.137.147/24
gateway4: 192.168.137.1
nameservers:
addresses:
- 114.114.114.114
- 8.8.8.8
enP1p17s0:
dhcp4: false
addresses:
- 192.168.2.123/24
#gateway4: 192.168.2.1
nameservers:
addresses:
- 114.114.114.114
- 8.8.8.8
enP2p33s0:
dhcp4: false
addresses:
- 192.168.3.123/24
#gateway4: 192.168.3.1
nameservers:
addresses:
- 114.114.114.114
- 8.8.8.8
eth2:
dhcp4: false
addresses:
- 192.168.4.123/24
#gateway4: 192.168.4.1
nameservers:
addresses:
- 114.114.114.114
- 8.8.8.8
wlan0:
dhcp4: true
version: 2
这个是Linux的Netplan配置文件,我用Libcyaml库对这个文件进行解析和修改,以下是我的代码和结构体,在Ubuntu上运行正常(但是调用cyaml_free的时候会崩溃),移植到开发板上后程序运行直接就会提示段错误(cyaml_load_file函数里),不明白问题出在哪
/*
* SPDX-License-Identifier: ISC
*
* Copyright (C) 2019 Michael Drake <tlsa@netsurf-browser.org>
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "./cyaml.h"
/******************************************************************************
* C data structure for storing a project plan.
*
* This is what we want to load the YAML into.
******************************************************************************/
struct nameservers {
char **addresses;
unsigned n_addresses;
};
struct wlan0 {
char *dhcp4;
};
struct ethx {
char *dhcp4;
char **addresses;
unsigned n_addresses;
struct nameservers *nameserver;
};
struct ethx_gateway {
char *dhcp4;
char **addresses;
unsigned n_addresses;
char *gateway4;
struct nameservers *nameserver;
};
struct ethernets {
struct ethx *eth0;
struct ethx_gateway *eth1;
struct ethx *enP1p17s0;
struct ethx *enP2p33s0;
struct ethx *eth2;
struct wlan0 *wlan0;
};
struct network {
struct ethernets *ethernet;
char *version;
};
struct netplan {
struct network *net;
};
/******************************************************************************
* CYAML schema to tell libcyaml about both expected YAML and data structure.
*
* (Our CYAML schema is just a bunch of static const data.)
******************************************************************************/
static const cyaml_schema_value_t string_ptr_schema = {
CYAML_VALUE_STRING(CYAML_FLAG_POINTER, char, 0, CYAML_UNLIMITED),
};
static const cyaml_schema_field_t address_fields_schema[] = {
CYAML_FIELD_SEQUENCE_COUNT(
"addresses", CYAML_FLAG_POINTER,
struct nameservers, addresses, n_addresses,
&string_ptr_schema, 0, CYAML_UNLIMITED),
};
static const cyaml_schema_field_t wlan0_fields_schema[] = {
CYAML_FIELD_STRING_PTR(
"dhcp4", CYAML_FLAG_DEFAULT,
struct wlan0, dhcp4, 0, CYAML_UNLIMITED),
};
static const cyaml_schema_field_t ethx_fields_schema[] = {
CYAML_FIELD_STRING_PTR(
"dhcp4", CYAML_FLAG_DEFAULT,
struct ethx, dhcp4, 0, CYAML_UNLIMITED),
CYAML_FIELD_SEQUENCE_COUNT(
"addresses", CYAML_FLAG_POINTER,
struct ethx, addresses, n_addresses,
&string_ptr_schema, 0, CYAML_UNLIMITED),
CYAML_FIELD_MAPPING_PTR(
"nameservers", CYAML_FLAG_POINTER,
struct ethx, nameserver, address_fields_schema),
CYAML_FIELD_END
};
static const cyaml_schema_field_t ethx_gateway_fields_schema[] = {
CYAML_FIELD_STRING_PTR(
"dhcp4", CYAML_FLAG_DEFAULT,
struct ethx_gateway, dhcp4, 0, CYAML_UNLIMITED),
CYAML_FIELD_SEQUENCE_COUNT(
"addresses", CYAML_FLAG_POINTER,
struct ethx_gateway, addresses, n_addresses,
&string_ptr_schema, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"gateway4", CYAML_FLAG_DEFAULT,
struct ethx_gateway, gateway4, 0, CYAML_UNLIMITED),
CYAML_FIELD_MAPPING_PTR(
"nameservers", CYAML_FLAG_POINTER,
struct ethx_gateway, nameserver, address_fields_schema),
CYAML_FIELD_END
};
static const cyaml_schema_field_t ethernet_fields_schema[] = {
CYAML_FIELD_MAPPING_PTR(
"eth0", CYAML_FLAG_POINTER,
struct ethernets, eth0, ethx_fields_schema),
CYAML_FIELD_MAPPING_PTR(
"eth1", CYAML_FLAG_POINTER,
struct ethernets, eth1, ethx_gateway_fields_schema),
CYAML_FIELD_MAPPING_PTR(
"enP1p17s0", CYAML_FLAG_POINTER,
struct ethernets, enP1p17s0, ethx_fields_schema),
CYAML_FIELD_MAPPING_PTR(
"enP2p33s0", CYAML_FLAG_POINTER,
struct ethernets, enP2p33s0, ethx_fields_schema),
CYAML_FIELD_MAPPING_PTR(
"eth2", CYAML_FLAG_POINTER,
struct ethernets, eth2, ethx_fields_schema),
CYAML_FIELD_MAPPING_PTR(
"wlan0", CYAML_FLAG_POINTER,
struct ethernets, wlan0, wlan0_fields_schema),
CYAML_FIELD_END
};
static const cyaml_schema_field_t net_fields_schema[] = {
CYAML_FIELD_MAPPING_PTR(
"ethernets", CYAML_FLAG_POINTER,
struct network, ethernet, ethernet_fields_schema),
CYAML_FIELD_STRING_PTR(
"version", CYAML_FLAG_DEFAULT,
struct network, version, 0, CYAML_UNLIMITED),
CYAML_FIELD_END
};
static const cyaml_schema_field_t network_fields_schema[] = {
CYAML_FIELD_MAPPING_PTR(
"network", CYAML_FLAG_POINTER,
struct netplan, net, net_fields_schema),
};
static const cyaml_schema_value_t netplan_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct netplan, network_fields_schema),
};
static const cyaml_config_t config = {
.log_fn = cyaml_log, /* Use the default logging function. */
.mem_fn = cyaml_mem, /* Use the default memory allocator. */
.log_level = CYAML_LOG_WARNING, /* Logging errors and warnings only. */
};
#define NETPLAN_PATH "/etc/netplan/netplan.yaml"
/* Main entry point from OS. */
int main(int argc, char *argv[])
{
cyaml_err_t err;
struct netplan *g_netplan;
printf("2221\n");
/* Load input file. */
err = cyaml_load_file("netplan.yaml", &config,
&netplan_schema, (void **) &g_netplan, NULL);
if (err != CYAML_OK) {
printf("ERROR11: %s\n", cyaml_strerror(err));
return EXIT_FAILURE;
}
printf("111\n");
// /* Use the data. */
printf("%s\n", g_netplan->net->ethernet->eth0->dhcp4);
printf("%s\n", g_netplan->net->ethernet->eth0->addresses[0]);
printf("%s\n", g_netplan->net->ethernet->eth0->nameserver->addresses[0]);
printf("%s\n", g_netplan->net->ethernet->eth0->nameserver->addresses[1]);
printf("%s\n", g_netplan->net->ethernet->eth1->dhcp4);
printf("%s\n", g_netplan->net->ethernet->eth1->addresses[0]);
printf("%s\n", g_netplan->net->ethernet->eth1->gateway4);
printf("%s\n", g_netplan->net->ethernet->eth1->nameserver->addresses[0]);
printf("%s\n", g_netplan->net->ethernet->eth1->nameserver->addresses[1]);
printf("%s\n", g_netplan->net->ethernet->enP1p17s0->dhcp4);
printf("%s\n", g_netplan->net->ethernet->enP1p17s0->addresses[0]);
printf("%s\n", g_netplan->net->ethernet->enP1p17s0->nameserver->addresses[0]);
printf("%s\n", g_netplan->net->ethernet->enP1p17s0->nameserver->addresses[1]);
printf("%s\n", g_netplan->net->ethernet->enP2p33s0->dhcp4);
printf("%s\n", g_netplan->net->ethernet->enP2p33s0->addresses[0]);
printf("%s\n", g_netplan->net->ethernet->enP2p33s0->nameserver->addresses[0]);
printf("%s\n", g_netplan->net->ethernet->enP2p33s0->nameserver->addresses[1]);
printf("%s\n", g_netplan->net->ethernet->eth2->dhcp4);
printf("%s\n", g_netplan->net->ethernet->eth2->addresses[0]);
printf("%s\n", g_netplan->net->ethernet->eth2->nameserver->addresses[0]);
printf("%s\n", g_netplan->net->ethernet->eth2->nameserver->addresses[1]);
printf("%s\n", g_netplan->net->version);
memcpy(g_netplan->net->ethernet->eth0->dhcp4, "true", sizeof("true"));
/* Save data to new YAML file. */
err = cyaml_save_file("./test.yaml", &config,
&netplan_schema, g_netplan, 0);
if (err != CYAML_OK) {
fprintf(stderr, "ERROR: %s\n", cyaml_strerror(err));
cyaml_free(&config, &netplan_schema, g_netplan, 0);
return EXIT_FAILURE;
}
/* Free the data */
cyaml_free(&config, &netplan_schema, &g_netplan, 0);
return EXIT_SUCCESS;
}