mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-10-28 07:44:06 +01:00
Common: adds more FF_DEBUG
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
#include "common/android/binder.h"
|
||||
#include "common/debug.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
@@ -9,11 +11,16 @@ const char* ffBinderOpen(FFBinder* binder) {
|
||||
|
||||
const int fd = open(FF_BINDER_DEVICE, O_RDWR | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
FF_DEBUG("open(" FF_BINDER_DEVICE ") failed: %s", strerror(errno));
|
||||
return "Failed to open " FF_BINDER_DEVICE;
|
||||
}
|
||||
|
||||
struct binder_version version = { .protocol_version = 0 };
|
||||
if (ioctl(fd, BINDER_VERSION, &version) != 0 || version.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION) {
|
||||
const int versionIoctl = ioctl(fd, BINDER_VERSION, &version);
|
||||
if (versionIoctl != 0 || version.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION) {
|
||||
FF_DEBUG("BINDER_VERSION reported protocol %u, expected %u (%s)",
|
||||
version.protocol_version, BINDER_CURRENT_PROTOCOL_VERSION,
|
||||
versionIoctl != 0 ? strerror(errno) : "version mismatch");
|
||||
close(fd);
|
||||
return "Unsupported binder protocol version";
|
||||
}
|
||||
@@ -22,6 +29,7 @@ const char* ffBinderOpen(FFBinder* binder) {
|
||||
// addresses in BR_REPLY, so it has to stay mapped for as long as the handle is used.
|
||||
void* shared = mmap(nullptr, FF_BINDER_SHARED_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, fd, 0);
|
||||
if (shared == MAP_FAILED) {
|
||||
FF_DEBUG("mmap(" FF_BINDER_DEVICE ") failed: %s", strerror(errno));
|
||||
close(fd);
|
||||
return "Failed to mmap " FF_BINDER_DEVICE;
|
||||
}
|
||||
@@ -55,6 +63,8 @@ const char* ffBinderTransact(FFBinder* binder, uint32_t handle, uint32_t code, u
|
||||
reply->fdCount = 0;
|
||||
|
||||
if (parcel->truncated) {
|
||||
FF_DEBUG("The parcel was truncated at %zu bytes, the caller buffer holds %zu",
|
||||
parcel->size, parcel->capacity);
|
||||
return "Binder parcel does not fit the caller buffer";
|
||||
}
|
||||
|
||||
@@ -86,6 +96,7 @@ const char* ffBinderTransact(FFBinder* binder, uint32_t handle, uint32_t code, u
|
||||
.read_buffer = (binder_uintptr_t) (uintptr_t) readBuffer,
|
||||
};
|
||||
if (ioctl(binder->fd, BINDER_WRITE_READ, &exchange) != 0) {
|
||||
FF_DEBUG("BINDER_WRITE_READ(handle=%u, code=%u) failed: %s", handle, code, strerror(errno));
|
||||
return "BINDER_WRITE_READ failed";
|
||||
}
|
||||
|
||||
@@ -103,8 +114,10 @@ const char* ffBinderTransact(FFBinder* binder, uint32_t handle, uint32_t code, u
|
||||
break;
|
||||
|
||||
case BR_FAILED_REPLY:
|
||||
FF_DEBUG("BR_FAILED_REPLY for handle=%u, code=%u", handle, code);
|
||||
return "Binder transaction failed";
|
||||
case BR_DEAD_REPLY:
|
||||
FF_DEBUG("BR_DEAD_REPLY: handle=%u is dead", handle);
|
||||
return "Binder service is not running";
|
||||
|
||||
case BR_INCREFS:
|
||||
@@ -123,6 +136,8 @@ const char* ffBinderTransact(FFBinder* binder, uint32_t handle, uint32_t code, u
|
||||
|
||||
case BR_REPLY: {
|
||||
if ((size_t) (end - cursor) < sizeof(struct binder_transaction_data)) {
|
||||
FF_DEBUG("BR_REPLY is truncated: %zu of %zu bytes left",
|
||||
(size_t) (end - cursor), sizeof(struct binder_transaction_data));
|
||||
return "Truncated binder reply";
|
||||
}
|
||||
struct binder_transaction_data data;
|
||||
@@ -140,6 +155,8 @@ const char* ffBinderTransact(FFBinder* binder, uint32_t handle, uint32_t code, u
|
||||
const char* error = nullptr;
|
||||
if (payloadSize > 0) {
|
||||
if (payloadSize > reply->capacity) {
|
||||
FF_DEBUG("The reply carries %zu payload bytes, the caller buffer holds %zu",
|
||||
payloadSize, reply->capacity);
|
||||
error = "Binder reply does not fit the caller buffer";
|
||||
} else {
|
||||
memcpy(reply->data, payload, payloadSize);
|
||||
@@ -211,6 +228,7 @@ const char* ffBinderTransact(FFBinder* binder, uint32_t handle, uint32_t code, u
|
||||
// later transaction on them fails with BR_FAILED_REPLY, which says nothing about the
|
||||
// real cause. Reported, but only when nothing more specific is already at hand.
|
||||
if (ioctl(binder->fd, BINDER_WRITE_READ, &release) != 0 && error == nullptr) {
|
||||
FF_DEBUG("BC_ACQUIRE/BC_FREE_BUFFER failed: %s", strerror(errno));
|
||||
error = "Releasing the binder reply failed";
|
||||
}
|
||||
|
||||
@@ -218,10 +236,13 @@ const char* ffBinderTransact(FFBinder* binder, uint32_t handle, uint32_t code, u
|
||||
}
|
||||
|
||||
default:
|
||||
FF_DEBUG("Unexpected binder command 0x%08x for handle=%u, code=%u", command, handle, code);
|
||||
return "Unexpected binder command";
|
||||
}
|
||||
}
|
||||
|
||||
FF_DEBUG("The binder reply for handle=%u, code=%u held no BR_REPLY (%zu bytes read)",
|
||||
handle, code, (size_t) exchange.read_consumed);
|
||||
return "No reply from binder";
|
||||
}
|
||||
|
||||
@@ -238,12 +259,16 @@ const char* ffBinderLookupService(FFBinder* binder, const char* name, uint32_t t
|
||||
return error;
|
||||
}
|
||||
if (ffBinderReplyIsStatus(&reply)) {
|
||||
FF_DEBUG("The service manager returned a status parcel for %s, code=%u", name, transactionCode);
|
||||
return "Service manager rejected the request";
|
||||
}
|
||||
if (ffBinderReadI32(reply.data, reply.size, 0) != 0) {
|
||||
const int32_t exception = ffBinderReadI32(reply.data, reply.size, 0);
|
||||
if (exception != 0) {
|
||||
FF_DEBUG("The service manager raised exception %d for %s", exception, name);
|
||||
return "Service manager raised an exception";
|
||||
}
|
||||
if (reply.handleCount == 0) {
|
||||
FF_DEBUG("The service manager returned no handle for %s", name);
|
||||
return "Service is not registered";
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
#include "common/debug.h"
|
||||
#include "common/mallocHelper.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
@@ -460,6 +462,8 @@ static const char* findDexEntry(const uint8_t* jar, size_t jarSize, const char*
|
||||
}
|
||||
}
|
||||
if (eocd == SIZE_MAX) {
|
||||
FF_DEBUG("No end-of-central-directory record in the last %zu bytes of a %zu byte jar",
|
||||
newest - oldest + FF_ZIP_EOCD_SIZE, jarSize);
|
||||
return "The jar has no zip directory";
|
||||
}
|
||||
|
||||
@@ -479,6 +483,8 @@ static const char* findDexEntry(const uint8_t* jar, size_t jarSize, const char*
|
||||
const uint16_t commentLength = dexU16(jar + offset + FF_ZIP_OFF_CENTRAL_COMMENT_LENGTH);
|
||||
const size_t entrySize = FF_ZIP_CENTRAL_SIZE + (size_t) nameLength + (size_t) extraLength + (size_t) commentLength;
|
||||
if (entrySize > directoryEnd - offset) {
|
||||
FF_DEBUG("A zip entry claims %zu bytes but only %zu remain in the directory",
|
||||
entrySize, (size_t) (directoryEnd - offset));
|
||||
return "A zip directory entry runs past the directory";
|
||||
}
|
||||
|
||||
@@ -487,6 +493,8 @@ static const char* findDexEntry(const uint8_t* jar, size_t jarSize, const char*
|
||||
const uint32_t uncompressed = dexU32(jar + offset + FF_ZIP_OFF_CENTRAL_UNCOMPRESSED_SIZE);
|
||||
const uint32_t localOffset = dexU32(jar + offset + FF_ZIP_OFF_CENTRAL_LOCAL_OFFSET);
|
||||
if (compressedSize == FF_ZIP_ZIP64_SENTINEL || uncompressed == FF_ZIP_ZIP64_SENTINEL || localOffset == FF_ZIP_ZIP64_SENTINEL) {
|
||||
FF_DEBUG("The dex entry is zip64: compressed=%u, uncompressed=%u, localOffset=%u",
|
||||
compressedSize, uncompressed, localOffset);
|
||||
return "A dex entry is stored as zip64, which is not supported";
|
||||
}
|
||||
if (localOffset > jarSize || FF_ZIP_LOCAL_HEADER_SIZE > jarSize - localOffset) {
|
||||
@@ -509,6 +517,7 @@ static const char* findDexEntry(const uint8_t* jar, size_t jarSize, const char*
|
||||
|
||||
offset += entrySize;
|
||||
}
|
||||
FF_DEBUG("No entry in the %zu byte jar is named %s", jarSize, entry);
|
||||
return "The jar has no usable dex entry";
|
||||
}
|
||||
|
||||
@@ -545,6 +554,7 @@ static const char* inflateDex(const uint8_t* data, size_t dataSize, uint32_t unc
|
||||
// the pointer, which is also why no failure path has to free it by hand.
|
||||
FF_AUTO_FREE uint8_t* buffer = malloc(uncompressedSize);
|
||||
if (buffer == nullptr) {
|
||||
FF_DEBUG("malloc(%u) for the inflated dex failed", uncompressedSize);
|
||||
return "malloc failed";
|
||||
}
|
||||
|
||||
@@ -557,12 +567,16 @@ static const char* inflateDex(const uint8_t* data, size_t dataSize, uint32_t unc
|
||||
stream.next_out = buffer;
|
||||
stream.avail_out = (uInt) uncompressedSize;
|
||||
|
||||
if (ffinflateInit2_(&stream, -MAX_WBITS, ZLIB_VERSION, (int) sizeof(z_stream)) != Z_OK) {
|
||||
const int initStatus = ffinflateInit2_(&stream, -MAX_WBITS, ZLIB_VERSION, (int) sizeof(z_stream));
|
||||
if (initStatus != Z_OK) {
|
||||
FF_DEBUG("inflateInit2() failed: zlib status %d", initStatus);
|
||||
return "inflateInit2 failed";
|
||||
}
|
||||
const int status = ffinflate(&stream, Z_FINISH);
|
||||
ffinflateEnd(&stream);
|
||||
if (status != Z_STREAM_END || stream.total_out != (uLong) uncompressedSize) {
|
||||
FF_DEBUG("inflate() returned %d, produced %lu of %u bytes",
|
||||
status, stream.total_out, uncompressedSize);
|
||||
return "Inflating the dex failed";
|
||||
}
|
||||
|
||||
@@ -587,19 +601,25 @@ const char* ffDexStaticInts(const char* jarPath, const FFDexStaticIntRequest* re
|
||||
|
||||
const int fd = open(jarPath, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
FF_DEBUG("open(%s) failed: %s", jarPath, strerror(errno));
|
||||
return "open(jar) failed";
|
||||
}
|
||||
|
||||
struct stat st = {};
|
||||
if (fstat(fd, &st) != 0 || st.st_size <= 0) {
|
||||
const int statStatus = fstat(fd, &st);
|
||||
if (statStatus != 0 || st.st_size <= 0) {
|
||||
FF_DEBUG("fstat(%s) reported %s (%lld bytes)", jarPath,
|
||||
statStatus != 0 ? strerror(errno) : "an empty file", (long long) st.st_size);
|
||||
close(fd);
|
||||
return "fstat(jar) failed";
|
||||
}
|
||||
mapping.mappedSize = (size_t) st.st_size;
|
||||
mapping.mapped = mmap(nullptr, mapping.mappedSize, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
// The mapping outlives the descriptor, so the descriptor can go either way from here.
|
||||
const int mmapErrno = mapping.mapped == MAP_FAILED ? errno : 0;
|
||||
close(fd);
|
||||
if (mapping.mapped == MAP_FAILED) {
|
||||
FF_DEBUG("mmap(%s, %zu bytes) failed: %s", jarPath, mapping.mappedSize, strerror(mmapErrno));
|
||||
mapping.mapped = nullptr;
|
||||
return "mmap(jar) failed";
|
||||
}
|
||||
@@ -610,6 +630,8 @@ const char* ffDexStaticInts(const char* jarPath, const FFDexStaticIntRequest* re
|
||||
FF_AUTO_FREE uint8_t* settled = calloc(count, 1);
|
||||
FF_AUTO_FREE uint32_t* typeIndexes = malloc((size_t) count * sizeof(uint32_t));
|
||||
if (settled == nullptr || typeIndexes == nullptr) {
|
||||
FF_DEBUG("Allocating %zu bytes for %u static int requests failed",
|
||||
(size_t) count * (1 + sizeof(uint32_t)), count);
|
||||
return "malloc failed";
|
||||
}
|
||||
|
||||
@@ -650,6 +672,7 @@ const char* ffDexStaticInts(const char* jarPath, const FFDexStaticIntRequest* re
|
||||
}
|
||||
data = findDexMagic(mapping.mapped, mapping.mappedSize, &dataSize);
|
||||
if (data == nullptr) {
|
||||
FF_DEBUG("Neither %s nor a dex magic signature is in the %zu byte jar", entry, mapping.mappedSize);
|
||||
return "No dex in the jar";
|
||||
}
|
||||
} else if (method == FF_ZIP_METHOD_DEFLATED) {
|
||||
@@ -664,6 +687,8 @@ const char* ffDexStaticInts(const char* jarPath, const FFDexStaticIntRequest* re
|
||||
return "The jar deflates its dex entries and fastfetch was built without zlib";
|
||||
#endif
|
||||
} else if (method != FF_ZIP_METHOD_STORED) {
|
||||
FF_DEBUG("%s uses compression method %u, only %u (stored) and %u (deflated) are handled",
|
||||
entry, method, FF_ZIP_METHOD_STORED, FF_ZIP_METHOD_DEFLATED);
|
||||
return "A dex entry uses an unsupported compression method";
|
||||
}
|
||||
// A STORED entry needs no further work: `dataSize` already holds the `compressedSize` that
|
||||
|
||||
@@ -1,36 +1,47 @@
|
||||
#include "cf_helpers.h"
|
||||
#include "common/debug.h"
|
||||
|
||||
const char* ffCfNumGetInt64(CFTypeRef cf, int64_t* result) {
|
||||
if (CFGetTypeID(cf) == CFNumberGetTypeID()) {
|
||||
if (!CFNumberGetValue((CFNumberRef) cf, kCFNumberSInt64Type, result)) {
|
||||
FF_DEBUG("CFNumberGetValue(kCFNumberSInt64Type) failed, the number is of type 0x%08lx",
|
||||
(unsigned long) CFNumberGetType((CFNumberRef) cf));
|
||||
return "Number type is not SInt64";
|
||||
}
|
||||
return nullptr;
|
||||
} else if (CFGetTypeID(cf) == CFDataGetTypeID()) {
|
||||
if (CFDataGetLength((CFDataRef) cf) != sizeof(int64_t)) {
|
||||
FF_DEBUG("CFData holds %ld bytes, int64_t needs %zu",
|
||||
(long) CFDataGetLength((CFDataRef) cf), sizeof(int64_t));
|
||||
return "Data length is not sizeof(int64_t)";
|
||||
}
|
||||
CFDataGetBytes((CFDataRef) cf, CFRangeMake(0, sizeof(int64_t)), (uint8_t*) result);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FF_DEBUG("Expected a CFNumber or CFData, got TypeID 0x%08lx", (unsigned long) CFGetTypeID(cf));
|
||||
return "TypeID is neither 'CFNumber' nor 'CFData'";
|
||||
}
|
||||
|
||||
const char* ffCfNumGetInt(CFTypeRef cf, int32_t* result) {
|
||||
if (CFGetTypeID(cf) == CFNumberGetTypeID()) {
|
||||
if (!CFNumberGetValue((CFNumberRef) cf, kCFNumberSInt32Type, result)) {
|
||||
FF_DEBUG("CFNumberGetValue(kCFNumberSInt32Type) failed, the number is of type 0x%08lx",
|
||||
(unsigned long) CFNumberGetType((CFNumberRef) cf));
|
||||
return "Number type is not SInt32";
|
||||
}
|
||||
return nullptr;
|
||||
} else if (CFGetTypeID(cf) == CFDataGetTypeID()) {
|
||||
if (CFDataGetLength((CFDataRef) cf) != sizeof(*result)) {
|
||||
FF_DEBUG("CFData holds %ld bytes, int32_t needs %zu",
|
||||
(long) CFDataGetLength((CFDataRef) cf), sizeof(*result));
|
||||
return "Data length is not sizeof(int32_t)";
|
||||
}
|
||||
CFDataGetBytes((CFDataRef) cf, CFRangeMake(0, sizeof(*result)), (uint8_t*) result);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FF_DEBUG("Expected a CFNumber or CFData, got TypeID 0x%08lx", (unsigned long) CFGetTypeID(cf));
|
||||
return "TypeID is neither 'CFNumber' nor 'CFData'";
|
||||
}
|
||||
|
||||
@@ -38,16 +49,20 @@ const char* ffCfNumGetDouble(CFTypeRef cf, double* result) {
|
||||
if (CFGetTypeID(cf) == CFNumberGetTypeID()) {
|
||||
if (!CFNumberGetValue((CFNumberRef) cf, kCFNumberDoubleType, result) &&
|
||||
!CFNumberGetValue((CFNumberRef) cf, kCFNumberFloatType, result)) {
|
||||
FF_DEBUG("CFNumber is of type 0x%08lx, neither Double nor Float",
|
||||
(unsigned long) CFNumberGetType((CFNumberRef) cf));
|
||||
return "Number type is not Double or Float";
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FF_DEBUG("Expected a CFNumber, got TypeID 0x%08lx", (unsigned long) CFGetTypeID(cf));
|
||||
return "TypeID is neither 'CFNumber'";
|
||||
}
|
||||
|
||||
const char* ffCfDateGetEpoch(CFTypeRef cf, uint64_t* result) {
|
||||
if (CFGetTypeID(cf) != CFDateGetTypeID()) {
|
||||
FF_DEBUG("Expected a CFDate, got TypeID 0x%08lx", (unsigned long) CFGetTypeID(cf));
|
||||
return "TypeID is not 'CFDate'";
|
||||
}
|
||||
|
||||
@@ -76,6 +91,7 @@ const char* ffCfStrGetString(CFTypeRef cf, FFstrbuf* result) {
|
||||
}
|
||||
ffStrbufEnsureFixedLengthFree(result, (uint32_t) CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8));
|
||||
if (!CFStringGetCString(cfStr, result->chars, result->allocated, kCFStringEncodingUTF8)) {
|
||||
FF_DEBUG("CFStringGetCString() failed for a %u character string", (unsigned) length);
|
||||
return "CFStringGetCString() failed";
|
||||
}
|
||||
// CFStringGetCString ensures the buffer is NUL terminated
|
||||
@@ -93,6 +109,7 @@ const char* ffCfStrGetString(CFTypeRef cf, FFstrbuf* result) {
|
||||
result->length = (uint32_t) strnlen(result->chars, length);
|
||||
result->chars[result->length] = '\0';
|
||||
} else {
|
||||
FF_DEBUG("Expected a CFString or CFData, got TypeID 0x%08lx", (unsigned long) CFGetTypeID(cf));
|
||||
return "TypeID is neither 'CFString' nor 'CFData'";
|
||||
}
|
||||
|
||||
@@ -116,6 +133,7 @@ const char* ffCfDataGetDataAsString(CFTypeRef cf, FFstrbuf* result) {
|
||||
result->length = length;
|
||||
result->chars[result->length] = '\0';
|
||||
} else {
|
||||
FF_DEBUG("Expected a CFData, got TypeID 0x%08lx", (unsigned long) CFGetTypeID(cf));
|
||||
return "TypeID is not 'CFData'";
|
||||
}
|
||||
|
||||
@@ -125,6 +143,7 @@ const char* ffCfDataGetDataAsString(CFTypeRef cf, FFstrbuf* result) {
|
||||
const char* ffCfDictGetString(CFDictionaryRef dict, CFStringRef key, FFstrbuf* result) {
|
||||
CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
|
||||
if (cf == nullptr) {
|
||||
FF_DEBUG("The dictionary has no value for the key");
|
||||
return "CFDictionaryGetValue() failed";
|
||||
}
|
||||
|
||||
@@ -134,6 +153,7 @@ const char* ffCfDictGetString(CFDictionaryRef dict, CFStringRef key, FFstrbuf* r
|
||||
const char* ffCfDictGetDataAsString(CFDictionaryRef dict, CFStringRef key, FFstrbuf* result) {
|
||||
CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
|
||||
if (cf == nullptr) {
|
||||
FF_DEBUG("The dictionary has no value for the key");
|
||||
return "CFDictionaryGetValue() failed";
|
||||
}
|
||||
|
||||
@@ -143,10 +163,12 @@ const char* ffCfDictGetDataAsString(CFDictionaryRef dict, CFStringRef key, FFstr
|
||||
const char* ffCfDictGetBool(CFDictionaryRef dict, CFStringRef key, bool* result) {
|
||||
CFBooleanRef cf = (CFBooleanRef) CFDictionaryGetValue(dict, key);
|
||||
if (cf == nullptr) {
|
||||
FF_DEBUG("The dictionary has no value for the key");
|
||||
return "CFDictionaryGetValue() failed";
|
||||
}
|
||||
|
||||
if (CFGetTypeID(cf) != CFBooleanGetTypeID()) {
|
||||
FF_DEBUG("Expected a CFBoolean, got TypeID 0x%08lx", (unsigned long) CFGetTypeID(cf));
|
||||
return "TypeID is not 'CFBoolean'";
|
||||
}
|
||||
|
||||
@@ -157,6 +179,7 @@ const char* ffCfDictGetBool(CFDictionaryRef dict, CFStringRef key, bool* result)
|
||||
const char* ffCfDictGetInt(CFDictionaryRef dict, CFStringRef key, int* result) {
|
||||
CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
|
||||
if (cf == nullptr) {
|
||||
FF_DEBUG("The dictionary has no value for the key");
|
||||
return "CFDictionaryGetValue() failed";
|
||||
}
|
||||
|
||||
@@ -166,6 +189,7 @@ const char* ffCfDictGetInt(CFDictionaryRef dict, CFStringRef key, int* result) {
|
||||
const char* ffCfDictGetInt64(CFDictionaryRef dict, CFStringRef key, int64_t* result) {
|
||||
CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
|
||||
if (cf == nullptr) {
|
||||
FF_DEBUG("The dictionary has no value for the key");
|
||||
return "CFDictionaryGetValue() failed";
|
||||
}
|
||||
|
||||
@@ -175,6 +199,7 @@ const char* ffCfDictGetInt64(CFDictionaryRef dict, CFStringRef key, int64_t* res
|
||||
const char* ffCfDictGetDouble(CFDictionaryRef dict, CFStringRef key, double* result) {
|
||||
CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
|
||||
if (cf == nullptr) {
|
||||
FF_DEBUG("The dictionary has no value for the key");
|
||||
return "CFDictionaryGetValue() failed";
|
||||
}
|
||||
|
||||
@@ -184,16 +209,20 @@ const char* ffCfDictGetDouble(CFDictionaryRef dict, CFStringRef key, double* res
|
||||
const char* ffCfDictGetData(CFDictionaryRef dict, CFStringRef key, uint32_t offset, uint32_t size, uint8_t* result, uint32_t* length) {
|
||||
CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
|
||||
if (cf == nullptr) {
|
||||
FF_DEBUG("The dictionary has no value for the key");
|
||||
return "CFDictionaryGetValue() failed";
|
||||
}
|
||||
|
||||
if (CFGetTypeID(cf) != CFDataGetTypeID()) {
|
||||
FF_DEBUG("Expected a CFData, got TypeID 0x%08lx", (unsigned long) CFGetTypeID(cf));
|
||||
return "TypeID is not 'CFData'";
|
||||
}
|
||||
|
||||
CFIndex trueLength = CFDataGetLength((CFDataRef) cf);
|
||||
|
||||
if (trueLength < offset + size) {
|
||||
FF_DEBUG("The CFData holds %ld bytes, the caller asked for [%u, %u)",
|
||||
(long) trueLength, offset, offset + size);
|
||||
return "Data length is less than offset + size";
|
||||
}
|
||||
|
||||
@@ -208,6 +237,8 @@ const char* ffCfDictGetData(CFDictionaryRef dict, CFStringRef key, uint32_t offs
|
||||
const char* ffCfDictGetDict(CFDictionaryRef dict, CFStringRef key, CFDictionaryRef* result) {
|
||||
CFDictionaryRef cf = (CFDictionaryRef) CFDictionaryGetValue(dict, key);
|
||||
if (cf == nullptr || CFGetTypeID(cf) != CFDictionaryGetTypeID()) {
|
||||
FF_DEBUG("Expected a CFDictionary, got %s",
|
||||
cf == nullptr ? "no value at all" : "a value of another type");
|
||||
return "TypeID is not 'CFDictionary'";
|
||||
}
|
||||
|
||||
@@ -218,6 +249,7 @@ const char* ffCfDictGetDict(CFDictionaryRef dict, CFStringRef key, CFDictionaryR
|
||||
const char* ffCfDictGetDateAsEpoch(CFDictionaryRef dict, CFStringRef key, uint64_t* result) {
|
||||
CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
|
||||
if (cf == nullptr) {
|
||||
FF_DEBUG("The dictionary has no value for the key");
|
||||
return "CFDictionaryGetValue() failed";
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "smc_temps.h"
|
||||
#include "common/apple/cf_helpers.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/strutil.h"
|
||||
|
||||
#include <stdint.h>
|
||||
@@ -83,7 +84,10 @@ static void smcUltostr(char* str, uint32_t val) {
|
||||
static const char* smcCall(io_connect_t conn, uint32_t selector, SmcKeyData_t* inputStructure, SmcKeyData_t* outputStructure) {
|
||||
size_t size = sizeof(SmcKeyData_t);
|
||||
|
||||
if (IOConnectCallStructMethod(conn, selector, inputStructure, size, outputStructure, &size) != kIOReturnSuccess) {
|
||||
const IOReturn callStatus = IOConnectCallStructMethod(conn, selector, inputStructure, size, outputStructure, &size);
|
||||
if (callStatus != kIOReturnSuccess) {
|
||||
FF_DEBUG("IOConnectCallStructMethod(selector=%u, command=%u) failed: IOReturn 0x%08x",
|
||||
selector, (uint32_t) (unsigned char) inputStructure->data8, (unsigned) callStatus);
|
||||
return "IOConnectCallStructMethod(conn) failed";
|
||||
}
|
||||
return nullptr;
|
||||
@@ -136,10 +140,13 @@ static const char* smcReadSmcVal(io_connect_t conn, const UInt32Char_t key, SmcV
|
||||
static const char* smcOpen(io_connect_t* conn) {
|
||||
FF_IOOBJECT_AUTO_RELEASE io_object_t device = IOServiceGetMatchingService(MACH_PORT_NULL, IOServiceMatching("AppleSMC"));
|
||||
if (!device) {
|
||||
FF_DEBUG("IOKit has no AppleSMC service");
|
||||
return "No SMC device found";
|
||||
}
|
||||
|
||||
if (IOServiceOpen(device, mach_task_self(), 0, conn) != kIOReturnSuccess) {
|
||||
const IOReturn openStatus = IOServiceOpen(device, mach_task_self(), 0, conn);
|
||||
if (openStatus != kIOReturnSuccess) {
|
||||
FF_DEBUG("IOServiceOpen(AppleSMC) failed: IOReturn 0x%08x", (unsigned) openStatus);
|
||||
return "IOServiceOpen() failed";
|
||||
}
|
||||
|
||||
@@ -153,6 +160,7 @@ static const char* smcReadValue(io_connect_t conn, const UInt32Char_t key, doubl
|
||||
return error;
|
||||
}
|
||||
if (val.dataSize == 0) {
|
||||
FF_DEBUG("The SMC key %s reported a data size of 0", key);
|
||||
return "Empty SMC result";
|
||||
}
|
||||
|
||||
@@ -173,9 +181,12 @@ static const char* smcReadValue(io_connect_t conn, const UInt32Char_t key, doubl
|
||||
*value = (double) ntohll(*(uint64_t*) (val.bytes));
|
||||
break;
|
||||
default:
|
||||
FF_DEBUG("SMC key %s: unsigned type %s has an unsupported size of %u bytes",
|
||||
key, val.dataType, val.dataSize);
|
||||
return "Unsupported SMC unsigned integer data size";
|
||||
}
|
||||
} else {
|
||||
FF_DEBUG("SMC key %s: unsupported unsigned type %s", key, val.dataType);
|
||||
return "Unsupported SMC unsigned data type";
|
||||
}
|
||||
break;
|
||||
@@ -204,9 +215,13 @@ static const char* smcReadValue(io_connect_t conn, const UInt32Char_t key, doubl
|
||||
} else if (ffStrEquals(val.dataType, "fpe2")) {
|
||||
*value = ntohs(*(uint16_t*) (val.bytes)) / 4.0;
|
||||
} else {
|
||||
FF_DEBUG("SMC key %s: unsupported fixed point type %s of %u bytes",
|
||||
key, val.dataType, val.dataSize);
|
||||
return "Unsupported SMC floating point data type";
|
||||
}
|
||||
} else {
|
||||
FF_DEBUG("SMC key %s: unsupported floating point type %s of %u bytes",
|
||||
key, val.dataType, val.dataSize);
|
||||
return "Unsupported SMC floating point data type";
|
||||
}
|
||||
break;
|
||||
@@ -227,6 +242,8 @@ static const char* smcReadValue(io_connect_t conn, const UInt32Char_t key, doubl
|
||||
*value = (double) ntohll(*(int64_t*) (val.bytes));
|
||||
break;
|
||||
default:
|
||||
FF_DEBUG("SMC key %s: signed type %s has an unsupported size of %u bytes",
|
||||
key, val.dataType, val.dataSize);
|
||||
return "Unsupported SMC signed integer data size";
|
||||
}
|
||||
} else if (val.dataType[1] == 'p' && val.dataSize == 2) // signed fixed point types
|
||||
@@ -252,9 +269,12 @@ static const char* smcReadValue(io_connect_t conn, const UInt32Char_t key, doubl
|
||||
} else if (ffStrEquals(val.dataType, "spf0")) {
|
||||
*value = (int16_t) ntohs(*(int16_t*) (val.bytes)) / 1.0;
|
||||
} else {
|
||||
FF_DEBUG("SMC key %s: unsupported signed fixed point type %s of %u bytes",
|
||||
key, val.dataType, val.dataSize);
|
||||
return "Unsupported SMC signed integer data type";
|
||||
}
|
||||
} else {
|
||||
FF_DEBUG("SMC key %s: unsupported signed type %s", key, val.dataType);
|
||||
return "Unsupported SMC signed data type";
|
||||
}
|
||||
break;
|
||||
@@ -263,11 +283,15 @@ static const char* smcReadValue(io_connect_t conn, const UInt32Char_t key, doubl
|
||||
if (ffStrEquals(val.dataType, "{pwm") && val.dataSize == 2) {
|
||||
*value = (double) ntohs(*(uint16_t*) (val.bytes)) * 100 / 65536.0;
|
||||
} else {
|
||||
FF_DEBUG("SMC key %s: unsupported special type %s of %u bytes", key, val.dataType, val.dataSize);
|
||||
return "Unsupported SMC special data type";
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
FF_DEBUG("SMC key %s: unknown data type '%c%c' (%s) of %u bytes",
|
||||
key, val.dataType[0] ? val.dataType[0] : '?', val.dataType[1] ? val.dataType[1] : '?',
|
||||
val.dataType, val.dataSize);
|
||||
return "Unsupported SMC data type";
|
||||
}
|
||||
return nullptr;
|
||||
@@ -300,6 +324,7 @@ const char* ffDetectSmcSpecificTemp(const char* sensor, double* result) {
|
||||
}
|
||||
|
||||
if (!detectTemp(conn, sensor, result)) {
|
||||
FF_DEBUG("The SMC sensor %s could not be read, or read a value outside 10..120", sensor);
|
||||
return "Could not read SMC temperature";
|
||||
}
|
||||
|
||||
@@ -490,6 +515,7 @@ const char* ffDetectSmcTemps(enum FFTempType type, double* result) {
|
||||
break;
|
||||
}
|
||||
|
||||
FF_DEBUG("None of the SMC sensors for temp type %d reported a usable reading", (int) type);
|
||||
if (count == 0) {
|
||||
return "No temperatures detected";
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#ifdef FF_HAVE_DBUS
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/thread.h"
|
||||
#include "common/strutil.h"
|
||||
|
||||
@@ -39,11 +40,13 @@ static const FFDBusLibrary* loadLib(void) {
|
||||
const char* ffDBusLoadData(DBusBusType busType, FFDBusData* data) {
|
||||
data->lib = loadLib();
|
||||
if (data->lib == nullptr) {
|
||||
FF_DEBUG("libdbus-1 could not be loaded");
|
||||
return "Failed to load DBus library";
|
||||
}
|
||||
|
||||
data->connection = data->lib->ffdbus_bus_get(busType, nullptr);
|
||||
if (data->connection == nullptr) {
|
||||
FF_DEBUG("dbus_bus_get(busType=%d) returned no connection", (int) busType);
|
||||
return "Failed to connect to DBus";
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "common/io.h"
|
||||
#include "fastfetch.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/strutil.h"
|
||||
#include "common/time.h"
|
||||
|
||||
@@ -41,9 +42,11 @@ bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data) {
|
||||
createSubfolders(fileName);
|
||||
fd = open(fileName, openFlagsModes, openFlagsRights);
|
||||
if (fd == -1) {
|
||||
FF_DEBUG("open(%s) failed after creating the parent folders: %s", fileName, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
FF_DEBUG("open(%s) failed: %s", fileName, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -146,16 +149,19 @@ const char* ffGetTerminalResponse(const char* request, int nParams, const char*
|
||||
if (ftty < 0) {
|
||||
ftty = open("/dev/tty", O_RDWR | O_NOCTTY | O_CLOEXEC);
|
||||
if (ftty < 0) {
|
||||
FF_DEBUG("open(/dev/tty) failed: %s", strerror(errno));
|
||||
return "open(\"/dev/tty\", O_RDWR | O_NOCTTY | O_CLOEXEC) failed";
|
||||
}
|
||||
|
||||
if (tcgetattr(ftty, &oldTerm) == -1) {
|
||||
FF_DEBUG("tcgetattr(/dev/tty) failed: %s", strerror(errno));
|
||||
return "tcgetattr(STDIN_FILENO, &oldTerm) failed";
|
||||
}
|
||||
|
||||
struct termios newTerm = oldTerm;
|
||||
newTerm.c_lflag &= (tcflag_t) ~(ICANON | ECHO);
|
||||
if (tcsetattr(ftty, TCSAFLUSH, &newTerm) == -1) {
|
||||
FF_DEBUG("tcsetattr(/dev/tty) failed: %s", strerror(errno));
|
||||
return "tcsetattr(STDIN_FILENO, TCSAFLUSH, &newTerm)";
|
||||
}
|
||||
atexit(restoreTerm);
|
||||
@@ -165,7 +171,10 @@ const char* ffGetTerminalResponse(const char* request, int nParams, const char*
|
||||
|
||||
// Give the terminal some time to respond
|
||||
#ifndef __APPLE__
|
||||
if (poll(&(struct pollfd) { .fd = ftty, .events = POLLIN }, 1, FF_IO_TERM_RESP_WAIT_MS) <= 0) {
|
||||
const int pollResult = poll(&(struct pollfd) { .fd = ftty, .events = POLLIN }, 1, FF_IO_TERM_RESP_WAIT_MS);
|
||||
if (pollResult <= 0) {
|
||||
FF_DEBUG("poll(/dev/tty) returned %d after %d ms: %s",
|
||||
pollResult, FF_IO_TERM_RESP_WAIT_MS, pollResult == 0 ? "timed out" : strerror(errno));
|
||||
return "poll(/dev/tty) timeout or failed";
|
||||
}
|
||||
#else
|
||||
@@ -175,7 +184,10 @@ const char* ffGetTerminalResponse(const char* request, int nParams, const char*
|
||||
fd_set rd;
|
||||
FD_ZERO(&rd);
|
||||
FD_SET(ftty, &rd);
|
||||
if (select(ftty + 1, &rd, nullptr, nullptr, &(struct timeval) { .tv_sec = FF_IO_TERM_RESP_WAIT_MS / 1000, .tv_usec = (FF_IO_TERM_RESP_WAIT_MS % 1000) * 1000 }) <= 0) {
|
||||
const int selectResult = select(ftty + 1, &rd, nullptr, nullptr, &(struct timeval) { .tv_sec = FF_IO_TERM_RESP_WAIT_MS / 1000, .tv_usec = (FF_IO_TERM_RESP_WAIT_MS % 1000) * 1000 });
|
||||
if (selectResult <= 0) {
|
||||
FF_DEBUG("select(/dev/tty) returned %d after %d ms: %s",
|
||||
selectResult, FF_IO_TERM_RESP_WAIT_MS, selectResult == 0 ? "timed out" : strerror(errno));
|
||||
return "select(/dev/tty) timeout or failed";
|
||||
}
|
||||
}
|
||||
@@ -191,6 +203,8 @@ const char* ffGetTerminalResponse(const char* request, int nParams, const char*
|
||||
ssize_t nRead = read(ftty, buffer + bytesRead, sizeof(buffer) - bytesRead - 1);
|
||||
|
||||
if (nRead <= 0) {
|
||||
FF_DEBUG("read(/dev/tty) returned %zd after %zu bytes: %s",
|
||||
nRead, bytesRead, nRead == 0 ? "the terminal closed the connection" : strerror(errno));
|
||||
va_end(args);
|
||||
return "read(STDIN_FILENO, buffer, sizeof(buffer) - 1) failed";
|
||||
}
|
||||
@@ -204,6 +218,7 @@ const char* ffGetTerminalResponse(const char* request, int nParams, const char*
|
||||
va_end(cargs);
|
||||
|
||||
if (ret <= 0) {
|
||||
FF_DEBUG("vsscanf(\"%s\") matched %d of %d parameters", buffer, ret, nParams);
|
||||
va_end(args);
|
||||
return "vsscanf(buffer, format, args) failed";
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/color.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/jsonconfig.h"
|
||||
#include "common/printing.h"
|
||||
#include "common/io.h"
|
||||
@@ -87,6 +88,7 @@ const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair p
|
||||
}
|
||||
}
|
||||
|
||||
FF_DEBUG("The enum value %d is not one of the accepted integers", intVal);
|
||||
return "Invalid enum integer";
|
||||
} else if (yyjson_is_str(val)) {
|
||||
const char* strVal = yyjson_get_str(val);
|
||||
@@ -97,8 +99,11 @@ const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair p
|
||||
}
|
||||
}
|
||||
|
||||
FF_DEBUG("The enum string \"%s\" is not one of the accepted names", strVal);
|
||||
return "Invalid enum string";
|
||||
} else {
|
||||
FF_DEBUG("The enum value is of JSON type %s, not a string or an integer",
|
||||
yyjson_get_type_desc(val));
|
||||
return "Invalid enum value type; must be a string or integer";
|
||||
}
|
||||
}
|
||||
@@ -273,6 +278,7 @@ static const char* printJsonConfig(FFdata* data, bool prepare) {
|
||||
assert(root);
|
||||
|
||||
if (!yyjson_is_obj(root)) {
|
||||
FF_DEBUG("The config root is of JSON type %s", yyjson_get_type_desc(root));
|
||||
return "Invalid JSON config format. Root value must be an object";
|
||||
}
|
||||
|
||||
@@ -281,6 +287,7 @@ static const char* printJsonConfig(FFdata* data, bool prepare) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!yyjson_is_arr(modules)) {
|
||||
FF_DEBUG("'modules' is of JSON type %s", yyjson_get_type_desc(modules));
|
||||
return "Property 'modules' must be an array of strings or objects";
|
||||
}
|
||||
|
||||
@@ -303,6 +310,7 @@ static const char* printJsonConfig(FFdata* data, bool prepare) {
|
||||
yyjson_val* conditions = yyjson_obj_get(module, "condition");
|
||||
if (conditions) {
|
||||
if (!yyjson_is_obj(conditions)) {
|
||||
FF_DEBUG("'condition' is of JSON type %s", yyjson_get_type_desc(conditions));
|
||||
return "Property 'condition' must be an object";
|
||||
}
|
||||
|
||||
@@ -329,6 +337,8 @@ static const char* printJsonConfig(FFdata* data, bool prepare) {
|
||||
yyjson_val* previousSucceeded = yyjson_obj_get(conditions, "succeeded");
|
||||
if (previousSucceeded && !unsafe_yyjson_is_null(previousSucceeded)) {
|
||||
if (!unsafe_yyjson_is_bool(previousSucceeded)) {
|
||||
FF_DEBUG("'condition.succeeded' is of JSON type %s",
|
||||
yyjson_get_type_desc(previousSucceeded));
|
||||
return "Property 'succeeded' in 'condition' must be a boolean";
|
||||
}
|
||||
gatedOnSucceeded = true;
|
||||
@@ -355,6 +365,7 @@ static const char* printJsonConfig(FFdata* data, bool prepare) {
|
||||
if (gatedOnSucceeded && ffStrEqualsIgnCase(yyjson_get_str(yyjson_obj_get(module, "type")), ffCommandModuleInfo.name)) {
|
||||
yyjson_val* parallel = yyjson_obj_get(module, "parallel");
|
||||
if (parallel == nullptr || yyjson_get_bool(parallel)) {
|
||||
FF_DEBUG("The command module at index %zu is gated on 'condition.succeeded' and runs in parallel", idx);
|
||||
return "Module \"command\" cannot be combined with \"condition.succeeded\" while it runs in "
|
||||
"parallel: whether it is printed is only known in the print pass, so it cannot be "
|
||||
"prepared, and the prepared results are matched to modules by position. Set "
|
||||
@@ -371,12 +382,14 @@ static const char* printJsonConfig(FFdata* data, bool prepare) {
|
||||
|
||||
type = yyjson_get_str(yyjson_obj_get(module, "type"));
|
||||
if (!type) {
|
||||
FF_DEBUG("The module object at index %zu has no \"type\" key, or it is not a string", idx);
|
||||
return "module object must contain a \"type\" key ( case sensitive )";
|
||||
}
|
||||
if (yyjson_obj_size(module) == 1) { // contains only Property type
|
||||
module = nullptr;
|
||||
}
|
||||
} else {
|
||||
FF_DEBUG("The modules entry at index %zu is of JSON type %s", idx, yyjson_get_type_desc(module));
|
||||
return "modules must be an array of strings or objects";
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#if FF_HAVE_LUA
|
||||
|
||||
#include "common/lua.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/mallocHelper.h"
|
||||
|
||||
struct FFLuaData luaData;
|
||||
@@ -141,6 +142,7 @@ static int yyjsonEncode(lua_State* L) {
|
||||
const char* ffLuaLoadState(void) {
|
||||
if (luaData.inited) {
|
||||
if (luaData.L == nullptr) {
|
||||
FF_DEBUG("The Lua state was already initialised and is gone");
|
||||
return "Lua library is not available";
|
||||
}
|
||||
return nullptr;
|
||||
@@ -212,6 +214,7 @@ const char* ffLuaLoadState(void) {
|
||||
|
||||
lua_State* L = ffluaL_newstate();
|
||||
if (L == nullptr) {
|
||||
FF_DEBUG("luaL_newstate() could not allocate an interpreter");
|
||||
return "luaL_newstate() failed";
|
||||
}
|
||||
#if LUA_VERSION_NUM >= 505
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "common/path.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/io.h"
|
||||
#include "common/arrutil.h"
|
||||
|
||||
@@ -6,6 +7,7 @@
|
||||
const char* ffFindExecutableInPath(const char* name, FFstrbuf* result) {
|
||||
char* path = getenv("PATH");
|
||||
if (!path) {
|
||||
FF_DEBUG("The PATH environment variable is not set");
|
||||
return "$PATH not set";
|
||||
}
|
||||
|
||||
@@ -50,6 +52,7 @@ const char* ffFindExecutableInPath(const char* name, FFstrbuf* result) {
|
||||
return nullptr;
|
||||
}
|
||||
ffStrbufClear(result);
|
||||
FF_DEBUG("%s is not executable in any of the %s entries", name, "PATH");
|
||||
return "Executable not found";
|
||||
}
|
||||
#else
|
||||
@@ -62,6 +65,7 @@ const char* ffFindExecutableInPath(const char* name, FFstrbuf* result) {
|
||||
char buffer[MAX_PATH + 1];
|
||||
DWORD length = SearchPathA(nullptr, name, ".exe", sizeof(buffer), buffer, nullptr);
|
||||
if (length == 0) {
|
||||
FF_DEBUG("SearchPathA(%s) failed: %s", name, ffDebugWin32Error(GetLastError()));
|
||||
ffStrbufClear(result);
|
||||
return "Executable not found";
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/percent.h"
|
||||
#include "common/color.h"
|
||||
#include "common/option.h"
|
||||
@@ -27,6 +28,8 @@ const char* ffPercentParseTypeJsonConfig(yyjson_val* jsonVal, FFPercentageTypeFl
|
||||
yyjson_arr_foreach (jsonVal, idx, max, item) {
|
||||
const char* flag = yyjson_get_str(item);
|
||||
if (!flag) {
|
||||
FF_DEBUG("A percent.type array entry is of JSON type %s, not a string",
|
||||
yyjson_get_type_desc(item));
|
||||
return "Error: percent.type: invalid flag string";
|
||||
}
|
||||
if (ffStrEqualsIgnCase(flag, "num")) {
|
||||
@@ -40,6 +43,7 @@ const char* ffPercentParseTypeJsonConfig(yyjson_val* jsonVal, FFPercentageTypeFl
|
||||
} else if (ffStrEqualsIgnCase(flag, "bar-monochrome")) {
|
||||
flags |= FF_PERCENTAGE_TYPE_BAR_MONOCHROME_BIT;
|
||||
} else {
|
||||
FF_DEBUG("Unknown percent.type flag \"%s\"", flag);
|
||||
return "Error: percent.type: unknown flag string";
|
||||
}
|
||||
}
|
||||
@@ -48,6 +52,7 @@ const char* ffPercentParseTypeJsonConfig(yyjson_val* jsonVal, FFPercentageTypeFl
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FF_DEBUG("percent.type is of JSON type %s", yyjson_get_type_desc(jsonVal));
|
||||
return "Error: usage: percent.type must be a number or an array of strings";
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
#include "common/sysctl.h"
|
||||
#include "common/debug.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
const char* ffSysctlGetString(int mib1, int mib2, FFstrbuf* result) {
|
||||
size_t neededLength;
|
||||
if (sysctl((int[]) { mib1, mib2 }, 2, nullptr, &neededLength, nullptr, 0) != 0 || neededLength == 1) { // neededLength is 1 for empty strings, because of the null terminator
|
||||
FF_DEBUG("sysctl({%d, %d}) length query failed: %s", mib1, mib2, strerror(errno));
|
||||
return "sysctl() length query failed";
|
||||
}
|
||||
|
||||
ffStrbufEnsureFree(result, (uint32_t) neededLength - 1);
|
||||
|
||||
if (sysctl((int[]) { mib1, mib2 }, 2, result->chars + result->length, &neededLength, nullptr, 0) != 0) {
|
||||
FF_DEBUG("sysctl({%d, %d}) failed to retrieve %zu bytes: %s", mib1, mib2, neededLength, strerror(errno));
|
||||
return "sysctl() failed to retrieve string data";
|
||||
}
|
||||
|
||||
@@ -62,12 +67,14 @@ int64_t ffSysctlGetInt64(int mib1, int mib2, int64_t defaultValue) {
|
||||
const char* ffSysctlGetString(const char* propName, FFstrbuf* result) {
|
||||
size_t neededLength;
|
||||
if (sysctlbyname(propName, nullptr, &neededLength, nullptr, 0) != 0 || neededLength == 1) { // neededLength is 1 for empty strings, because of the null terminator
|
||||
FF_DEBUG("sysctlbyname(%s) length query failed: %s", propName, strerror(errno));
|
||||
return "sysctlbyname() failed";
|
||||
}
|
||||
|
||||
ffStrbufEnsureFree(result, (uint32_t) neededLength - 1);
|
||||
|
||||
if (sysctlbyname(propName, result->chars + result->length, &neededLength, nullptr, 0) != 0) {
|
||||
FF_DEBUG("sysctlbyname(%s) failed to retrieve %zu bytes: %s", propName, neededLength, strerror(errno));
|
||||
return "sysctlbyname() failed to retrieve string data";
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user