Compare commits

..

9 Commits
0.5.0 ... 0.5.2

Author SHA1 Message Date
Guillem Jover
1bf0a55579 Release libbsd 0.5.2 2013-06-08 18:26:04 +02:00
Guillem Jover
ad613d9d09 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
2013-06-08 18:26:04 +02:00
Guillem Jover
e084ce3fa7 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.
2013-06-08 18:09:36 +02:00
Guillem Jover
50e4c55afd Try to check if setproctitle() constructor got passed arguments 2013-06-08 18:09:36 +02:00
Guillem Jover
6faea4d2a0 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
2013-06-08 18:09:29 +02:00
Guillem Jover
367e036537 test: Try setting and getting an environment variable after setproctitle() 2013-06-08 18:08:58 +02:00
Guillem Jover
dc8b09783f build: Ignore automake 1.13+ test suite generated files 2013-05-30 04:09:25 +02:00
Guillem Jover
4663364783 Release libbsd 0.5.1 2013-05-27 06:52:05 +02:00
Guillem Jover
df5aebd7e1 test: Mark a literal integer as long long
This fixes build failures on 32-bit architectures.
2013-05-27 06:51:15 +02:00
7 changed files with 110 additions and 17 deletions

2
.gitignore vendored
View File

@@ -5,6 +5,8 @@ ChangeLog
*.o
*.so*
*.a
*.log
*.trs
.deps/
.libs/
Makefile

View File

@@ -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@hadrons.org>
Copyright © 2004-2006, 2008-2013 Guillem Jover <guillem@hadrons.org>
Copyright © 2005 Hector Garcia Alvarez
Copyright © 2005 Aurelien Jarno
Copyright © 2006 Robert Millan

View File

@@ -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(

View File

@@ -34,7 +34,7 @@ libbsd_la_DEPENDENCIES = \
libbsd.map
libbsd_la_LDFLAGS = \
-Wl,--version-script=$(srcdir)/libbsd.map \
-version-number 0:5:0
-version-number 0:5:2
libbsd_la_SOURCES = \
arc4random.c \
bsd_getopt.c \

View File

@@ -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
@@ -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;
}
@@ -129,11 +153,15 @@ 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;
int i, error;
int i, envc, error;
/* Try to make sure we got called with main() arguments. */
if (argc < 0)
return;
base = argv[0];
if (base == NULL)
@@ -155,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) {
@@ -169,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;
@@ -186,6 +215,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
@@ -245,11 +282,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@LIBBSD_0.2");
#else
void setproctitle_stub(const char *fmt, ...)
__attribute__((alias("setproctitle_impl")));
#endif
__asm__(".symver setproctitle_stub,setproctitle@LIBBSD_0.2");

View File

@@ -58,7 +58,7 @@ main(int argc, char **argv)
assert(val == 20971520);
assert(dehumanize_number("-3G", &val) == 0);
assert(val == -3221225472);
assert(val == -3221225472LL);
return 0;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2012 Guillem Jover <guillem@hadrons.org>
* Copyright © 2012-2013 Guillem Jover <guillem@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;
}