the session readers use getline(3), which a Windows CRT does not have

Building the Windows TUI by hand -- the first local build since the CI file
went away -- stopped in src/tools/session_tools.c: `getline` was an implicit
declaration there, which this GCC treats as an error. src/session.c had a
private fgetc() shim for exactly that; the session-list scan is newer and used
the POSIX call directly, and only the Windows build notices.

The shim moves to os_compat as os_getline(): getline(3) itself on Unix, the
fgetc() loop on Windows, one prototype in the header so a caller reads the same
everywhere. src/session.c drops its copy and calls it; the scan does too (its
`ssize_t` becomes `long long`, which Windows has).

make check is green on Linux, the Windows cross build now finishes and
packages (dist/cst-agent-0.9.7-windows-x86_64.zip plus the NSIS setup), and the
static Linux tarball was rebuilt with it.
This commit is contained in:
WHC
2026-10-11 21:54:32 +08:00
parent b7034baec4
commit 60047ca5ce
4 changed files with 49 additions and 36 deletions
+2 -34
View File
@@ -15,39 +15,7 @@
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
typedef long long cst_ssize_t;
static cst_ssize_t cst_getline(char **lineptr, size_t *n, FILE *stream) {
if (!lineptr || !n || !stream)
return -1;
if (!*lineptr || *n == 0) {
*n = 256;
*lineptr = (char *)malloc(*n);
if (!*lineptr)
return -1;
}
size_t len = 0;
int c = 0;
while ((c = fgetc(stream)) != EOF) {
if (len + 2 > *n) {
size_t nn = (*n) * 2;
char *nb = (char *)realloc(*lineptr, nn);
if (!nb)
return -1;
*lineptr = nb;
*n = nn;
}
(*lineptr)[len++] = (char)c;
if (c == '\n')
break;
}
if (len == 0 && c == EOF)
return -1;
(*lineptr)[len] = 0;
return (cst_ssize_t)len;
}
#define getline cst_getline
#endif
#include "os_compat.h"
struct cst_session {
char path[4096];
@@ -158,7 +126,7 @@ static void load_existing(cst_session_t *s) {
return;
char *line = NULL;
size_t cap = 0;
while (getline(&line, &cap, rp) != -1) {
while (os_getline(&line, &cap, rp) != -1) {
cJSON *o = cJSON_Parse(line);
if (!o || !cJSON_IsObject(o)) {
cJSON_Delete(o);