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:
@@ -2,6 +2,7 @@
|
|||||||
#define CST_OS_COMPAT_H
|
#define CST_OS_COMPAT_H
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -12,6 +13,13 @@ extern "C" {
|
|||||||
#define OS_PATH_MAX 4096
|
#define OS_PATH_MAX 4096
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* --- text --- */
|
||||||
|
/* One line of a file into *lineptr, growing it as needed: POSIX getline(3),
|
||||||
|
* which a MinGW CRT does not have (the session file readers used it directly
|
||||||
|
* and only the Windows build noticed). Returns the number of bytes read -- 0
|
||||||
|
* for an empty line -- or -1 at the end of the file. */
|
||||||
|
long long os_getline(char **lineptr, size_t *n, FILE *stream);
|
||||||
|
|
||||||
/* --- path --- */
|
/* --- path --- */
|
||||||
int os_path_is_abs(const char *p);
|
int os_path_is_abs(const char *p);
|
||||||
/* Join with native separator; out always uses '/' on Unix and '\\' on Win for
|
/* Join with native separator; out always uses '/' on Unix and '\\' on Win for
|
||||||
|
|||||||
@@ -1217,3 +1217,40 @@ int unsetenv(const char *name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
/* getline(3) itself where the libc has it; the same thing spelled out with
|
||||||
|
* fgetc() where it does not (Windows), so the callers read the same on every
|
||||||
|
* platform. */
|
||||||
|
long long os_getline(char **lineptr, size_t *n, FILE *stream) {
|
||||||
|
#ifndef _WIN32
|
||||||
|
return (long long)getline(lineptr, n, stream);
|
||||||
|
#else
|
||||||
|
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) {
|
||||||
|
const 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 (long long)len;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|||||||
+2
-34
@@ -15,39 +15,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#include "os_compat.h"
|
||||||
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
|
|
||||||
|
|
||||||
struct cst_session {
|
struct cst_session {
|
||||||
char path[4096];
|
char path[4096];
|
||||||
@@ -158,7 +126,7 @@ static void load_existing(cst_session_t *s) {
|
|||||||
return;
|
return;
|
||||||
char *line = NULL;
|
char *line = NULL;
|
||||||
size_t cap = 0;
|
size_t cap = 0;
|
||||||
while (getline(&line, &cap, rp) != -1) {
|
while (os_getline(&line, &cap, rp) != -1) {
|
||||||
cJSON *o = cJSON_Parse(line);
|
cJSON *o = cJSON_Parse(line);
|
||||||
if (!o || !cJSON_IsObject(o)) {
|
if (!o || !cJSON_IsObject(o)) {
|
||||||
cJSON_Delete(o);
|
cJSON_Delete(o);
|
||||||
|
|||||||
@@ -121,8 +121,8 @@ int cst_tool_session_search(const cst_tool_ctx_t *ctx, const ctl_tool_call_t *c,
|
|||||||
char *line = NULL;
|
char *line = NULL;
|
||||||
size_t cap = 0;
|
size_t cap = 0;
|
||||||
cst_buf_t one = {0};
|
cst_buf_t one = {0};
|
||||||
ssize_t got;
|
long long got;
|
||||||
while ((got = getline(&line, &cap, fp)) > 0) {
|
while ((got = os_getline(&line, &cap, fp)) > 0) {
|
||||||
lineno++;
|
lineno++;
|
||||||
scanned_bytes += got;
|
scanned_bytes += got;
|
||||||
/* A tool output line can be megabytes (a whole file read back): such a
|
/* A tool output line can be megabytes (a whole file read back): such a
|
||||||
|
|||||||
Reference in New Issue
Block a user