1#ifndef WEBKIT_LOG_CAPTURE_H
2#define WEBKIT_LOG_CAPTURE_H
3
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7#include <unistd.h>
8#include <glib.h>
9
10static int webkit_log_pipe[2];
11static FILE* webkit_original_stdout;
12static FILE* webkit_original_stderr;
13static gboolean webkit_capture_enabled = FALSE;
14
15// Initialize log capture pipes
16static inline void webkit_init_log_capture() {
17 if (webkit_capture_enabled) return;
18
19 // Create pipe for capturing C output
20 if (pipe(webkit_log_pipe) == 0) {
21 // Duplicate stdout/stderr for restoration later
22 webkit_original_stdout = fdopen(dup(1), "w");
23 webkit_original_stderr = fdopen(dup(2), "w");
24 webkit_capture_enabled = TRUE;
25
26 g_debug("WebKit log capture initialized");
27 } else {
28 g_warning("Failed to initialize WebKit log capture");
29 }
30}
31
32// Start capturing WebKit output
33static inline void webkit_start_log_capture() {
34 if (!webkit_capture_enabled) return;
35
36 // Redirect stdout/stderr to pipe (for C printf statements)
37 dup2(webkit_log_pipe[1], 1);
38 dup2(webkit_log_pipe[1], 2);
39}
40
41// Stop capturing and restore original output
42static inline void webkit_stop_log_capture() {
43 if (!webkit_capture_enabled) return;
44
45 // Restore original stdout/stderr
46 if (webkit_original_stdout) {
47 dup2(fileno(webkit_original_stdout), 1);
48 fclose(webkit_original_stdout);
49 }
50 if (webkit_original_stderr) {
51 dup2(fileno(webkit_original_stderr), 2);
52 fclose(webkit_original_stderr);
53 }
54
55 close(webkit_log_pipe[0]);
56 close(webkit_log_pipe[1]);
57 webkit_capture_enabled = FALSE;
58}
59
60// Read captured output (non-blocking)
61static inline int webkit_read_captured_log(char* buffer, int buffer_size) {
62 if (!webkit_capture_enabled) return 0;
63
64 fd_set read_fds;
65 struct timeval timeout;
66
67 FD_ZERO(&read_fds);
68 FD_SET(webkit_log_pipe[0], &read_fds);
69
70 // Non-blocking check
71 timeout.tv_sec = 0;
72 timeout.tv_usec = 0;
73
74 int result = select(webkit_log_pipe[0] + 1, &read_fds, NULL, NULL, &timeout);
75 if (result > 0 && FD_ISSET(webkit_log_pipe[0], &read_fds)) {
76 int n = read(webkit_log_pipe[0], buffer, buffer_size - 1);
77 if (n > 0) {
78 buffer[n] = '\0';
79 return n;
80 }
81 }
82 return 0;
83}
84
85// GLib log handler to capture GLib/GTK/WebKit messages
86static inline void webkit_glib_log_handler(const gchar *log_domain,
87 GLogLevelFlags log_level,
88 const gchar *message,
89 gpointer user_data) {
90 // Forward to Go callback
91 extern void goWebKitLogHandler(char* domain, int level, char* message);
92 goWebKitLogHandler((char*)log_domain, (int)log_level, (char*)message);
93}
94
95// Set up GLib log handlers for various domains
96static inline void webkit_setup_glib_log_handlers() {
97 // Set up log handlers for WebKit and GTK domains
98 g_log_set_handler("WebKit", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
99 webkit_glib_log_handler, NULL);
100 g_log_set_handler("Gtk", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
101 webkit_glib_log_handler, NULL);
102 g_log_set_handler("GLib", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
103 webkit_glib_log_handler, NULL);
104 g_log_set_handler(NULL, G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
105 webkit_glib_log_handler, NULL);
106}
107
108#endif // WEBKIT_LOG_CAPTURE_H