libbsd: Branch 'master' - 7 commits

Guillem Jover guillem at kemper.freedesktop.org
Sat Jun 8 09:35:18 PDT 2013


 .gitignore         |    2 +
 COPYING            |    2 -
 configure.ac       |   45 ++++++++++++++++++++++++++++++++++++
 src/Makefile.am    |    2 -
 src/setproctitle.c |   66 ++++++++++++++++++++++++++++++++++++++++++-----------
 test/proctitle.c   |    8 +++++-
 6 files changed, 109 insertions(+), 16 deletions(-)

New commits:
commit 1bf0a55579d823fadccb1ff2d58770cbb404c810
Author: Guillem Jover <guillem at hadrons.org>
Date:   Sat Jun 8 17:43:42 2013 +0200

    Release libbsd 0.5.2

diff --git a/src/Makefile.am b/src/Makefile.am
index a8ab6af..08c0d54 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -34,7 +34,7 @@ libbsd_la_DEPENDENCIES = \
 	libbsd.map
 libbsd_la_LDFLAGS = \
 	-Wl,--version-script=$(srcdir)/libbsd.map \
-	-version-number 0:5:1
+	-version-number 0:5:2
 libbsd_la_SOURCES = \
 	arc4random.c \
 	bsd_getopt.c \
commit ad613d9d09e12c2397d8804c66f65ff1f89eed64
Author: Guillem Jover <guillem at hadrons.org>
Date:   Fri Jun 7 07:11:50 2013 +0200

    Create a shallow copy of environ before replacing it in setproctitle()
    
    Because clearenv() or setenv() might free the environ array of pointers,
    we should make sure to copy it so that we can access it later on when
    doing the deep copy via setenv().
    
    Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=65470

diff --git a/src/setproctitle.c b/src/setproctitle.c
index 0d97954..7e4b165 100644
--- a/src/setproctitle.c
+++ b/src/setproctitle.c
@@ -76,36 +76,60 @@ spt_clearenv(void)
 }
 
 static int
-spt_copyenv(char *oldenv[])
+spt_copyenv(int envc, char *envp[])
 {
+	char **envcopy;
 	char *eq;
+	int envsize;
 	int i, error;
 
-	if (environ != oldenv)
+	if (environ != envp)
 		return 0;
 
+	/* Make a copy of the old environ array of pointers, in case
+	 * clearenv() or setenv() is implemented to free the internal
+	 * environ array, because we will need to access the old environ
+	 * contents to make the new copy. */
+	envsize = (envc + 1) * sizeof(char *);
+	envcopy = malloc(envsize);
+	if (envcopy == NULL)
+		return errno;
+	memcpy(envcopy, envp, envsize);
+
 	error = spt_clearenv();
 	if (error) {
-		environ = oldenv;
+		environ = envp;
+		free(envcopy);
 		return error;
 	}
 
-	for (i = 0; oldenv[i]; i++) {
-		eq = strchr(oldenv[i], '=');
+	for (i = 0; envcopy[i]; i++) {
+		eq = strchr(envcopy[i], '=');
 		if (eq == NULL)
 			continue;
 
 		*eq = '\0';
-		if (setenv(oldenv[i], eq + 1, 1) < 0)
+		if (setenv(envcopy[i], eq + 1, 1) < 0)
 			error = errno;
 		*eq = '=';
 
 		if (error) {
-			environ = oldenv;
+#ifdef HAVE_CLEARENV
+			/* Because the old environ might not be available
+			 * anymore we will make do with the shallow copy. */
+			environ = envcopy;
+#else
+			environ = envp;
+			free(envcopy);
+#endif
 			return error;
 		}
 	}
 
+	/* Dispose of the shallow copy, now that we've finished transfering
+	 * the old environment. */
+	free(envcopy);
+
 	return 0;
 }
 
@@ -133,7 +157,7 @@ static void
 spt_init(int argc, char *argv[], char *envp[])
 {
 	char *base, *end, *nul, *tmp;
-	int i, error;
+	int i, envc, error;
 
 	/* Try to make sure we got called with main() arguments. */
 	if (argc < 0)
@@ -159,6 +183,7 @@ spt_init(int argc, char *argv[], char *envp[])
 
 		end = envp[i] + strlen(envp[i]) + 1;
 	}
+	envc = i;
 
 	SPT.arg0 = strdup(argv[0]);
 	if (SPT.arg0 == NULL) {
@@ -173,7 +198,7 @@ spt_init(int argc, char *argv[], char *envp[])
 	}
 	setprogname(tmp);
 
-	error = spt_copyenv(envp);
+	error = spt_copyenv(envc, envp);
 	if (error) {
 		SPT.error = error;
 		return;
commit e084ce3fa75d38067c3f0b2a4c73410070742238
Author: Guillem Jover <guillem at hadrons.org>
Date:   Fri Jun 7 04:46:29 2013 +0200

    Specify setproctitle_stub() signature manually if typeof is missing
    
    Do not stop exporting the function in the version node even if typeof
    is not available, as that would break ABI.

diff --git a/src/setproctitle.c b/src/setproctitle.c
index e4f648a..0d97954 100644
--- a/src/setproctitle.c
+++ b/src/setproctitle.c
@@ -257,11 +257,14 @@ setproctitle_impl(const char *fmt, ...)
 }
 __asm__(".symver setproctitle_impl,setproctitle@@LIBBSD_0.5");
 
-#ifdef HAVE_TYPEOF
 /* The original function introduced in 0.2 was a stub, it only got implemented
  * in 0.5, make the implementation available in the old version as an alias
  * for code linking against that version, and change the default to use the
  * new version, so that new code depends on the implemented version. */
+#ifdef HAVE_TYPEOF
 extern typeof(setproctitle_impl) setproctitle_stub __attribute__((alias("setproctitle_impl")));
-__asm__(".symver setproctitle_stub,setproctitle at LIBBSD_0.2");
+#else
+void setproctitle_stub(const char *fmt, ...)
+	__attribute__((alias("setproctitle_impl")));
 #endif
+__asm__(".symver setproctitle_stub,setproctitle at LIBBSD_0.2");
commit 50e4c55afddad7f1001c80f3682ea7400a808747
Author: Guillem Jover <guillem at hadrons.org>
Date:   Sat Jun 8 17:55:19 2013 +0200

    Try to check if setproctitle() constructor got passed arguments

diff --git a/src/setproctitle.c b/src/setproctitle.c
index 2137190..e4f648a 100644
--- a/src/setproctitle.c
+++ b/src/setproctitle.c
@@ -135,6 +135,10 @@ spt_init(int argc, char *argv[], char *envp[])
 	char *base, *end, *nul, *tmp;
 	int i, error;
 
+	/* Try to make sure we got called with main() arguments. */
+	if (argc < 0)
+		return;
+
 	base = argv[0];
 	if (base == NULL)
 		return;
commit 6faea4d2a0eb7782187dd6d92749a0813e7405bd
Author: Guillem Jover <guillem at hadrons.org>
Date:   Wed May 29 02:23:56 2013 +0200

    Force setproctitle() into .init_array section
    
    The GNU .init_array support is an extension over the standard System V
    ABI .init_array support, which passes the main() arguments to the init
    function.
    
    This support comes in three parts. First the dynamic linker (from glibc)
    needs to support it. Then function pointers need to be placed in the
    section, for example by using __attribute__((constructor)), that the
    compiler (gcc or clang for example) might place in section .ctors and
    the linker (from binutils) will move to .init_array on the output
    object, or by placing them directly into .init_array by the compiler
    when compiling. If this does not happen and the function pointers end
    up in .ctors, then they will not get passed the main() arguments, which
    we do really need in this case.
    
    But this relies on recent binutils or gcc having native .init_array
    support, and not having it disabled through --disable-initfini-array.
    
    To guarantee we get the correct behaviour, let's just place the function
    pointer in the .init_array section directly, so we only require a recent
    enough glibc.
    
    Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=65029

diff --git a/configure.ac b/configure.ac
index bdadc6e..e63ebfe 100644
--- a/configure.ac
+++ b/configure.ac
@@ -53,6 +53,51 @@ AC_CHECK_DECL([F_CLOSEM],
               [#include <limits.h>
                #include <fcntl.h>])
 
+AC_CACHE_CHECK(
+	[for GNU .init_array section support],
+	[libbsd_cv_gnu_init_array_support],
+	[AC_RUN_IFELSE(
+		[AC_LANG_SOURCE(
+[[
+static int rc = 1;
+static void init(int argc) { if (argc == 1) rc = 0; }
+void (*init_func)(int argc) __attribute__((section(".init_array"))) = init;
+int main() { return rc; }
+]]
+		)],
+		[libbsd_cv_gnu_init_array_support=yes],
+		[libbsd_cv_gnu_init_array_support=no],
+		[AC_PREPROC_IFELSE(
+			[AC_LANG_SOURCE(
+[[
+/* Look for a known libc that supports .init_array with the GNU extension
+ * to pass main() arguments to the init functions. */
+#include <stdlib.h>
+#if defined __GLIBC_PREREQ
+#  if __GLIBC_PREREQ(2, 4)
+/* glibc supports GNU .init_array since 2.4. */
+#  else
+#    error glibc does not support GNU .init_array
+#  endif
+#else
+/*
+ * Basic SysV ABI .init_array support, init functions do not get arguments:
+ * - Bionic since its inception.
+ * - uClibc since 0.9.29.
+ */
+#  error unknown whether libc supports GNU .init_array
+#endif
+]]
+			)],
+			[libbsd_cv_gnu_init_array_support=yes],
+			[libbsd_cv_gnu_init_array_support=no])
+		]
+	)]
+)
+if test "$libbsd_cv_gnu_init_array_support" = no; then
+	AC_MSG_ERROR([missing required GNU .init_array section support])
+fi
+
 # Checks for library functions.
 AC_MSG_CHECKING([for program_invocation_short_name])
 AC_LINK_IFELSE(
diff --git a/src/setproctitle.c b/src/setproctitle.c
index 60b6484..2137190 100644
--- a/src/setproctitle.c
+++ b/src/setproctitle.c
@@ -1,6 +1,6 @@
 /*
  * Copyright © 2010 William Ahern
- * Copyright © 2012 Guillem Jover <guillem at hadrons.org>
+ * Copyright © 2012-2013 Guillem Jover <guillem at hadrons.org>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -129,7 +129,7 @@ spt_copyargs(int argc, char *argv[])
 	return 0;
 }
 
-static void __attribute__((constructor))
+static void
 spt_init(int argc, char *argv[], char *envp[])
 {
 	char *base, *end, *nul, *tmp;
@@ -186,6 +186,14 @@ spt_init(int argc, char *argv[], char *envp[])
 	SPT.end  = end;
 }
 
+/*
+ * Force spt_init() function into the .init_array section instead of expecting
+ * either the compiler to place constructors there or the linker to move them
+ * from .ctors to .init_array.
+ */
+void (*spt_init_func)(int argc, char *argv[], char *envp[])
+	__attribute__((section(".init_array"))) = spt_init;
+
 #ifndef SPT_MAXTITLE
 #define SPT_MAXTITLE 255
 #endif
commit 367e036537109f8955221123af0569329868edf1
Author: Guillem Jover <guillem at hadrons.org>
Date:   Sat Jun 8 08:15:21 2013 +0200

    test: Try setting and getting an environment variable after setproctitle()

diff --git a/COPYING b/COPYING
index 5bcfd38..285ed8f 100644
--- a/COPYING
+++ b/COPYING
@@ -66,7 +66,7 @@ for man/arc4random.3, man/tree.3 and man/getprogname.3.
 The rest of the licenses apply to code and/or man pages.
 
 
-    Copyright © 2004-2006, 2008-2012 Guillem Jover <guillem at hadrons.org>
+    Copyright © 2004-2006, 2008-2013 Guillem Jover <guillem at hadrons.org>
     Copyright © 2005 Hector Garcia Alvarez
     Copyright © 2005 Aurelien Jarno
     Copyright © 2006 Robert Millan
diff --git a/test/proctitle.c b/test/proctitle.c
index 450f0d1..56ea863 100644
--- a/test/proctitle.c
+++ b/test/proctitle.c
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2012 Guillem Jover <guillem at hadrons.org>
+ * Copyright © 2012-2013 Guillem Jover <guillem at hadrons.org>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,6 +35,7 @@ main(int argc, char **argv)
 {
 	const char newtitle_base[] = "test arg1 arg2";
 	char *newtitle_full;
+	char *envvar;
 
 	setproctitle("-test %s arg2", "arg1");
 	assert(strcmp(argv[0], newtitle_base) == 0);
@@ -44,5 +45,10 @@ main(int argc, char **argv)
 	assert(strcmp(argv[0], newtitle_full) == 0);
 	free(newtitle_full);
 
+	assert(setenv("LIBBSD_TEST", "test value", 1) == 0);
+	envvar = getenv("LIBBSD_TEST");
+	assert(envvar != NULL);
+	assert(strcmp(envvar, "test value") == 0);
+
 	return 0;
 }
commit dc8b09783f429a7d1c6d69f1fec8e55b943577f4
Author: Guillem Jover <guillem at hadrons.org>
Date:   Thu May 30 04:09:25 2013 +0200

    build: Ignore automake 1.13+ test suite generated files

diff --git a/.gitignore b/.gitignore
index 20f33d0..b055d8c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,8 @@ ChangeLog
 *.o
 *.so*
 *.a
+*.log
+*.trs
 .deps/
 .libs/
 Makefile


More information about the libbsd mailing list