Fix error handling in spawn()
[surf.git] / surf.c
diff --git a/surf.c b/surf.c
index edfc3c3..32c1920 100644 (file)
--- a/surf.c
+++ b/surf.c
@@ -56,8 +56,8 @@ enum {
 };
 
 typedef union {
-       gboolean b;
-       gint i;
+       int b;
+       int i;
        const void *v;
 } Arg;
 
@@ -69,8 +69,7 @@ typedef struct Client {
        WebKitHitTestResult *mousepos;
        GTlsCertificateFlags tlsflags;
        Window xid;
-       gint progress;
-       gboolean fullscreen;
+       int progress, fullscreen;
        const char *title, *targeturi;
        const char *needle;
        struct Client *next;
@@ -108,7 +107,7 @@ static char *buildpath(const char *path);
 static Client *newclient(Client *c);
 static void addaccelgroup(Client *c);
 static void loaduri(Client *c, const Arg *a);
-static char *geturi(Client *c);
+static const char *geturi(Client *c);
 static void setatom(Client *c, int a, const char *v);
 static const char *getatom(Client *c, int a);
 static void updatetitle(Client *c);
@@ -116,13 +115,13 @@ static void gettogglestats(Client *c);
 static void getpagestats(Client *c);
 static WebKitCookieAcceptPolicy cookiepolicy_get(void);
 static char cookiepolicy_set(const WebKitCookieAcceptPolicy p);
-static const gchar *getstyle(const char *uri);
+static const char *getstyle(const char *uri);
 static void setstyle(Client *c, const char *stylefile);
 static void runscript(Client *c);
 static void evalscript(Client *c, const char *jsstr, ...);
 static void updatewinid(Client *c);
-static void handleplumb(Client *c, const gchar *uri);
-static void newwindow(Client *c, const Arg *a, gboolean noembed);
+static void handleplumb(Client *c, const char *uri);
+static void newwindow(Client *c, const Arg *a, int noembed);
 static void spawn(Client *c, const Arg *a);
 static void destroyclient(Client *c);
 static void cleanup(void);
@@ -131,7 +130,7 @@ static void cleanup(void);
 static WebKitWebView *newview(Client *c, WebKitWebView *rv);
 static GtkWidget *createview(WebKitWebView *v, WebKitNavigationAction *a,
                              Client *c);
-static gboolean buttonreleased(GtkWidget *w, GdkEventKey *e, Client *c);
+static gboolean buttonreleased(GtkWidget *w, GdkEvent *e, Client *c);
 static gboolean keypress(GtkAccelGroup *group, GObject *obj, guint key,
                          GdkModifierType mods, Client *c);
 static GdkFilterReturn processx(GdkXEvent *xevent, GdkEvent *event,
@@ -185,7 +184,7 @@ static char togglestats[10];
 static char pagestats[2];
 static Atom atoms[AtomLast];
 static Window embed;
-static gboolean showxid = FALSE;
+static int showxid;
 static int cookiepolicy;
 static Display *dpy;
 static Client *clients;
@@ -212,7 +211,7 @@ die(const char *errstr, ...)
        va_start(ap, errstr);
        vfprintf(stderr, errstr, ap);
        va_end(ap);
-       exit(EXIT_FAILURE);
+       exit(1);
 }
 
 void
@@ -260,7 +259,8 @@ sigchld(int unused)
 {
        if (signal(SIGCHLD, sigchld) == SIG_ERR)
                die("Can't install SIGCHLD handler");
-       while (0 < waitpid(-1, NULL, WNOHANG));
+       while (waitpid(-1, NULL, WNOHANG) > 0)
+               ;
 }
 
 char *
@@ -333,14 +333,12 @@ newclient(Client *rc)
        if (!(c = calloc(1, sizeof(Client))))
                die("Cannot malloc!\n");
 
-       c->title = NULL;
-       c->progress = 100;
-
        c->next = clients;
        clients = c;
 
-       c->view = newview(c, rc ? rc->view : NULL);
+       c->progress = 100;
        c->tlsflags = G_TLS_CERTIFICATE_VALIDATE_ALL + 1;
+       c->view = newview(c, rc ? rc->view : NULL);
 
        return c;
 }
@@ -392,12 +390,12 @@ loaduri(Client *c, const Arg *a)
        g_free(url);
 }
 
-char *
+const char *
 geturi(Client *c)
 {
-       char *uri;
+       const char *uri;
 
-       if (!(uri = (char *)webkit_web_view_get_uri(c->view)))
+       if (!(uri = webkit_web_view_get_uri(c->view)))
                uri = "about:blank";
        return uri;
 }
@@ -407,8 +405,8 @@ setatom(Client *c, int a, const char *v)
 {
        XSync(dpy, False);
        XChangeProperty(dpy, c->xid,
-                       atoms[a], XA_STRING, 8, PropModeReplace,
-                       (unsigned char *)v, strlen(v) + 1);
+                       atoms[a], XA_STRING, 8, PropModeReplace,
+                       (unsigned char *)v, strlen(v) + 1);
 }
 
 const char *
@@ -435,26 +433,24 @@ void
 updatetitle(Client *c)
 {
        char *title;
+       const char *name = c->targeturi ? c->targeturi :
+                          c->title ? c->title : "";
 
        if (showindicators) {
                gettogglestats(c);
                getpagestats(c);
 
-               if (c->progress != 100) {
+               if (c->progress != 100)
                        title = g_strdup_printf("[%i%%] %s:%s | %s",
-                               c->progress, togglestats, pagestats,
-                               c->targeturi ? c->targeturi : c->title);
-               } else {
+                               c->progress, togglestats, pagestats, name);
+               else
                        title = g_strdup_printf("%s:%s | %s",
-                               togglestats, pagestats,
-                               c->targeturi ? c->targeturi : c->title);
-               }
+                               togglestats, pagestats, name);
 
                gtk_window_set_title(GTK_WINDOW(c->win), title);
                g_free(title);
        } else {
-               gtk_window_set_title(GTK_WINDOW(c->win), c->title ?
-                                    c->title : "");
+               gtk_window_set_title(GTK_WINDOW(c->win), name);
        }
 }
 
@@ -489,12 +485,11 @@ cookiepolicy_get(void)
                return WEBKIT_COOKIE_POLICY_ACCEPT_NEVER;
        case '@':
                return WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY;
+       default: /* fallthrough */
        case 'A':
-       default:
-               break;
+               return WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS;
        }
 
-       return WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS;
 }
 
 char
@@ -505,15 +500,14 @@ cookiepolicy_set(const WebKitCookieAcceptPolicy p)
                return 'a';
        case WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY:
                return '@';
+       default: /* fallthrough */
        case WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS:
-       default:
-               break;
+               return 'A';
        }
 
-       return 'A';
 }
 
-const gchar *
+const char *
 getstyle(const char *uri)
 {
        int i;
@@ -582,7 +576,7 @@ updatewinid(Client *c)
 }
 
 void
-handleplumb(Client *c, const gchar *uri)
+handleplumb(Client *c, const char *uri)
 {
        Arg a = (Arg)PLUMB(uri);
        spawn(c, &a);
@@ -649,9 +643,9 @@ spawn(Client *c, const Arg *a)
                        close(ConnectionNumber(dpy));
                setsid();
                execvp(((char **)a->v)[0], (char **)a->v);
-               fprintf(stderr, "surf: execvp %s", ((char **)a->v)[0]);
+               fprintf(stderr, "%s: execvp %s", argv0, ((char **)a->v)[0]);
                perror(" failed");
-               exit(0);
+               exit(1);
        }
 }
 
@@ -814,18 +808,17 @@ createview(WebKitWebView *v, WebKitNavigationAction *a, Client *c)
 }
 
 gboolean
-buttonreleased(GtkWidget *w, GdkEventKey *e, Client *c)
+buttonreleased(GtkWidget *w, GdkEvent *e, Client *c)
 {
        WebKitHitTestResultContext element;
-       GdkEventButton *eb = (GdkEventButton*)e;
        int i;
 
        element = webkit_hit_test_result_get_context(c->mousepos);
 
        for (i = 0; i < LENGTH(buttons); ++i) {
                if (element & buttons[i].target &&
-                   eb->button == buttons[i].button &&
-                   CLEANMASK(eb->state) == CLEANMASK(buttons[i].mask) &&
+                   e->button.button == buttons[i].button &&
+                   CLEANMASK(e->button.state) == CLEANMASK(buttons[i].mask) &&
                    buttons[i].func) {
                        buttons[i].func(c, &buttons[i].arg, c->mousepos);
                        return buttons[i].stopevent;
@@ -907,7 +900,6 @@ winevent(GtkWidget *w, GdkEvent *e, Client *c)
 void
 showview(WebKitWebView *v, Client *c)
 {
-       GdkGeometry hints = { 1, 1 };
        GdkRGBA bgcolor = { 0 };
        GdkWindow *gwin;
 
@@ -918,8 +910,6 @@ showview(WebKitWebView *v, Client *c)
        c->win = createwindow(c);
 
        gtk_container_add(GTK_CONTAINER(c->win), GTK_WIDGET(c->view));
-       gtk_window_set_geometry_hints(GTK_WINDOW(c->win), NULL, &hints,
-                                     GDK_HINT_MIN_SIZE);
        gtk_widget_show_all(c->win);
        gtk_widget_grab_focus(GTK_WIDGET(c->view));
 
@@ -953,6 +943,7 @@ showview(WebKitWebView *v, Client *c)
 GtkWidget *
 createwindow(Client *c)
 {
+       char *wmstr;
        GtkWidget *w;
 
        if (embed) {
@@ -960,19 +951,14 @@ createwindow(Client *c)
        } else {
                w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 
-               /* TA:  20091214:  Despite what the GNOME docs say, the ICCCM
-                * is always correct, so we should still call this function.
-                * But when doing so, we *must* differentiate between a
-                * WM_CLASS and a resource on the window.  By convention, the
-                * window class (WM_CLASS) is capped, while the resource is in
-                * lowercase.   Both these values come as a pair.
-                */
-               gtk_window_set_wmclass(GTK_WINDOW(w), "surf", "Surf");
+               wmstr = g_path_get_basename(argv0);
+               gtk_window_set_wmclass(GTK_WINDOW(w), wmstr, "Surf");
+               g_free(wmstr);
 
-               /* TA:  20091214:  And set the role here as well -- so that
-                * sessions can pick this up.
-                */
-               gtk_window_set_role(GTK_WINDOW(w), "Surf");
+               wmstr = g_strdup_printf("%s[%lu]", "Surf",
+                       webkit_web_view_get_page_id(c->view));
+               gtk_window_set_role(GTK_WINDOW(w), wmstr);
+               g_free(wmstr);
 
                gtk_window_set_default_size(GTK_WINDOW(w), 800, 600);
        }
@@ -1228,15 +1214,14 @@ void
 pasteuri(GtkClipboard *clipboard, const char *text, gpointer d)
 {
        Arg a = {.v = text };
-       if (!text)
+       if (text)
                loaduri((Client *) d, &a);
 }
 
 void
 reload(Client *c, const Arg *a)
 {
-       gboolean nocache = *(gboolean *)a;
-       if (nocache)
+       if (a->b)
                webkit_web_view_reload_bypass_cache(c->view);
        else
                webkit_web_view_reload(c->view);
@@ -1542,7 +1527,7 @@ main(int argc, char *argv[])
                die("surf-"VERSION", ©2009-2015 surf engineers, "
                    "see LICENSE for details\n");
        case 'x':
-               showxid = TRUE;
+               showxid = 1;
                break;
        case 'z':
                zoomlevel = strtof(EARGF(usage()), NULL);
@@ -1552,18 +1537,18 @@ main(int argc, char *argv[])
        } ARGEND;
        if (argc > 0)
                arg.v = argv[0];
+       else
+               arg.v = "about:blank";
 
        setup();
        c = newclient(NULL);
        showview(NULL, c);
 
-       if (arg.v)
-               loaduri(clients, &arg);
-       else
-               updatetitle(c);
+       loaduri(c, &arg);
+       updatetitle(c);
 
        gtk_main();
        cleanup();
 
-       return EXIT_SUCCESS;
+       return 0;
 }