Build the service in a container, and fix what the target compiler found

The openlgtv NDK is a Linux toolchain with no macOS or Windows build, so
tools/build.sh could not produce a binary anywhere else. docker-build.sh
bakes the SDK into an image and compiles there; packaging and deploy stay
on the host, where the TV is reachable. The SDK ships aarch64 as well as
x86_64, so the image picks the one matching the daemon and Apple Silicon
builds natively rather than under emulation.

Cross-compiling for real turned up three things the host compiler did
not:

  sink_hyperhdr_viz.c  read p->width and p->height to format the error
                       message after free(p)
  sink_hyperhdr.c      an SDP connection line of 128 bytes cannot hold
                       "IN IP4 " plus a 127-byte host plus "/255", so a
                       long hostname would silently lose its TTL suffix
  common/log.c         the log body was sized to the whole ring line,
                       leaving nothing for the prefix; budget for it so
                       the bound is provable rather than left to
                       snprintf

A clean cross-compile is now warning-free, and readelf confirms the
design rule holds: luna-service2, glib, PmLogLib and libc, with no
libpulse or libasound.

Also: @webosose/ares-cli was pinned to ^3.0.0, which does not exist
(latest is 2.4.0), so npm install failed outright. build.sh now puts
node_modules/.bin on PATH so a local install is enough.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Rene Kievits
2026-08-26 10:29:09 +02:00
co-authored by Claude Opus 5
parent 7529a60650
commit 3e4d0e17bc
11 changed files with 5692 additions and 14 deletions
+6 -1
View File
@@ -9,6 +9,8 @@
#define RING_LINES 200
#define RING_LINE_LEN 256
// "HH:MM:SS.mmm [level] file.c:1234 " — 64 covers it with room to spare.
#define RING_LINE_PREFIX 64
static log_level_t s_level = LOG_INFO;
static pthread_mutex_t s_lock = PTHREAD_MUTEX_INITIALIZER;
@@ -56,7 +58,10 @@ void log_printf(log_level_t level, const char* file, int line, const char* fmt,
snprintf(stamp, sizeof(stamp), "%02d:%02d:%02d.%03d", tm.tm_hour, tm.tm_min,
tm.tm_sec, (int)(tv.tv_usec / 1000));
char body[RING_LINE_LEN];
// A ring line is a fixed size, so an over-long message is truncated rather
// than allowed to grow the buffer. Budgeting for the prefix here keeps the
// final snprintf provably within bounds instead of relying on it to clip.
char body[RING_LINE_LEN - RING_LINE_PREFIX];
va_list ap;
va_start(ap, fmt);
vsnprintf(body, sizeof(body), fmt, ap);
+3 -1
View File
@@ -79,7 +79,9 @@ static int build_sdp(hh_priv_t* p, char* out, size_t cap)
char src_str[INET_ADDRSTRLEN];
snprintf(src_str, sizeof(src_str), "%s", inet_ntoa(src));
char conn[128];
// Wide enough for the longest host plus the prefix and the TTL suffix, so
// a long hostname cannot quietly lose its "/255" to truncation.
char conn[sizeof(p->host) + 16];
if (p->multicast) {
// The /255 suffix is the TTL, required for multicast connection lines.
snprintf(conn, sizeof(conn), "IN IP4 %s/255", p->host);
+1 -1
View File
@@ -388,9 +388,9 @@ static sink_t* viz_open(const json_value_t* cfg, const audio_format_t* fmt, char
p->frame_bytes = (size_t)p->width * (size_t)p->height * 3;
p->frame = calloc(1, p->frame_bytes);
if (!p->frame) {
snprintf(err, errlen, "out of memory allocating %dx%d frame", p->width, p->height);
free(p);
free(s);
snprintf(err, errlen, "out of memory allocating %dx%d frame", p->width, p->height);
return NULL;
}