214 {
215
216 if (g_query_active) {
217 return g_query_port;
218 }
219
220
222 if (!find_query_server_path(server_path, sizeof(server_path))) {
223 fprintf(stderr, "[query] Could not find ascii-query-server executable\n");
224 fprintf(stderr, "[query] Set ASCIICHAT_QUERY_SERVER environment variable or ensure "
225 "it's in .deps-cache/query-tool/\n");
226 return -1;
227 }
228
229#ifdef _WIN32
230
231 WSADATA wsa_data;
232 if (WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0) {
233 fprintf(stderr, "[query] WSAStartup failed\n");
234 return -1;
235 }
236
237 char cmdline[2048];
238 safe_snprintf(cmdline,
sizeof(cmdline),
"\"%s\" --attach %lu --port %d", server_path,
239 (unsigned long)GetCurrentProcessId(), preferred_port);
240
241 STARTUPINFOA si;
242 PROCESS_INFORMATION pi;
243 memset(&si, 0, sizeof(si));
244 si.cb = sizeof(si);
245 memset(&pi, 0, sizeof(pi));
246
247
248 if (!CreateProcessA(NULL,
249 cmdline,
250 NULL,
251 NULL,
252 FALSE,
253 CREATE_NEW_CONSOLE,
254 NULL,
255 NULL,
256 &si, &pi)) {
257 fprintf(stderr, "[query] Failed to start query server: error %lu\n", GetLastError());
258 return -1;
259 }
260
261 g_controller_handle = pi.hProcess;
262 g_controller_pid = pi.dwProcessId;
263 CloseHandle(pi.hThread);
264
265 fprintf(stderr, "[query] Started query server (PID %lu) on port %d\n", (unsigned long)g_controller_pid,
266 preferred_port);
267
268#else
269
270 pid_t self_pid = getpid();
271
272 char port_str[16];
273 char pid_str[16];
274 safe_snprintf(port_str,
sizeof(port_str),
"%d", preferred_port);
276
277 pid_t child = fork();
278 if (child < 0) {
279 fprintf(stderr, "[query] fork() failed: %s\n", strerror(errno));
280 return -1;
281 }
282
283 if (child == 0) {
284
285
286
287
288 execl(server_path, "ascii-query-server", "--attach", pid_str, "--port", port_str, (char *)NULL);
289
290
291 fprintf(stderr, "[query] exec(%s) failed: %s\n", server_path, strerror(errno));
292 exit(1);
293 }
294
295
296 g_controller_pid = child;
297 fprintf(stderr, "[query] Started query server (PID %d) on port %d\n", child, preferred_port);
298#endif
299
300
301 fprintf(stderr, "[query] Waiting for HTTP server to be ready...\n");
303 fprintf(stderr, "[query] Timeout waiting for query server to start\n");
305 return -1;
306 }
307
308 g_query_active = true;
309 g_query_port = preferred_port;
310
311 fprintf(stderr, "[query] Query server ready at http://localhost:%d\n", preferred_port);
312 return preferred_port;
313}
#define HEALTH_CHECK_TIMEOUT_NS
int safe_snprintf(char *buffer, size_t buffer_size, const char *format,...)
Safe formatted string printing to buffer.
#define PLATFORM_MAX_PATH_LENGTH