mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-09-30 11:25:47 +00:00
network: wire up dnsmasq option xmlns
This maps to XML like: <network xmlns:dnsmasq='http://libvirt.org/schemas/network/dnsmasq/1.0'> ... <dnsmasq:options> <dnsmasq:option value="foo=bar"/> <dnsmasq:option value="cname=*.foo.example.com,master.example.com"/> </dnsmasq:options> </network> To dnsmasq config options ... foo=bar cname=*.foo.example.com,master.example.com Reviewed-by: Laine Stump <laine@laine.org> Signed-off-by: Cole Robinson <crobinso@redhat.com>
This commit is contained in:
parent
2dde2dbba1
commit
fb9f6ce625
@ -405,6 +405,17 @@
|
|||||||
<zeroOrMore>
|
<zeroOrMore>
|
||||||
<ref name="route"/>
|
<ref name="route"/>
|
||||||
</zeroOrMore>
|
</zeroOrMore>
|
||||||
|
|
||||||
|
<!-- <dnsmasq:options> -->
|
||||||
|
<optional>
|
||||||
|
<element name="options" ns="http://libvirt.org/schemas/network/dnsmasq/1.0">
|
||||||
|
<zeroOrMore>
|
||||||
|
<element name="option">
|
||||||
|
<attribute name='value'/>
|
||||||
|
</element>
|
||||||
|
</zeroOrMore>
|
||||||
|
</element>
|
||||||
|
</optional>
|
||||||
</interleave>
|
</interleave>
|
||||||
</element>
|
</element>
|
||||||
</define>
|
</define>
|
||||||
|
@ -69,6 +69,8 @@
|
|||||||
#include "virjson.h"
|
#include "virjson.h"
|
||||||
#include "virnetworkportdef.h"
|
#include "virnetworkportdef.h"
|
||||||
|
|
||||||
|
#include <libxml/xpathInternals.h>
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_NETWORK
|
#define VIR_FROM_THIS VIR_FROM_NETWORK
|
||||||
#define MAX_BRIDGE_ID 256
|
#define MAX_BRIDGE_ID 256
|
||||||
|
|
||||||
@ -83,6 +85,8 @@
|
|||||||
|
|
||||||
VIR_LOG_INIT("network.bridge_driver");
|
VIR_LOG_INIT("network.bridge_driver");
|
||||||
|
|
||||||
|
#define DNSMASQ_NAMESPACE_HREF "http://libvirt.org/schemas/network/dnsmasq/1.0"
|
||||||
|
|
||||||
static virNetworkDriverStatePtr network_driver;
|
static virNetworkDriverStatePtr network_driver;
|
||||||
|
|
||||||
|
|
||||||
@ -136,10 +140,126 @@ networkDnsmasqCapsRefresh(virNetworkDriverStatePtr driver)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static virNetworkXMLOptionPtr
|
|
||||||
|
static void
|
||||||
|
networkDnsmasqDefNamespaceFree(void *nsdata)
|
||||||
|
{
|
||||||
|
networkDnsmasqXmlNsDefPtr def = nsdata;
|
||||||
|
if (!def)
|
||||||
|
return;
|
||||||
|
|
||||||
|
virStringListFreeCount(def->options, def->noptions);
|
||||||
|
|
||||||
|
VIR_FREE(def);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
networkDnsmasqDefNamespaceParseOptions(networkDnsmasqXmlNsDefPtr nsdef,
|
||||||
|
xmlXPathContextPtr ctxt)
|
||||||
|
{
|
||||||
|
VIR_AUTOFREE(xmlNodePtr *) nodes = NULL;
|
||||||
|
ssize_t nnodes;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if ((nnodes = virXPathNodeSet("./dnsmasq:options/dnsmasq:option",
|
||||||
|
ctxt, &nodes)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (nnodes == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (VIR_ALLOC_N(nsdef->options, nnodes) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (i = 0; i < nnodes; i++) {
|
||||||
|
if (!(nsdef->options[nsdef->noptions++] = virXMLPropString(nodes[i], "value"))) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("No dnsmasq options value specified"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
networkDnsmasqDefNamespaceParse(xmlXPathContextPtr ctxt,
|
||||||
|
void **data)
|
||||||
|
{
|
||||||
|
networkDnsmasqXmlNsDefPtr nsdata = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (xmlXPathRegisterNs(ctxt, BAD_CAST "dnsmasq",
|
||||||
|
BAD_CAST DNSMASQ_NAMESPACE_HREF) < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Failed to register xml namespace '%s'"),
|
||||||
|
DNSMASQ_NAMESPACE_HREF);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VIR_ALLOC(nsdata) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (networkDnsmasqDefNamespaceParseOptions(nsdata, ctxt))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (nsdata->noptions > 0)
|
||||||
|
VIR_STEAL_PTR(*data, nsdata);
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
networkDnsmasqDefNamespaceFree(nsdata);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
networkDnsmasqDefNamespaceFormatXML(virBufferPtr buf,
|
||||||
|
void *nsdata)
|
||||||
|
{
|
||||||
|
networkDnsmasqXmlNsDefPtr def = nsdata;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (!def->noptions)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
virBufferAddLit(buf, "<dnsmasq:options>\n");
|
||||||
|
virBufferAdjustIndent(buf, 2);
|
||||||
|
|
||||||
|
for (i = 0; i < def->noptions; i++) {
|
||||||
|
virBufferEscapeString(buf, "<dnsmasq:option value='%s'/>\n",
|
||||||
|
def->options[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
virBufferAdjustIndent(buf, -2);
|
||||||
|
virBufferAddLit(buf, "</dnsmasq:options>\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
networkDnsmasqDefNamespaceHref(void)
|
||||||
|
{
|
||||||
|
return "xmlns:dnsmasq='" DNSMASQ_NAMESPACE_HREF "'";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virNetworkXMLNamespace networkDnsmasqXMLNamespace = {
|
||||||
|
.parse = networkDnsmasqDefNamespaceParse,
|
||||||
|
.free = networkDnsmasqDefNamespaceFree,
|
||||||
|
.format = networkDnsmasqDefNamespaceFormatXML,
|
||||||
|
.href = networkDnsmasqDefNamespaceHref,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
virNetworkXMLOptionPtr
|
||||||
networkDnsmasqCreateXMLConf(void)
|
networkDnsmasqCreateXMLConf(void)
|
||||||
{
|
{
|
||||||
return virNetworkXMLOptionNew(NULL);
|
return virNetworkXMLOptionNew(&networkDnsmasqXMLNamespace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1480,6 +1600,12 @@ networkDnsmasqConfContents(virNetworkObjPtr obj,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (def->namespaceData) {
|
||||||
|
networkDnsmasqXmlNsDefPtr dnsmasqxmlns = def->namespaceData;
|
||||||
|
for (i = 0; i < dnsmasqxmlns->noptions; i++)
|
||||||
|
virBufferAsprintf(&configbuf, "%s\n", dnsmasqxmlns->options[i]);
|
||||||
|
}
|
||||||
|
|
||||||
if (!(*configstr = virBufferContentAndReset(&configbuf)))
|
if (!(*configstr = virBufferContentAndReset(&configbuf)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
@ -27,6 +27,18 @@
|
|||||||
#include "virdnsmasq.h"
|
#include "virdnsmasq.h"
|
||||||
#include "virnetworkobj.h"
|
#include "virnetworkobj.h"
|
||||||
|
|
||||||
|
extern virNetworkXMLNamespace networkDnsmasqXMLNamespace;
|
||||||
|
|
||||||
|
typedef struct _networkDnsmasqXmlNsDef networkDnsmasqXmlNsDef;
|
||||||
|
typedef networkDnsmasqXmlNsDef *networkDnsmasqXmlNsDefPtr;
|
||||||
|
struct _networkDnsmasqXmlNsDef {
|
||||||
|
size_t noptions;
|
||||||
|
char **options;
|
||||||
|
};
|
||||||
|
|
||||||
|
virNetworkXMLOptionPtr
|
||||||
|
networkDnsmasqCreateXMLConf(void);
|
||||||
|
|
||||||
int
|
int
|
||||||
networkRegister(void);
|
networkRegister(void);
|
||||||
|
|
||||||
|
@ -332,13 +332,13 @@ test_programs += virjsontest
|
|||||||
endif WITH_YAJL
|
endif WITH_YAJL
|
||||||
|
|
||||||
test_programs += \
|
test_programs += \
|
||||||
networkxml2xmltest \
|
|
||||||
networkxml2xmlupdatetest \
|
networkxml2xmlupdatetest \
|
||||||
virnetworkportxml2xmltest \
|
virnetworkportxml2xmltest \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
if WITH_NETWORK
|
if WITH_NETWORK
|
||||||
test_programs += \
|
test_programs += \
|
||||||
|
networkxml2xmltest \
|
||||||
networkxml2conftest \
|
networkxml2conftest \
|
||||||
networkxml2firewalltest \
|
networkxml2firewalltest \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
@ -807,11 +807,6 @@ EXTRA_DIST += \
|
|||||||
bhyveargv2xmlmock.c
|
bhyveargv2xmlmock.c
|
||||||
endif ! WITH_BHYVE
|
endif ! WITH_BHYVE
|
||||||
|
|
||||||
networkxml2xmltest_SOURCES = \
|
|
||||||
networkxml2xmltest.c \
|
|
||||||
testutils.c testutils.h
|
|
||||||
networkxml2xmltest_LDADD = $(LDADDS)
|
|
||||||
|
|
||||||
networkxml2xmlupdatetest_SOURCES = \
|
networkxml2xmlupdatetest_SOURCES = \
|
||||||
networkxml2xmlupdatetest.c \
|
networkxml2xmlupdatetest.c \
|
||||||
testutils.c testutils.h
|
testutils.c testutils.h
|
||||||
@ -823,6 +818,11 @@ virnetworkportxml2xmltest_SOURCES = \
|
|||||||
virnetworkportxml2xmltest_LDADD = $(LDADDS)
|
virnetworkportxml2xmltest_LDADD = $(LDADDS)
|
||||||
|
|
||||||
if WITH_NETWORK
|
if WITH_NETWORK
|
||||||
|
networkxml2xmltest_SOURCES = \
|
||||||
|
networkxml2xmltest.c \
|
||||||
|
testutils.c testutils.h
|
||||||
|
networkxml2xmltest_LDADD = ../src/libvirt_driver_network_impl.la $(LDADDS)
|
||||||
|
|
||||||
networkxml2conftest_SOURCES = \
|
networkxml2conftest_SOURCES = \
|
||||||
networkxml2conftest.c \
|
networkxml2conftest.c \
|
||||||
testutils.c testutils.h
|
testutils.c testutils.h
|
||||||
@ -834,7 +834,7 @@ networkxml2firewalltest_SOURCES = \
|
|||||||
networkxml2firewalltest_LDADD = ../src/libvirt_driver_network_impl.la $(LDADDS)
|
networkxml2firewalltest_LDADD = ../src/libvirt_driver_network_impl.la $(LDADDS)
|
||||||
|
|
||||||
else ! WITH_NETWORK
|
else ! WITH_NETWORK
|
||||||
EXTRA_DIST += networkxml2conftest.c
|
EXTRA_DIST += networkxml2xmltest.c networkxml2conftest.c
|
||||||
endif ! WITH_NETWORK
|
endif ! WITH_NETWORK
|
||||||
|
|
||||||
if WITH_STORAGE_SHEEPDOG
|
if WITH_STORAGE_SHEEPDOG
|
||||||
|
18
tests/networkxml2confdata/dnsmasq-options.conf
Normal file
18
tests/networkxml2confdata/dnsmasq-options.conf
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
##WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
|
||||||
|
##OVERWRITTEN AND LOST. Changes to this configuration should be made using:
|
||||||
|
## virsh net-edit default
|
||||||
|
## or other application using the libvirt API.
|
||||||
|
##
|
||||||
|
## dnsmasq conf file created by libvirt
|
||||||
|
strict-order
|
||||||
|
except-interface=lo
|
||||||
|
bind-dynamic
|
||||||
|
interface=virbr0
|
||||||
|
dhcp-range=192.168.122.2,192.168.122.254,255.255.255.0
|
||||||
|
dhcp-no-override
|
||||||
|
dhcp-authoritative
|
||||||
|
dhcp-lease-max=253
|
||||||
|
dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
|
||||||
|
addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts
|
||||||
|
foo=bar
|
||||||
|
cname=*.cloudapps.example.com,master.example.com
|
15
tests/networkxml2confdata/dnsmasq-options.xml
Normal file
15
tests/networkxml2confdata/dnsmasq-options.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<network xmlns:dnsmasq="http://libvirt.org/schemas/network/dnsmasq/1.0">
|
||||||
|
<name>default</name>
|
||||||
|
<uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
|
||||||
|
<bridge name="virbr0"/>
|
||||||
|
<forward mode="nat" dev="eth1"/>
|
||||||
|
<ip address="192.168.122.1" netmask="255.255.255.0">
|
||||||
|
<dhcp>
|
||||||
|
<range start="192.168.122.2" end="192.168.122.254"/>
|
||||||
|
</dhcp>
|
||||||
|
</ip>
|
||||||
|
<dnsmasq:options>
|
||||||
|
<dnsmasq:option value="foo=bar"/>
|
||||||
|
<dnsmasq:option value="cname=*.cloudapps.example.com,master.example.com"/>
|
||||||
|
</dnsmasq:options>
|
||||||
|
</network>
|
@ -25,8 +25,12 @@ testCompareXMLToConfFiles(const char *inxml, const char *outconf, dnsmasqCapsPtr
|
|||||||
virCommandPtr cmd = NULL;
|
virCommandPtr cmd = NULL;
|
||||||
char *pidfile = NULL;
|
char *pidfile = NULL;
|
||||||
dnsmasqContext *dctx = NULL;
|
dnsmasqContext *dctx = NULL;
|
||||||
|
virNetworkXMLOptionPtr xmlopt = NULL;
|
||||||
|
|
||||||
if (!(def = virNetworkDefParseFile(inxml, NULL)))
|
if (!(xmlopt = networkDnsmasqCreateXMLConf()))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (!(def = virNetworkDefParseFile(inxml, xmlopt)))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (!(obj = virNetworkObjNew()))
|
if (!(obj = virNetworkObjNew()))
|
||||||
@ -63,6 +67,7 @@ testCompareXMLToConfFiles(const char *inxml, const char *outconf, dnsmasqCapsPtr
|
|||||||
VIR_FREE(actual);
|
VIR_FREE(actual);
|
||||||
VIR_FREE(pidfile);
|
VIR_FREE(pidfile);
|
||||||
virCommandFree(cmd);
|
virCommandFree(cmd);
|
||||||
|
virObjectUnref(xmlopt);
|
||||||
virNetworkObjEndAPI(&obj);
|
virNetworkObjEndAPI(&obj);
|
||||||
dnsmasqContextFree(dctx);
|
dnsmasqContextFree(dctx);
|
||||||
return ret;
|
return ret;
|
||||||
@ -141,6 +146,7 @@ mymain(void)
|
|||||||
DO_TEST("dhcp6-nat-network", dhcpv6);
|
DO_TEST("dhcp6-nat-network", dhcpv6);
|
||||||
DO_TEST("dhcp6host-routed-network", dhcpv6);
|
DO_TEST("dhcp6host-routed-network", dhcpv6);
|
||||||
DO_TEST("ptr-domains-auto", dhcpv6);
|
DO_TEST("ptr-domains-auto", dhcpv6);
|
||||||
|
DO_TEST("dnsmasq-options", dhcpv6);
|
||||||
|
|
||||||
virObjectUnref(dhcpv6);
|
virObjectUnref(dhcpv6);
|
||||||
virObjectUnref(full);
|
virObjectUnref(full);
|
||||||
|
15
tests/networkxml2xmlin/dnsmasq-options.xml
Normal file
15
tests/networkxml2xmlin/dnsmasq-options.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<network xmlns:dnsmasq="http://libvirt.org/schemas/network/dnsmasq/1.0">
|
||||||
|
<name>default</name>
|
||||||
|
<uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
|
||||||
|
<bridge name="virbr0"/>
|
||||||
|
<forward mode="nat" dev="eth1"/>
|
||||||
|
<ip address="192.168.122.1" netmask="255.255.255.0">
|
||||||
|
<dhcp>
|
||||||
|
<range start="192.168.122.2" end="192.168.122.254"/>
|
||||||
|
</dhcp>
|
||||||
|
</ip>
|
||||||
|
<dnsmasq:options>
|
||||||
|
<dnsmasq:option value="foo=bar"/>
|
||||||
|
<dnsmasq:option value="cname=*.cloudapps.example.com,master.example.com"/>
|
||||||
|
</dnsmasq:options>
|
||||||
|
</network>
|
17
tests/networkxml2xmlout/dnsmasq-options.xml
Normal file
17
tests/networkxml2xmlout/dnsmasq-options.xml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<network xmlns:dnsmasq='http://libvirt.org/schemas/network/dnsmasq/1.0'>
|
||||||
|
<name>default</name>
|
||||||
|
<uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
|
||||||
|
<forward dev='eth1' mode='nat'>
|
||||||
|
<interface dev='eth1'/>
|
||||||
|
</forward>
|
||||||
|
<bridge name='virbr0' stp='on' delay='0'/>
|
||||||
|
<ip address='192.168.122.1' netmask='255.255.255.0'>
|
||||||
|
<dhcp>
|
||||||
|
<range start='192.168.122.2' end='192.168.122.254'/>
|
||||||
|
</dhcp>
|
||||||
|
</ip>
|
||||||
|
<dnsmasq:options>
|
||||||
|
<dnsmasq:option value='foo=bar'/>
|
||||||
|
<dnsmasq:option value='cname=*.cloudapps.example.com,master.example.com'/>
|
||||||
|
</dnsmasq:options>
|
||||||
|
</network>
|
@ -10,6 +10,7 @@
|
|||||||
#include "network_conf.h"
|
#include "network_conf.h"
|
||||||
#include "testutilsqemu.h"
|
#include "testutilsqemu.h"
|
||||||
#include "virstring.h"
|
#include "virstring.h"
|
||||||
|
#include "network/bridge_driver.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_NONE
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
||||||
|
|
||||||
@ -29,15 +30,19 @@ testCompareXMLToXMLFiles(const char *inxml, const char *outxml,
|
|||||||
int ret;
|
int ret;
|
||||||
testCompareNetXML2XMLResult result = TEST_COMPARE_NET_XML2XML_RESULT_SUCCESS;
|
testCompareNetXML2XMLResult result = TEST_COMPARE_NET_XML2XML_RESULT_SUCCESS;
|
||||||
virNetworkDefPtr dev = NULL;
|
virNetworkDefPtr dev = NULL;
|
||||||
|
virNetworkXMLOptionPtr xmlopt = NULL;
|
||||||
|
|
||||||
if (!(dev = virNetworkDefParseFile(inxml, NULL))) {
|
if (!(xmlopt = networkDnsmasqCreateXMLConf()))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (!(dev = virNetworkDefParseFile(inxml, xmlopt))) {
|
||||||
result = TEST_COMPARE_NET_XML2XML_RESULT_FAIL_PARSE;
|
result = TEST_COMPARE_NET_XML2XML_RESULT_FAIL_PARSE;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (expectResult == TEST_COMPARE_NET_XML2XML_RESULT_FAIL_PARSE)
|
if (expectResult == TEST_COMPARE_NET_XML2XML_RESULT_FAIL_PARSE)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (!(actual = virNetworkDefFormat(dev, NULL, flags))) {
|
if (!(actual = virNetworkDefFormat(dev, xmlopt, flags))) {
|
||||||
result = TEST_COMPARE_NET_XML2XML_RESULT_FAIL_FORMAT;
|
result = TEST_COMPARE_NET_XML2XML_RESULT_FAIL_FORMAT;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
@ -67,6 +72,7 @@ testCompareXMLToXMLFiles(const char *inxml, const char *outxml,
|
|||||||
|
|
||||||
VIR_FREE(actual);
|
VIR_FREE(actual);
|
||||||
virNetworkDefFree(dev);
|
virNetworkDefFree(dev);
|
||||||
|
virObjectUnref(xmlopt);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,6 +164,7 @@ mymain(void)
|
|||||||
DO_TEST_PARSE_ERROR("passthrough-duplicate");
|
DO_TEST_PARSE_ERROR("passthrough-duplicate");
|
||||||
DO_TEST("metadata");
|
DO_TEST("metadata");
|
||||||
DO_TEST("set-mtu");
|
DO_TEST("set-mtu");
|
||||||
|
DO_TEST("dnsmasq-options");
|
||||||
|
|
||||||
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user