diff --git a/src/cryptonote_basic/miner.cpp b/src/cryptonote_basic/miner.cpp index 93f24875b..c90ab0f03 100644 --- a/src/cryptonote_basic/miner.cpp +++ b/src/cryptonote_basic/miner.cpp @@ -53,6 +53,19 @@ #include #endif +#ifdef __FreeBSD__ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "miner" @@ -783,6 +796,33 @@ namespace cryptonote return true; + #elif defined(__FreeBSD__) + + struct statinfo s; + size_t n = sizeof(s.cp_time); + if( sysctlbyname("kern.cp_time", s.cp_time, &n, NULL, 0) == -1 ) + { + LOG_ERROR("sysctlbyname(\"kern.cp_time\"): " << strerror(errno)); + return false; + } + if( n != sizeof(s.cp_time) ) + { + LOG_ERROR("sysctlbyname(\"kern.cp_time\") output is unexpectedly " + << n << " bytes instead of the expected " << sizeof(s.cp_time) + << " bytes."); + return false; + } + + idle_time = s.cp_time[CP_IDLE]; + total_time = + s.cp_time[CP_USER] + + s.cp_time[CP_NICE] + + s.cp_time[CP_SYS] + + s.cp_time[CP_INTR] + + s.cp_time[CP_IDLE]; + + return true; + #endif return false; // unsupported system @@ -805,7 +845,7 @@ namespace cryptonote return true; } - #elif (defined(__linux__) && defined(_SC_CLK_TCK)) || defined(__APPLE__) + #elif (defined(__linux__) && defined(_SC_CLK_TCK)) || defined(__APPLE__) || defined(__FreeBSD__) struct tms tms; if ( times(&tms) != (clock_t)-1 ) @@ -927,6 +967,70 @@ namespace cryptonote } return on_battery; + #elif defined(__FreeBSD__) + int ac; + size_t n = sizeof(ac); + if( sysctlbyname("hw.acpi.acline", &ac, &n, NULL, 0) == -1 ) + { + if( errno != ENOENT ) + { + LOG_ERROR("Cannot query battery status: " + << "sysctlbyname(\"hw.acpi.acline\"): " << strerror(errno)); + return boost::logic::tribool(boost::logic::indeterminate); + } + + // If sysctl fails with ENOENT, then try querying /dev/apm. + + static const char* dev_apm = "/dev/apm"; + const int fd = open(dev_apm, O_RDONLY); + if( fd == -1 ) { + LOG_ERROR("Cannot query battery status: " + << "open(): " << dev_apm << ": " << strerror(errno)); + return boost::logic::tribool(boost::logic::indeterminate); + } + + apm_info info; + if( ioctl(fd, APMIO_GETINFO, &info) == -1 ) { + close(fd); + LOG_ERROR("Cannot query battery status: " + << "ioctl(" << dev_apm << ", APMIO_GETINFO): " << strerror(errno)); + return boost::logic::tribool(boost::logic::indeterminate); + } + + close(fd); + + // See apm(8). + switch( info.ai_acline ) + { + case 0: // off-line + case 2: // backup power + return boost::logic::tribool(true); + case 1: // on-line + return boost::logic::tribool(false); + } + switch( info.ai_batt_stat ) + { + case 0: // high + case 1: // low + case 2: // critical + return boost::logic::tribool(true); + case 3: // charging + return boost::logic::tribool(false); + } + + LOG_ERROR("Cannot query battery status: " + << "sysctl hw.acpi.acline is not available and /dev/apm returns " + << "unexpected ac-line status (" << info.ai_acline << ") and " + << "battery status (" << info.ai_batt_stat << ")."); + return boost::logic::tribool(boost::logic::indeterminate); + } + if( n != sizeof(ac) ) + { + LOG_ERROR("sysctlbyname(\"hw.acpi.acline\") output is unexpectedly " + << n << " bytes instead of the expected " << sizeof(ac) << " bytes."); + return boost::logic::tribool(boost::logic::indeterminate); + } + return boost::logic::tribool(ac == 0); #endif LOG_ERROR("couldn't query power status");