diff --git a/surf.c b/surf.c index 93a1629..ba53b94 100644 --- a/surf.c +++ b/surf.c @@ -217,6 +217,7 @@ static void togglefullscreen(Client *c, const Arg *a); static void togglecookiepolicy(Client *c, const Arg *a); static void toggleinspector(Client *c, const Arg *a); static void find(Client *c, const Arg *a); +static void externalpipe(Client *c, const Arg *a); /* Buttons */ static void clicknavigate(Client *c, const Arg *a, WebKitHitTestResult *h); @@ -241,6 +242,80 @@ char *argv0; /* configuration, allows nested code to access above variables */ #include "config.h" +static void +externalpipe_execute(char* buffer, Arg *arg) { + int to[2]; + void (*oldsigpipe)(int); + + if (pipe(to) == -1) + return; + + switch (fork()) { + case -1: + close(to[0]); + close(to[1]); + return; + case 0: + dup2(to[0], STDIN_FILENO); close(to[0]); close(to[1]); + execvp(((char **)arg->v)[0], (char **)arg->v); + fprintf(stderr, "st: execvp %s\n", ((char **)arg->v)[0]); + perror("failed"); + exit(0); + } + + close(to[0]); + oldsigpipe = signal(SIGPIPE, SIG_IGN); + write(to[1], buffer, strlen(buffer)); + close(to[1]); + signal(SIGPIPE, oldsigpipe); +} + +static void +externalpipe_resource_done(WebKitWebResource *r, GAsyncResult *s, Arg *arg) +{ + GError *gerr = NULL; + guchar *buffer = webkit_web_resource_get_data_finish(r, s, NULL, &gerr); + if (gerr == NULL) { + externalpipe_execute((char *) buffer, arg); + } else { + g_error_free(gerr); + } + g_free(buffer); +} + +static void +externalpipe_js_done(WebKitWebView *wv, GAsyncResult *s, Arg *arg) +{ + WebKitJavascriptResult *j = webkit_web_view_run_javascript_finish( + wv, s, NULL); + if (!j) { + return; + } + JSCValue *v = webkit_javascript_result_get_js_value(j); + if (jsc_value_is_string(v)) { + char *buffer = jsc_value_to_string(v); + externalpipe_execute(buffer, arg); + g_free(buffer); + } + webkit_javascript_result_unref(j); +} + +void +externalpipe(Client *c, const Arg *arg) +{ + if (curconfig[JavaScript].val.i) { + webkit_web_view_run_javascript( + c->view, "window.document.documentElement.outerHTML", + NULL, externalpipe_js_done, arg); + } else { + WebKitWebResource *resource = webkit_web_view_get_main_resource(c->view); + if (resource != NULL) { + webkit_web_resource_get_data( + resource, NULL, externalpipe_resource_done, arg); + } + } +} + void usage(void) {