Allow to control vimb by fifo file (#144).
authorDaniel Carl <danielcarl@gmx.de>
Wed, 12 Nov 2014 23:00:38 +0000 (00:00 +0100)
committerDaniel Carl <danielcarl@gmx.de>
Sun, 16 Nov 2014 23:16:14 +0000 (00:16 +0100)
config.mk
doc/vimb.1
src/config.def.h
src/io.c [new file with mode: 0644]
src/io.h [new file with mode: 0644]
src/main.c
src/main.h

index a1f6fa8..9930aed 100644 (file)
--- a/config.mk
+++ b/config.mk
@@ -31,6 +31,7 @@ PROJECT_UCFIRST = $(shell echo '${PROJECT}' | awk '{for(i=1;i<=NF;i++){$$i=toupp
 CPPFLAGS  = -DVERSION=\"${VERSION}\"
 CPPFLAGS += -DPROJECT=\"${PROJECT}\" -DPROJECT_UCFIRST=\"${PROJECT_UCFIRST}\"
 CPPFLAGS += -D_XOPEN_SOURCE=500
+CPPFLAGS += -D_POSIX_SOURCE
 ifeq ($(USEGTK3), 1)
 CPPFLAGS += -DHAS_GTK3
 CPPFLAGS += -DGSEAL_ENABLE
index 447f29f..9158905 100644 (file)
@@ -15,10 +15,7 @@ vimb - Vim Browser - A modal web browser based on webkit, inspired by vim the
 great editor.
 .SH SYNOPSIS
 .SY vimb
-.OP \-hkv
-.OP \-C cmd
-.OP \-c config
-.OP \-e winid
+.OP OPTIONS
 .RI [ URI "|" file "|" - ]
 .YS
 .SH DESCRIPTION
@@ -55,6 +52,10 @@ Show help options.
 Run vimb in kiosk mode with nearly no keybindings, not inputbox and no context
 menu.
 .TP
+.B \-n, \-\-fifo-name
+If given vimb will create a control fifo in vimb's config directory
+named 'vimb-fifo-{name}'.
+.TP
 .B "\-v, \-\-version"
 Print build and version information.
 .SH MODES
@@ -1403,6 +1404,10 @@ Contains the pid of the running vimb instance.
 Holds the X-Window id of the vim window or of the embedding window if vimb is
 started with -e option.
 .TP
+.B VIMB_FILE
+Holds the full path to the control fifo, if vimb is compiled with FIFO feature
+and started with `--fifo-name' option.
+.TP
 .B http_proxy
 If this variable is set to an none empty value, and the configuration option
 `proxy' is enabled, this will be used as http proxy. If the proxy URL has no
index e99b68e..ce0e5cb 100644 (file)
@@ -52,6 +52,8 @@
 #define FEATURE_AUTOCMD
 /* enable the :auto-response-header feature */
 #define FEATURE_ARH
+/* allow to use fifo to remote control vimb */
+#define FEATURE_FIFO
 
 /* time in seconds after that message will be removed from inputbox if the
  * message where only temporary */
diff --git a/src/io.c b/src/io.c
new file mode 100644 (file)
index 0000000..c1095aa
--- /dev/null
+++ b/src/io.c
@@ -0,0 +1,110 @@
+/**
+ * vimb - a webkit based vim like browser.
+ *
+ * Copyright (C) 2012-2014 Daniel Carl
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+#include "config.h"
+#ifdef FEATURE_FIFO
+#include "io.h"
+#include "main.h"
+#include "map.h"
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+extern VbCore vb;
+
+static gboolean fifo_watch(GIOChannel *gio, GIOCondition condition);
+
+
+gboolean io_init_fifo(const char *name)
+{
+    char *fname, *path;
+
+    /* create fifo in directory as vimb-fifo-$PID */
+    fname = g_strdup_printf(PROJECT "-fifo-%s", name);
+    path  = g_build_filename(g_get_user_config_dir(), PROJECT, fname, NULL);
+    g_free(fname);
+
+    /* if the file already exists - remove this first */
+    if (g_file_test(path, G_FILE_TEST_IS_REGULAR)) {
+        unlink(path);
+    }
+
+    if (mkfifo(path, 0666) == 0) {
+        GError *error    = NULL;
+        /* use r+ to avoid blocking caused by wait of a writer */
+        GIOChannel *chan = g_io_channel_new_file(path, "r+", &error);
+        if (chan) {
+            if (g_io_add_watch(chan, G_IO_IN|G_IO_HUP, (GIOFunc)fifo_watch, NULL)) {
+                /* don't free path - because we want to keep the value in
+                 * vb.state.fifo_path still accessible */
+                vb.state.fifo_path = path;
+                g_setenv("VIMB_FIFO", path, TRUE);
+
+                return true;
+            }
+        } else {
+            g_warning ("Can't open fifo: %s", error->message);
+            g_error_free(error);
+        }
+    } else {
+        g_warning("Can't create fifo %s", path);
+    }
+    g_free(path);
+
+    return false;
+}
+
+void io_cleanup(void)
+{
+    if (vb.state.fifo_path) {
+        if (unlink(vb.state.fifo_path) == -1) {
+            g_warning("Can't remove fifo %s", vb.state.fifo_path);
+        }
+        g_free(vb.state.fifo_path);
+        vb.state.fifo_path = NULL;
+    }
+}
+
+static gboolean fifo_watch(GIOChannel *gio, GIOCondition condition)
+{
+    char *line;
+    GIOStatus ret;
+    GError *err = NULL;
+
+    if (condition & G_IO_HUP) {
+        g_error("fifo: read end of pipe died");
+    }
+
+    if (!gio) {
+        g_error("fifo: GIOChannel broken");
+    }
+
+    ret = g_io_channel_read_line(gio, &line, NULL, NULL, &err);
+    if (ret == G_IO_STATUS_ERROR) {
+        g_error("fifo: error reading from fifo: %s", err->message);
+        g_error_free(err);
+    }
+
+    map_handle_string(line, true);
+    g_free(line);
+
+    return true;
+}
+
+#endif
diff --git a/src/io.h b/src/io.h
new file mode 100644 (file)
index 0000000..fdddbf5
--- /dev/null
+++ b/src/io.h
@@ -0,0 +1,32 @@
+/**
+ * vimb - a webkit based vim like browser.
+ *
+ * Copyright (C) 2012-2014 Daniel Carl
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+#include "config.h"
+#ifdef FEATURE_FIFO
+
+#ifndef _IO_H
+#define _IO_H
+
+#include <glib.h>
+
+gboolean io_init_fifo(const char *dir);
+void io_cleanup(void);
+
+#endif /* end of include guard: _IO_H */
+#endif
index 342c7d5..301fcf1 100644 (file)
@@ -44,6 +44,7 @@
 #include "js.h"
 #include "autocmd.h"
 #include "arh.h"
+#include "io.h"
 
 /* variables */
 static char **args;
@@ -434,6 +435,9 @@ void vb_quit(gboolean force)
 #ifdef FEATURE_ARH
     arh_free(vb.config.autoresponseheader);
 #endif
+#ifdef FEATURE_FIFO
+    io_cleanup();
+#endif
 
     g_slist_free_full(vb.config.cmdargs, g_free);
 
@@ -1527,6 +1531,9 @@ static gboolean autocmdOptionArgFunc(const gchar *option_name, const gchar *valu
 int main(int argc, char *argv[])
 {
     static char *winid = NULL;
+#ifdef FEATURE_FIFO
+    static char *fifo_name = NULL;
+#endif
     static gboolean ver = false;
     static GError *err;
     char *pid;
@@ -1536,6 +1543,9 @@ int main(int argc, char *argv[])
         {"config", 'c', 0, G_OPTION_ARG_STRING, &vb.config.file, "Custom configuration file", NULL},
         {"embed", 'e', 0, G_OPTION_ARG_STRING, &winid, "Reparents to window specified by xid", NULL},
         {"kiosk", 'k', 0, G_OPTION_ARG_NONE, &vb.config.kioskmode, "Run in kiosk mode", NULL},
+#ifdef FEATURE_FIFO
+        {"fifo-name", 'n', 0, G_OPTION_ARG_STRING, &fifo_name, "Name used to create control fifo", NULL},
+#endif
         {"version", 'v', 0, G_OPTION_ARG_NONE, &ver, "Print version", NULL},
         {NULL}
     };
@@ -1559,7 +1569,7 @@ int main(int argc, char *argv[])
         vb.embed = strtol(winid, NULL, 0);
     }
 
-    pid = g_strdup_printf("%d", getpid());
+    pid = g_strdup_printf("%d", (int)getpid());
     g_setenv("VIMB_PID", pid, true);
     g_free(pid);
 
@@ -1581,6 +1591,13 @@ int main(int argc, char *argv[])
         vb_load_uri(&(Arg){VB_TARGET_CURRENT, argv[argc - 1]});
     }
 
+#ifdef FEATURE_FIFO
+    /* setup the control fifo - quit vimb if this failed */
+    if (fifo_name && *fifo_name && !io_init_fifo(fifo_name)) {
+        return EXIT_FAILURE;
+    }
+#endif
+
     /* Run the main GTK+ event loop */
     gtk_main();
 
index 0144a54..2aa6e95 100644 (file)
@@ -304,6 +304,7 @@ typedef struct {
 #ifdef FEATURE_SEARCH_HIGHLIGHT
     int             search_matches;         /* number of matches search results */
 #endif
+    char            *fifo_path;             /* holds the path to the control fifo */
 } State;
 
 typedef struct {