[PATCH] Logging to socket feature

Juuso Alasuutari juuso.alasuutari at gmail.com
Mon Nov 5 06:53:32 PST 2007


Hi.

It's been almost a year since I got this idea and suggested it on this list 
[0]. As someone who does a lot of building from source, I've long dreamed of 
a pkg-config feature to help identify missing dependencies. I finally found 
time and energy to implement it myself and wrote a patch which applies both 
against 0.22 and current development tree.

Here's from a README I wrote [1]:

"Making pkg-config log to a socket allows other programs to retrieve useful 
information about package dependencies during package configuration. When 
built with the socket logging feature, pkg-config will send data to a Unix 
socket defined in the environment variable PKG_CONFIG_LOG_SOCKET. No changes 
are required to the package configuring scripts themselves, making the 
logging feature useful in any situation involving pkg-config."

I've also written an example program demonstrating this feature which you can 
find in a tarball of the patch [1].

[0] http://lists.freedesktop.org/archives/pkg-config/2006-December/000166.html
[1] http://www.cs.uta.fi/~a445063/pkg-config-logsocket.tar.bz2

Sincerelly,
Juuso Alasuutari



diff -Naur pkg-config.old/configure.in pkg-config/configure.in
--- pkg-config.old/configure.in	2007-11-05 13:44:27.000000000 +0200
+++ pkg-config/configure.in	2007-11-05 13:51:31.000000000 +0200
@@ -112,7 +112,18 @@
       fi
     fi
   ])
-fi # !use_installed_glib
+
+  AC_ARG_ENABLE([log-socket],
+    [  --enable-log-socket     Enable logging to a Unix socket],
+    [enable_log_socket=$enableval], [])
+
+  AM_CONDITIONAL(LOG_SOCKET, test x$enable_log_socket = xyes)
+
+  if test x$enable_log_socket = xyes; then
+    AC_DEFINE(LOG_SOCKET, 1, [Logging to a Unix socket])
+  fi
+
+fi # !native_win32
 
 AM_CONDITIONAL(USE_INSTALLED_GLIB, test x$use_installed_glib = xyes)
 
@@ -123,7 +134,7 @@
 
 else
   AC_CONFIG_SUBDIRS(glib-1.2.8)
-fi # !native_win32
+fi # !use_installed_glib
 
 AC_FUNC_ALLOCA
 
diff -Naur pkg-config.old/logsocket.c pkg-config/logsocket.c
--- pkg-config.old/logsocket.c	1970-01-01 02:00:00.000000000 +0200
+++ pkg-config/logsocket.c	2007-11-05 13:51:39.000000000 +0200
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2007 Juuso Alasuutari
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "logsocket.h"
+
+char *log_socket = NULL;
+static int sock;
+static struct sockaddr_un saddr;
+
+void
+connect_to_log_socket (void)
+{
+  int r;
+
+  sock = socket (PF_UNIX, SOCK_DGRAM, 0);
+  if (sock == -1)
+    {
+      debug_spew ("Failed to create socket '%s'\n", strerror (errno));
+      goto fail;
+    }
+
+  saddr.sun_family = PF_UNIX;
+  r = snprintf (saddr.sun_path, sizeof (saddr.sun_path), log_socket);
+  if (r < 0 || r >= sizeof (saddr.sun_path))
+    {
+      debug_spew ("Error in socket path '%s'\n", log_socket);
+      goto close_and_fail;
+    }
+
+  if (connect (sock, (const struct sockaddr *) &saddr,
+      (socklen_t) sizeof (saddr)) == -1)
+    {
+      debug_spew ("Failed to connect to socket '%s'\n", strerror (errno));
+      goto close_and_fail;
+    }
+
+  debug_spew ("Connected to log socket '%s'\n", log_socket);
+
+  return;
+
+  close_and_fail:
+  close (sock);
+
+  fail:
+  log_socket = NULL;
+
+  return;
+}
+
+void
+_send_to_log_socket (const char *format, ...)
+{
+  va_list args;
+  gchar *str;
+
+  g_return_if_fail (format != NULL);
+
+  va_start (args, format);
+  str = g_strdup_vprintf (format, args);
+  va_end (args);
+
+  if (send (sock, str, strlen (str), 0) == -1)
+    {
+      debug_spew ("Failed to send to log socket\n");
+    }
+
+  g_free (str);
+}
diff -Naur pkg-config.old/logsocket.h pkg-config/logsocket.h
--- pkg-config.old/logsocket.h	1970-01-01 02:00:00.000000000 +0200
+++ pkg-config/logsocket.h	2007-11-05 13:51:39.000000000 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2007 Juuso Alasuutari
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef PKG_CONFIG_LOGSOCKET_H
+#define PKG_CONFIG_LOGSOCKET_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/un.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#ifdef USE_INSTALLED_GLIB
+#include <glib.h>
+#else
+#include "partial-glib.h"
+#endif
+
+#define send_to_log_socket(x, y...) \
+if (log_socket) _send_to_log_socket (x, ## y)
+
+extern char *log_socket;
+
+void
+connect_to_log_socket (void);
+
+void
+_send_to_log_socket (const char *format, ...);
+
+#endif
diff -Naur pkg-config.old/main.c pkg-config/main.c
--- pkg-config.old/main.c	2007-11-05 13:44:27.000000000 +0200
+++ pkg-config/main.c	2007-11-05 13:51:46.000000000 +0200
@@ -24,6 +24,10 @@
 #include "pkg.h"
 #include "parse.h"
 
+#ifdef LOG_SOCKET
+#include "logsocket.h"
+#endif
+
 #include "popt.h"
 #include <stdlib.h>
 #include <string.h>
@@ -375,6 +379,13 @@
       return 1;
     }
 
+#ifdef LOG_SOCKET
+  log_socket = getenv ("PKG_CONFIG_LOG_SOCKET");
+  if (log_socket && *log_socket != '\0')
+      connect_to_log_socket ();
+  else
+      debug_spew ("PKG_CONFIG_LOG_SOCKET is unset or empty\n");
+#endif
 
   /* Error printing is determined as follows:
    *     - for --cflags, --libs, etc. it's on by default
@@ -429,9 +440,21 @@
   if (required_pkgconfig_version)
     {
       if (compare_versions (VERSION, required_pkgconfig_version) >= 0)
-        return 0;
+        {
+#ifdef LOG_SOCKET
+          send_to_log_socket ("pkg-config >= %s",
+                              required_pkgconfig_version);
+#endif
+          return 0;
+        }
       else
-        return 1;
+        {
+#ifdef LOG_SOCKET
+          send_to_log_socket ("! pkg-config >= %s",
+                              required_pkgconfig_version);
+#endif
+          return 1;
+        }
     }
 
   package_init ();
@@ -481,8 +504,18 @@
           {
             failed = TRUE;
             verbose_error ("No package '%s' found\n", ver->name);
+#ifdef LOG_SOCKET
+            send_to_log_socket ("! %s", ver->name);
+#endif
             goto nextiter;
           }
+#ifdef LOG_SOCKET
+        else
+          {
+            req->req = ver;
+            send_to_log_socket ("%s", ver->name);
+          }
+#endif
 
         if (!version_test (ver->comparison, req->version, ver->version))
           {
@@ -498,8 +531,23 @@
 	      verbose_error ("You may find new versions of %s at %s\n",
 			     req->name, req->url);
 
+#ifdef LOG_SOCKET
+            send_to_log_socket ("! %s %s %s",
+                                ver->name,
+                                comparison_to_str (ver->comparison),
+                                ver->version);
+#endif
             goto nextiter;
           }
+#ifdef LOG_SOCKET
+        else if (ver->version)
+          {
+            send_to_log_socket ("%s %s %s",
+                                ver->name,
+                                comparison_to_str (ver->comparison),
+                                ver->version);
+          }
+#endif
 
         packages = g_slist_prepend (packages, req);
 
@@ -537,7 +585,16 @@
           Package *pkg = tmp->data;
 
           if (pkg_uninstalled (pkg))
-            return 0;
+            {
+#ifdef LOG_SOCKET
+              send_to_log_socket ("%s uninstalled", pkg->req->name);
+#endif
+              return 0;
+            }
+#ifdef LOG_SOCKET
+          else
+            send_to_log_socket ("! %s uninstalled", pkg->req->name);
+#endif
 
           tmp = g_slist_next (tmp);
         }
@@ -564,27 +621,69 @@
       Package *pkg = packages->data;
 
       if (compare_versions (pkg->version, required_exact_version) == 0)
-        return 0;
+        {
+#ifdef LOG_SOCKET
+          send_to_log_socket ("%s = %s",
+                              pkg->req->name,
+                              required_exact_version);
+#endif
+          return 0;
+        }
       else
-        return 1;
+        {
+#ifdef LOG_SOCKET
+          send_to_log_socket ("! %s = %s",
+                              pkg->req->name,
+                              required_exact_version);
+#endif
+          return 1;
+        }
     }
   else if (required_atleast_version)
     {
       Package *pkg = packages->data;
 
       if (compare_versions (pkg->version, required_atleast_version) >= 0)
-        return 0;
+        {
+#ifdef LOG_SOCKET
+          send_to_log_socket ("%s >= %s",
+                              pkg->req->name,
+                              required_atleast_version);
+#endif
+          return 0;
+        }
       else
-        return 1;
+        {
+#ifdef LOG_SOCKET
+          send_to_log_socket ("! %s >= %s",
+                              pkg->req->name,
+                              required_atleast_version);
+#endif
+          return 1;
+        }
     }
   else if (required_max_version)
     {
       Package *pkg = packages->data;
 
       if (compare_versions (pkg->version, required_max_version) <= 0)
-        return 0;
+        {
+#ifdef LOG_SOCKET
+          send_to_log_socket ("%s <= %s",
+                              pkg->req->name,
+                              required_max_version);
+#endif
+          return 0;
+        }
       else
-        return 1;
+        {
+#ifdef LOG_SOCKET
+          send_to_log_socket ("! %s <= %s",
+                              pkg->req->name,
+                              required_max_version);
+#endif
+          return 1;
+        }
     }
 
   /* Print all flags; then print a newline at the end. */
diff -Naur pkg-config.old/Makefile.am pkg-config/Makefile.am
--- pkg-config.old/Makefile.am	2007-11-05 13:44:27.000000000 +0200
+++ pkg-config/Makefile.am	2007-11-05 13:51:27.000000000 +0200
@@ -36,3 +36,6 @@
 	poptint.h \
 	poptparse.c
 
+if LOG_SOCKET
+pkg_config_SOURCES += logsocket.c logsocket.h
+endif
diff -Naur pkg-config.old/pkg.h pkg-config/pkg.h
--- pkg-config.old/pkg.h	2007-11-05 13:44:27.000000000 +0200
+++ pkg-config/pkg.h	2007-11-05 13:51:15.000000000 +0200
@@ -75,6 +75,9 @@
   int path_position; /* used to order packages by position in path of 
their .pc file, lower number means earlier in path */
   int libs_num; /* Number of times the "Libs" header has been seen */
   int libs_private_num;  /* Number of times the "Libs.private" header has 
been seen */
+#ifdef LOG_SOCKET
+  RequiredVersion *req;  /* Pointer to package's required version data */
+#endif
 };
 
 Package *get_package               (const char *name);


More information about the pkg-config mailing list