我如何使用 C 从 FreeBSD 获取 kenv 设置
How do I use C to get the kenv settings from FreeBSD
我正在尝试在 FreeBSD 上改进 Facter。以前这是 Ruby 代码,因此作为 Ruby 程序员很容易理解。自 Facter 的 3.X 发布以来,它主要转移到 C/C++ 以提高性能。
在此转变期间,它丢失了一些事实,例如在 FreebSD 上。我正在尝试将它们添加回去。但是,我不是 C++/C 程序员,所以我基本上只是在阅读其他人的 FreeBSD 的 C 代码并对其进行改编。
所以我认为我的方向是正确的:
facter/lib/inc/internal/facts/freebsd/dmi_resolver.hpp
/**
* @file
* Declares the FreeBSD Desktop Management Interface (DMI) fact resolver.
*/
#pragma once
#include "../resolvers/dmi_resolver.hpp"
namespace facter { namespace facts { namespace freebsd {
/**
* Responsible for resolving DMI facts.
*/
struct dmi_resolver : resolvers::dmi_resolver
{
protected:
/**
* Collects the resolver data.
* @param facts The fact collection that is resolving facts.
* @return Returns the resolver data.
*/
virtual data collect_data(collection& facts) override;
private:
std::string sysctl_lookup(int mib);
};
}}} // namespace facter::facts::openbsd
facter/lib/src/facts/freebsd/dmi_resolver.cc
#include <internal/facts/freebsd/dmi_resolver.hpp>
#include <leatherman/logging/logging.hpp>
#include <kenv.h>
using namespace std;
namespace facter { namespace facts { namespace freebsd {
dmi_resolver::data dmi_resolver::collect_data(collection& facts)
{
data result;
result.bios_vendor = kenv_lookup("smbios.bios.vendor");
result.uuid = kenv_lookup("smbios.system.uuid");
result.serial_number = kenv_lookup("smbios.planar.serial");
result.product_name = kenv_lookup("smbios.system.product");
result.bios_version = kenv_lookup("smbios.bios.vendor");
return result;
}
string dmi_resolver::kenv_lookup(char file)
{
char buffer[100] = {};
LOG_DEBUG("localchassis", "DMI request for %s", file);
if (kenv(KENV_GET, file, buffer, sizeof(buffer) - 1) == -1) {
LOG_DEBUG("localchassis", "cannot get %s", file);
return "";
}
return buffer;
}
} } } // namespace facter::facts::freebsd
但是当我 运行 这样做时,我得到以下错误:
/root/facter/lib/src/facts/freebsd/dmi_resolver.cc:13:42: error: conversion from string literal to 'char *' is deprecated
[-Werror,-Wc++11-compat-deprecated-writable-strings]
result.bios_vendor = kenv_lookup("smbios.bios.vendor");
^
/root/facter/lib/src/facts/freebsd/dmi_resolver.cc:14:35: error: conversion from string literal to 'char *' is deprecated
[-Werror,-Wc++11-compat-deprecated-writable-strings]
result.uuid = kenv_lookup("smbios.system.uuid");
^
/root/facter/lib/src/facts/freebsd/dmi_resolver.cc:15:44: error: conversion from string literal to 'char *' is deprecated
[-Werror,-Wc++11-compat-deprecated-writable-strings]
result.serial_number = kenv_lookup("smbios.planar.serial");
^
/root/facter/lib/src/facts/freebsd/dmi_resolver.cc:16:43: error: conversion from string literal to 'char *' is deprecated
[-Werror,-Wc++11-compat-deprecated-writable-strings]
result.product_name = kenv_lookup("smbios.system.product");
^
/root/facter/lib/src/facts/freebsd/dmi_resolver.cc:17:43: error: conversion from string literal to 'char *' is deprecated
[-Werror,-Wc++11-compat-deprecated-writable-strings]
result.bios_version = kenv_lookup("smbios.bios.vendor");
^
/root/facter/lib/src/facts/freebsd/dmi_resolver.cc:22:26: error: out-of-line definition of 'kenv_lookup' does not match any
declaration in 'facter::facts::freebsd::dmi_resolver'
string dmi_resolver::kenv_lookup(char file)
^~~~~~~~~~~
/root/facter/lib/inc/internal/facts/freebsd/dmi_resolver.hpp:25:33: note: type of 1st parameter of member declaration does not
match definition ('char *' vs 'char')
std::string kenv_lookup(char *file);
^
/root/facter/lib/src/facts/freebsd/dmi_resolver.cc:27:13: error: no matching function for call to 'kenv'
if (kenv(KENV_GET, file, buffer, sizeof(buffer) - 1) == -1) {
^~~~
/usr/include/kenv.h:36:5: note: candidate function not viable: no known conversion from 'char' to 'const char *' for 2nd argument;
take the address of the argument with &
int kenv(int, const char *, char *, int);
^
我该如何解决这个问题?
理查德史密斯是正确的。工作代码如下
/Users/petersouter/projects/facter/lib/src/facts/freebsd/dmi_resolver.cc
#include <internal/facts/freebsd/dmi_resolver.hpp>
#include <leatherman/logging/logging.hpp>
#include <kenv.h>
using namespace std;
namespace facter { namespace facts { namespace freebsd {
dmi_resolver::data dmi_resolver::collect_data(collection& facts)
{
data result;
result.bios_vendor = kenv_lookup("smbios.bios.vendor");
result.bios_version = kenv_lookup("smbios.bios.version");
result.bios_release_date = kenv_lookup("smbios.bios.reldate");
result.uuid = kenv_lookup("smbios.system.uuid");
result.serial_number = kenv_lookup("smbios.planar.serial");
result.product_name = kenv_lookup("smbios.system.product");
result.manufacturer = kenv_lookup("smbios.system.maker");
return result;
}
string dmi_resolver::kenv_lookup(const char* file)
{
char buffer[100] = {};
LOG_DEBUG("kenv lookup for %s", file);
if (kenv(KENV_GET, file, buffer, sizeof(buffer) - 1) == -1) {
LOG_WARNING("kenv lookup for %1% failed: %2% (%3%)", file, strerror(errno), errno);
return "";
}
return buffer;
}
} } } // namespace facter::facts::freebsd
facter/lib/inc/internal/facts/freebsd/dmi_resolver.hpp
/**
* @file
* Declares the FreeBSD Desktop Management Interface (DMI) fact resolver.
*/
#pragma once
#include "../resolvers/dmi_resolver.hpp"
namespace facter { namespace facts { namespace freebsd {
/**
* Responsible for resolving DMI facts.
*/
struct dmi_resolver : resolvers::dmi_resolver
{
protected:
/**
* Collects the resolver data.
* @param facts The fact collection that is resolving facts.
* @return Returns the resolver data.
*/
virtual data collect_data(collection& facts) override;
private:
static std::string kenv_lookup(const char* file);
};
}}} // namespace facter::facts::freebsd
我正在尝试在 FreeBSD 上改进 Facter。以前这是 Ruby 代码,因此作为 Ruby 程序员很容易理解。自 Facter 的 3.X 发布以来,它主要转移到 C/C++ 以提高性能。
在此转变期间,它丢失了一些事实,例如在 FreebSD 上。我正在尝试将它们添加回去。但是,我不是 C++/C 程序员,所以我基本上只是在阅读其他人的 FreeBSD 的 C 代码并对其进行改编。
所以我认为我的方向是正确的:
facter/lib/inc/internal/facts/freebsd/dmi_resolver.hpp
/**
* @file
* Declares the FreeBSD Desktop Management Interface (DMI) fact resolver.
*/
#pragma once
#include "../resolvers/dmi_resolver.hpp"
namespace facter { namespace facts { namespace freebsd {
/**
* Responsible for resolving DMI facts.
*/
struct dmi_resolver : resolvers::dmi_resolver
{
protected:
/**
* Collects the resolver data.
* @param facts The fact collection that is resolving facts.
* @return Returns the resolver data.
*/
virtual data collect_data(collection& facts) override;
private:
std::string sysctl_lookup(int mib);
};
}}} // namespace facter::facts::openbsd
facter/lib/src/facts/freebsd/dmi_resolver.cc
#include <internal/facts/freebsd/dmi_resolver.hpp>
#include <leatherman/logging/logging.hpp>
#include <kenv.h>
using namespace std;
namespace facter { namespace facts { namespace freebsd {
dmi_resolver::data dmi_resolver::collect_data(collection& facts)
{
data result;
result.bios_vendor = kenv_lookup("smbios.bios.vendor");
result.uuid = kenv_lookup("smbios.system.uuid");
result.serial_number = kenv_lookup("smbios.planar.serial");
result.product_name = kenv_lookup("smbios.system.product");
result.bios_version = kenv_lookup("smbios.bios.vendor");
return result;
}
string dmi_resolver::kenv_lookup(char file)
{
char buffer[100] = {};
LOG_DEBUG("localchassis", "DMI request for %s", file);
if (kenv(KENV_GET, file, buffer, sizeof(buffer) - 1) == -1) {
LOG_DEBUG("localchassis", "cannot get %s", file);
return "";
}
return buffer;
}
} } } // namespace facter::facts::freebsd
但是当我 运行 这样做时,我得到以下错误:
/root/facter/lib/src/facts/freebsd/dmi_resolver.cc:13:42: error: conversion from string literal to 'char *' is deprecated
[-Werror,-Wc++11-compat-deprecated-writable-strings]
result.bios_vendor = kenv_lookup("smbios.bios.vendor");
^
/root/facter/lib/src/facts/freebsd/dmi_resolver.cc:14:35: error: conversion from string literal to 'char *' is deprecated
[-Werror,-Wc++11-compat-deprecated-writable-strings]
result.uuid = kenv_lookup("smbios.system.uuid");
^
/root/facter/lib/src/facts/freebsd/dmi_resolver.cc:15:44: error: conversion from string literal to 'char *' is deprecated
[-Werror,-Wc++11-compat-deprecated-writable-strings]
result.serial_number = kenv_lookup("smbios.planar.serial");
^
/root/facter/lib/src/facts/freebsd/dmi_resolver.cc:16:43: error: conversion from string literal to 'char *' is deprecated
[-Werror,-Wc++11-compat-deprecated-writable-strings]
result.product_name = kenv_lookup("smbios.system.product");
^
/root/facter/lib/src/facts/freebsd/dmi_resolver.cc:17:43: error: conversion from string literal to 'char *' is deprecated
[-Werror,-Wc++11-compat-deprecated-writable-strings]
result.bios_version = kenv_lookup("smbios.bios.vendor");
^
/root/facter/lib/src/facts/freebsd/dmi_resolver.cc:22:26: error: out-of-line definition of 'kenv_lookup' does not match any
declaration in 'facter::facts::freebsd::dmi_resolver'
string dmi_resolver::kenv_lookup(char file)
^~~~~~~~~~~
/root/facter/lib/inc/internal/facts/freebsd/dmi_resolver.hpp:25:33: note: type of 1st parameter of member declaration does not
match definition ('char *' vs 'char')
std::string kenv_lookup(char *file);
^
/root/facter/lib/src/facts/freebsd/dmi_resolver.cc:27:13: error: no matching function for call to 'kenv'
if (kenv(KENV_GET, file, buffer, sizeof(buffer) - 1) == -1) {
^~~~
/usr/include/kenv.h:36:5: note: candidate function not viable: no known conversion from 'char' to 'const char *' for 2nd argument;
take the address of the argument with &
int kenv(int, const char *, char *, int);
^
我该如何解决这个问题?
理查德史密斯是正确的。工作代码如下
/Users/petersouter/projects/facter/lib/src/facts/freebsd/dmi_resolver.cc
#include <internal/facts/freebsd/dmi_resolver.hpp>
#include <leatherman/logging/logging.hpp>
#include <kenv.h>
using namespace std;
namespace facter { namespace facts { namespace freebsd {
dmi_resolver::data dmi_resolver::collect_data(collection& facts)
{
data result;
result.bios_vendor = kenv_lookup("smbios.bios.vendor");
result.bios_version = kenv_lookup("smbios.bios.version");
result.bios_release_date = kenv_lookup("smbios.bios.reldate");
result.uuid = kenv_lookup("smbios.system.uuid");
result.serial_number = kenv_lookup("smbios.planar.serial");
result.product_name = kenv_lookup("smbios.system.product");
result.manufacturer = kenv_lookup("smbios.system.maker");
return result;
}
string dmi_resolver::kenv_lookup(const char* file)
{
char buffer[100] = {};
LOG_DEBUG("kenv lookup for %s", file);
if (kenv(KENV_GET, file, buffer, sizeof(buffer) - 1) == -1) {
LOG_WARNING("kenv lookup for %1% failed: %2% (%3%)", file, strerror(errno), errno);
return "";
}
return buffer;
}
} } } // namespace facter::facts::freebsd
facter/lib/inc/internal/facts/freebsd/dmi_resolver.hpp
/**
* @file
* Declares the FreeBSD Desktop Management Interface (DMI) fact resolver.
*/
#pragma once
#include "../resolvers/dmi_resolver.hpp"
namespace facter { namespace facts { namespace freebsd {
/**
* Responsible for resolving DMI facts.
*/
struct dmi_resolver : resolvers::dmi_resolver
{
protected:
/**
* Collects the resolver data.
* @param facts The fact collection that is resolving facts.
* @return Returns the resolver data.
*/
virtual data collect_data(collection& facts) override;
private:
static std::string kenv_lookup(const char* file);
};
}}} // namespace facter::facts::freebsd