summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2012-10-03 17:36:15 -0400
committerColin Walters <walters@verbum.org>2012-10-03 17:36:29 -0400
commitbed372a86defdd6886d8c520eeead2b08cdf2542 (patch)
tree1aef2e89639fc9f9895513efbd32e07d1b0adfa7
parenta55cab9cb2d288870b899b35e2d55c3d7f4634da (diff)
Import libgsystem, use it for local-allocations in main.cwip/libgsystem-2
See http://git.gnome.org/browse/libgsystem/tree/README for a description of libgsystem. What we specifically are using it for here is the local allocation macros; this patch just modifies main.c as a demo. Note this patch fixes a double-free in an error condition in check_pidfile(); those sort of mistakes are basically impossible to make when using these macros.
-rw-r--r--src/Makefile.am14
-rw-r--r--src/libgsystem/Makefile-libgsystem.am31
-rw-r--r--src/libgsystem/README7
-rw-r--r--src/libgsystem/README-NetworkManager-import5
-rw-r--r--src/libgsystem/gsystem-file-utils.c86
-rw-r--r--src/libgsystem/gsystem-file-utils.h34
-rw-r--r--src/libgsystem/gsystem-local-alloc.c65
-rw-r--r--src/libgsystem/gsystem-local-alloc.h42
-rw-r--r--src/libgsystem/libgsystem.doap31
-rw-r--r--src/libgsystem/libgsystem.h33
-rw-r--r--src/main.c76
11 files changed, 368 insertions, 56 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index b155209c..cf239d18 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -21,11 +21,20 @@ endif
SUBDIRS += . tests
+noinst_LTLIBRARIES =
+EXTRA_DIST =
+NULL =
+libgsystem_srcpath := libgsystem
+libgsystem_cflags = $(GIO_CFLAGS)
+libgsystem_libs = $(GIO_LIBS)
+include libgsystem/Makefile-libgsystem.am
+
INCLUDES = -I${top_srcdir} \
-I${top_builddir}/include \
-I${top_srcdir}/include \
-I${top_builddir}/src/generated \
-I${top_srcdir}/src/generated \
+ -I${top_srcdir}/src/libgsystem \
-I${top_srcdir}/src/logging \
-I${top_srcdir}/src/posix-signals \
-I${top_srcdir}/src/dns-manager \
@@ -47,7 +56,7 @@ INCLUDES = -I${top_srcdir} \
# Test libraries
###########################################
-noinst_LTLIBRARIES = \
+noinst_LTLIBRARIES += \
libtest-dhcp.la \
libtest-policy-hosts.la \
libtest-wifi-ap-utils.la
@@ -306,6 +315,7 @@ endif
NetworkManager_LDADD = \
./generated/libnm-generated.la \
+ libgsystem.la \
./logging/libnm-logging.la \
./posix-signals/libnm-posix-signals.la \
./dns-manager/libdns-manager.la \
@@ -356,7 +366,7 @@ NetworkManager_DATA = gdb-cmd
dbusservicedir = $(DBUS_SYS_DIR)
dbusservice_DATA = org.freedesktop.NetworkManager.conf
-EXTRA_DIST = \
+EXTRA_DIST += \
$(dbusservice_DATA) \
$(NetworkManager_DATA)
diff --git a/src/libgsystem/Makefile-libgsystem.am b/src/libgsystem/Makefile-libgsystem.am
new file mode 100644
index 00000000..0f6e72fe
--- /dev/null
+++ b/src/libgsystem/Makefile-libgsystem.am
@@ -0,0 +1,31 @@
+# Copyright (C) 2012 Colin Walters <walters@verbum.org>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+noinst_LTLIBRARIES += libgsystem.la
+
+EXTRA_DIST += $(libgsystem_srcpath)/README $(libgsystem_srcpath)/COPYING
+
+libgsystem_la_SOURCES = \
+ $(libgsystem_srcpath)/gsystem-local-alloc.h \
+ $(libgsystem_srcpath)/gsystem-local-alloc.c \
+ $(libgsystem_srcpath)/gsystem-file-utils.h \
+ $(libgsystem_srcpath)/gsystem-file-utils.c \
+ $(libgsystem_srcpath)/libgsystem.h \
+ $(NULL)
+
+libgsystem_la_CFLAGS = $(AM_CFLAGS) $(libgsystem_cflags)
+libgsystem_la_LIBADD = $(libgsystem_libs)
diff --git a/src/libgsystem/README b/src/libgsystem/README
new file mode 100644
index 00000000..06949401
--- /dev/null
+++ b/src/libgsystem/README
@@ -0,0 +1,7 @@
+libgsystem is intended to be used as a git external for components
+that depend on GLib, but accept a hard dependency on things which are
+difficult to do in GLib itself. For example, the local-alloc API
+depends on GCC/clang.
+
+It will also be a useful place to evolve new APIs (e.g. logging)
+before their eventual inclusion in GLib (if ever).
diff --git a/src/libgsystem/README-NetworkManager-import b/src/libgsystem/README-NetworkManager-import
new file mode 100644
index 00000000..fa759985
--- /dev/null
+++ b/src/libgsystem/README-NetworkManager-import
@@ -0,0 +1,5 @@
+This code is copied from:
+
+http://git.gnome.org/browse/libgsystem
+
+Please send any patches there!
diff --git a/src/libgsystem/gsystem-file-utils.c b/src/libgsystem/gsystem-file-utils.c
new file mode 100644
index 00000000..92ddf49f
--- /dev/null
+++ b/src/libgsystem/gsystem-file-utils.c
@@ -0,0 +1,86 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2012 William Jon McCann <mccann@redhat.com>
+ * Copyright (C) 2012 Colin Walters <walters@verbum.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include "libgsystem.h"
+#include <glib/gstdio.h>
+#include <gio/gunixinputstream.h>
+#include <glib-unix.h>
+
+static int
+_open_fd_noatime (const char *path)
+{
+ int fd;
+
+#ifdef O_NOATIME
+ fd = g_open (path, O_RDONLY | O_NOATIME, 0);
+ /* Only the owner or superuser may use O_NOATIME; so we may get
+ * EPERM. EINVAL may happen if the kernel is really old...
+ */
+ if (fd == -1 && (errno == EPERM || errno == EINVAL))
+#endif
+ fd = g_open (path, O_RDONLY, 0);
+
+ return fd;
+}
+
+/**
+ * gs_file_read_noatime:
+ * @file: a #GFile
+ * @cancellable: a #GCancellable
+ * @error: a #GError
+ *
+ * Like g_file_read(), but try to avoid updating the file's
+ * access time. This should be used by background scanning
+ * components such as search indexers, antivirus programs, etc.
+ *
+ * Returns: (transfer full): A new input stream, or %NULL on error
+ */
+GInputStream *
+gs_file_read_noatime (GFile *file,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gs_lfree char *path = NULL;
+ int fd;
+
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ return NULL;
+
+ path = g_file_get_path (file);
+ if (path == NULL)
+ return NULL;
+
+ fd = _open_fd_noatime (path);
+ if (fd < 0)
+ {
+ g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+ "%s", g_strerror (errno));
+ return NULL;
+ }
+
+ return g_unix_input_stream_new (fd, TRUE);
+}
diff --git a/src/libgsystem/gsystem-file-utils.h b/src/libgsystem/gsystem-file-utils.h
new file mode 100644
index 00000000..f8c1c733
--- /dev/null
+++ b/src/libgsystem/gsystem-file-utils.h
@@ -0,0 +1,34 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2012 Colin Walters <walters@verbum.org>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GSYSTEM_FILE_UTILS_H__
+#define __GSYSTEM_FILE_UTILS_H__
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+GInputStream *gs_file_read_noatime (GFile *path,
+ GCancellable *cancellable,
+ GError **error);
+
+G_END_DECLS
+
+#endif
diff --git a/src/libgsystem/gsystem-local-alloc.c b/src/libgsystem/gsystem-local-alloc.c
new file mode 100644
index 00000000..1bbea900
--- /dev/null
+++ b/src/libgsystem/gsystem-local-alloc.c
@@ -0,0 +1,65 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2012 Colin Walters <walters@verbum.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gsystem-local-alloc.h"
+
+void
+gs_local_free (void *loc)
+{
+ void **location = loc;
+ if (location)
+ g_free (*location);
+}
+
+#define _gs_local_free(type, function) do { \
+ void **location = loc; \
+ if (location) \
+ { \
+ type *value = *location; \
+ if (value) \
+ function (value); \
+ } \
+ } while (0)
+
+void
+gs_local_obj_unref (void *loc)
+{
+ _gs_local_free(GObject, g_object_unref);
+}
+
+void
+gs_local_variant_unref (void *loc)
+{
+ _gs_local_free(GVariant, g_variant_unref);
+}
+
+void
+gs_local_ptrarray_unref (void *loc)
+{
+ _gs_local_free(GPtrArray, g_ptr_array_unref);
+}
+
+void
+gs_local_hashtable_unref (void *loc)
+{
+ _gs_local_free(GHashTable, g_hash_table_unref);
+}
diff --git a/src/libgsystem/gsystem-local-alloc.h b/src/libgsystem/gsystem-local-alloc.h
new file mode 100644
index 00000000..24e7ca29
--- /dev/null
+++ b/src/libgsystem/gsystem-local-alloc.h
@@ -0,0 +1,42 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2012 Colin Walters <walters@verbum.org>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GSYSTEM_LOCAL_ALLOC_H__
+#define __GSYSTEM_LOCAL_ALLOC_H__
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+void gs_local_free (void *loc);
+void gs_local_obj_unref (void *loc);
+void gs_local_variant_unref (void *loc);
+void gs_local_ptrarray_unref (void *loc);
+void gs_local_hashtable_unref (void *loc);
+
+#define gs_lfree __attribute__ ((cleanup(gs_local_free)))
+#define gs_lobj __attribute__ ((cleanup(gs_local_obj_unref)))
+#define gs_lvariant __attribute__ ((cleanup(gs_local_variant_unref)))
+#define gs_lptrarray __attribute__ ((cleanup(gs_local_ptrarray_unref)))
+#define gs_lhash __attribute__ ((cleanup(gs_local_hashtable_unref)))
+
+G_END_DECLS
+
+#endif
diff --git a/src/libgsystem/libgsystem.doap b/src/libgsystem/libgsystem.doap
new file mode 100644
index 00000000..f2483867
--- /dev/null
+++ b/src/libgsystem/libgsystem.doap
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Project xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
+ xmlns:foaf="http://xmlns.com/foaf/0.1/"
+ xmlns:gnome="http://api.gnome.org/doap-extensions#"
+ xmlns="http://usefulinc.com/ns/doap#">
+
+ <name>libgsystem</name>
+ <shortname>libgsystem</shortname>
+
+ <shortdesc xml:lang="en">"Copylib" for system service modules using GLib with GCC</shortdesc>
+
+ <description xml:lang="en">This module is intended for use by
+ infrastructure daemons using GLib, such as NetworkManager/udisks as
+ a git submodule.
+ </description>
+
+ <license rdf:resource="http://usefulinc.com/doap/licenses/lgpl" />
+ <mailing-list rdf:resource="mailto:desktop-devel-list@gnome.org" />
+
+ <programming-language>C</programming-language>
+
+ <maintainer>
+ <foaf:Person>
+ <foaf:name>Colin Walters</foaf:name>
+ <foaf:mbox rdf:resource="mailto:walters@verbum.org"/>
+ <gnome:userid>walters</gnome:userid>
+ </foaf:Person>
+ </maintainer>
+
+</Project>
diff --git a/src/libgsystem/libgsystem.h b/src/libgsystem/libgsystem.h
new file mode 100644
index 00000000..7b6a8c86
--- /dev/null
+++ b/src/libgsystem/libgsystem.h
@@ -0,0 +1,33 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2012 Colin Walters <walters@verbum.org>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __LIBGSYSTEM__
+#define __LIBGSYSTEM__
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#include <gsystem-local-alloc.h>
+#include <gsystem-file-utils.h>
+
+G_END_DECLS
+
+#endif
diff --git a/src/main.c b/src/main.c
index 9cac0fd7..f0b367ab 100644
--- a/src/main.c
+++ b/src/main.c
@@ -40,6 +40,7 @@
#include "NetworkManager.h"
#include "NetworkManagerUtils.h"
+#include "libgsystem.h"
#include "nm-manager.h"
#include "nm-policy.h"
#include "nm-dns-manager.h"
@@ -202,10 +203,10 @@ write_pidfile (const char *pidfile)
static gboolean
check_pidfile (const char *pidfile)
{
- char *contents = NULL;
+ gs_lfree char *contents = NULL;
+ gs_lfree char *proc_cmdline = NULL;
gsize len = 0;
glong pid;
- char *proc_cmdline = NULL;
gboolean nm_running = FALSE;
const char *process_name;
@@ -220,7 +221,6 @@ check_pidfile (const char *pidfile)
if (pid <= 0 || pid > 65536 || errno)
goto done;
- g_free (contents);
proc_cmdline = g_strdup_printf ("/proc/%ld/cmdline", pid);
if (!g_file_get_contents (proc_cmdline, &contents, &len, NULL))
goto done;
@@ -239,8 +239,6 @@ check_pidfile (const char *pidfile)
}
done:
- g_free (proc_cmdline);
- g_free (contents);
return nm_running;
}
@@ -278,7 +276,8 @@ parse_state_file (const char *filename,
* users upgrading NM get this working too.
*/
if (g_error_matches (tmp_error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) {
- char *data, *dirname;
+ gs_lfree char *dirname = NULL;
+ gs_lfree char *data = NULL;
gsize len = 0;
g_clear_error (&tmp_error);
@@ -290,11 +289,9 @@ parse_state_file (const char *filename,
if (errno != EEXIST) {
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_ACCES,
"Error creating state directory %s: %s", dirname, strerror(errno));
- g_free (dirname);
return FALSE;
}
}
- g_free (dirname);
/* Write out the initial state to the state file */
g_key_file_set_boolean (state_file, "main", "NetworkingEnabled", *net_enabled);
@@ -305,7 +302,6 @@ parse_state_file (const char *filename,
data = g_key_file_to_data (state_file, &len, NULL);
if (data)
ret = g_file_set_contents (filename, data, len, error);
- g_free (data);
} else {
/* the error is not "No such file or directory" - propagate the error */
g_propagate_error (error, tmp_error);
@@ -351,24 +347,27 @@ main (int argc, char *argv[])
GOptionContext *opt_ctx = NULL;
gboolean become_daemon = FALSE;
gboolean g_fatal_warnings = FALSE;
- char *pidfile = NULL, *state_file = NULL;
- char *config_path = NULL, *plugins = NULL;
- char *log_level = NULL, *log_domains = NULL;
- char *connectivity_uri = NULL;
+ gs_lfree char *pidfile = NULL;
+ gs_lfree char *state_file = NULL;
+ gs_lfree char *config_path = NULL;
+ gs_lfree char *plugins = NULL;
+ gs_lfree char *log_level = NULL;
+ gs_lfree char *log_domains = NULL;
+ gs_lfree char *connectivity_uri = NULL;
gint connectivity_interval = -1;
- char *connectivity_response = NULL;
+ gs_lfree char *connectivity_response = NULL;
gboolean wifi_enabled = TRUE, net_enabled = TRUE, wwan_enabled = TRUE, wimax_enabled = TRUE;
gboolean success, show_version = FALSE;
NMPolicy *policy = NULL;
- NMVPNManager *vpn_manager = NULL;
- NMDnsManager *dns_mgr = NULL;
- NMDBusManager *dbus_mgr = NULL;
- NMSupplicantManager *sup_mgr = NULL;
- NMDHCPManager *dhcp_mgr = NULL;
- NMFirewallManager *fw_mgr = NULL;
- NMSettings *settings = NULL;
- NMConfig *config;
- NMNetlinkMonitor *monitor = NULL;
+ gs_lobj NMVPNManager *vpn_manager = NULL;
+ gs_lobj NMDnsManager *dns_mgr = NULL;
+ gs_lobj NMDBusManager *dbus_mgr = NULL;
+ gs_lobj NMSupplicantManager *sup_mgr = NULL;
+ gs_lobj NMDHCPManager *dhcp_mgr = NULL;
+ gs_lobj NMFirewallManager *fw_mgr = NULL;
+ gs_lobj NMSettings *settings = NULL;
+ gs_lobj NMConfig *config;
+ gs_lobj NMNetlinkMonitor *monitor = NULL;
GError *error = NULL;
gboolean wrote_pidfile = FALSE;
@@ -668,27 +667,6 @@ done:
if (manager)
g_object_unref (manager);
- if (settings)
- g_object_unref (settings);
-
- if (vpn_manager)
- g_object_unref (vpn_manager);
-
- if (dns_mgr)
- g_object_unref (dns_mgr);
-
- if (dhcp_mgr)
- g_object_unref (dhcp_mgr);
-
- if (sup_mgr)
- g_object_unref (sup_mgr);
-
- if (fw_mgr)
- g_object_unref (fw_mgr);
-
- if (dbus_mgr)
- g_object_unref (dbus_mgr);
-
nm_logging_shutdown ();
if (pidfile && wrote_pidfile)
@@ -696,16 +674,6 @@ done:
nm_config_free (config);
- /* Free options */
- g_free (pidfile);
- g_free (state_file);
- g_free (config_path);
- g_free (plugins);
- g_free (log_level);
- g_free (log_domains);
- g_free (connectivity_uri);
- g_free (connectivity_response);
-
nm_log_info (LOGD_CORE, "exiting (%s)", success ? "success" : "error");
exit (success ? 0 : 1);
}