[hackers] [surf][PATCH] Removed fork()/exec() calls. Added GLib spawn process API.

From: <flvcst_AT_posteo.net>
Date: Mon, 13 May 2019 23:51:31 +0200

Hello. I noticed some zombie processes hanging around after running
surf. I
don't know if it is something wrong in my system (x86_64 Gentoo),
although
it is pretty much all stable and default flags. But while debugging it I
noticed that g_object_new() in newview() overrides our SIGCHLD handler.

I decided to rewrite spawn() with GLib spawn process API and remove
fork() and exec() calls. It worked, no more zombies. We are already
using g_object_new() so no dependencies added. I do believe the code
gets tidier also.

---
  surf.c | 28 ++++++----------------------
  1 file changed, 6 insertions(+), 22 deletions(-)
diff --git a/surf.c b/surf.c
index 2b54e3c..cde488e 100644
--- a/surf.c
+++ b/surf.c
_AT_@ -143,7 +143,6 @@ typedef struct {
  /* Surf */
  static void usage(void);
  static void setup(void);
-static void sigchld(int unused);
  static void sighup(int unused);
  static char *buildfile(const char *path);
  static char *buildpath(const char *path);
_AT_@ -316,8 +315,6 @@ setup(void)
     GdkDisplay *gdpy;
     int i, j;
-   /* clean up any zombies immediately */
-   sigchld(0);
     if (signal(SIGHUP, sighup) == SIG_ERR)
         die("Can't install SIGHUP handler");
_AT_@ -399,15 +396,6 @@ setup(void)
     }
  }
-void
-sigchld(int unused)
-{
-   if (signal(SIGCHLD, sigchld) == SIG_ERR)
-       die("Can't install SIGCHLD handler");
-   while (waitpid(-1, NULL, WNOHANG) > 0)
-       ;
-}
-
  void
  sighup(int unused)
  {
_AT_@ -1035,16 +1023,12 @@ newwindow(Client *c, const Arg *a, int noembed)
  void
  spawn(Client *c, const Arg *a)
  {
-   if (fork() == 0) {
-       if (dpy)
-           close(ConnectionNumber(dpy));
-       close(pipein[0]);
-       close(pipeout[1]);
-       setsid();
-       execvp(((char **)a->v)[0], (char **)a->v);
-       fprintf(stderr, "%s: execvp %s", argv0, ((char **)a->v)[0]);
-       perror(" failed");
-       exit(1);
+   const gchar sep = ' ';
+   GError *error;
+
+   if (!g_spawn_async(NULL, (gchar **)a->v, NULL, G_SPAWN_DEFAULT, 
NULL, NULL, NULL, &error)) {
+       fprintf(stderr, "g_spawn_command_line_async failed\n");
+       fprintf(stderr, "argv: %s\n", g_strjoinv(&sep, (gchar **)a->v));
     }
  }
-- 
2.21.0
Received on Mon May 13 2019 - 23:51:31 CEST

This archive was generated by hypermail 2.3.0 : Tue May 14 2019 - 00:00:37 CEST