summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac45
-rw-r--r--src/setproctitle.c12
2 files changed, 55 insertions, 2 deletions
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@hadrons.org>
+ * Copyright © 2012-2013 Guillem Jover <guillem@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