Modify setproctitle() to conform to project coding style

Use local getprogname()/setprogname() instead of reimplementing them
locally. Use clearenv() if available, not just on glibc. Use bool
instead of _Bool. Use paranthesis on sizeof. Fold the SPT_MIN macro
into spt_min(). Make spt_init() static. Avoid unnecessary gotos.
This commit is contained in:
Guillem Jover 2012-11-25 21:10:53 +01:00
parent 2a0260d08c
commit 35785f8dd1
3 changed files with 99 additions and 123 deletions

View File

@ -432,6 +432,7 @@ The rest of the licenses apply to code and/or man pages.
-- --
Copyright © 2010 William Ahern Copyright © 2010 William Ahern
Copyright © 2012 Guillem Jover <guillem@hadrons.org>
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the copy of this software and associated documentation files (the

View File

@ -71,7 +71,7 @@ AC_LINK_IFELSE(
AC_MSG_RESULT([yes])], AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])]) [AC_MSG_RESULT([no])])
AC_CHECK_FUNCS([dirfd __fpurge getexecname getline sysconf]) AC_CHECK_FUNCS([clearenv dirfd __fpurge getexecname getline sysconf])
AC_CONFIG_FILES([ AC_CONFIG_FILES([
Makefile Makefile

View File

@ -1,7 +1,6 @@
/* ========================================================================== /*
* setproctitle.c - Linux/Darwin setproctitle. * Copyright © 2010 William Ahern
* -------------------------------------------------------------------------- * Copyright © 2012 Guillem Jover <guillem@hadrons.org>
* Copyright (C) 2010 William Ahern
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the * copy of this software and associated documentation files (the
@ -21,69 +20,52 @@
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. * USE OR OTHER DEALINGS IN THE SOFTWARE.
* ==========================================================================
*/ */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stddef.h> /* NULL size_t */
#include <stdarg.h> /* va_list va_start va_end */
#include <stdlib.h> /* malloc(3) setenv(3) clearenv(3) setproctitle(3) getprogname(3) */
#include <stdio.h> /* vsnprintf(3) snprintf(3) */
#include <string.h> /* strlen(3) strchr(3) strdup(3) memset(3) memcpy(3) */
#include <errno.h> /* errno program_invocation_name program_invocation_short_name */
#if !defined(HAVE_SETPROCTITLE)
#define HAVE_SETPROCTITLE (defined __NetBSD__ || defined __FreeBSD__ || defined __OpenBSD__)
#endif
#if !HAVE_SETPROCTITLE
#if (defined __linux || defined __APPLE__) && defined __GNUC__
#include <errno.h>
#include <stddef.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
static struct { static struct {
/* original value */ /* Original value. */
const char *arg0; const char *arg0;
/* title space available */ /* Title space available. */
char *base, *end; char *base, *end;
/* pointer to original nul character within base */ /* Pointer to original nul character within base. */
char *nul; char *nul;
_Bool reset; bool reset;
int error; int error;
} SPT; } SPT;
#ifndef SPT_MIN static inline size_t
#define SPT_MIN(a, b) (((a) < (b))? (a) : (b)) spt_min(size_t a, size_t b)
#endif {
return a < b ? a : b;
static inline size_t spt_min(size_t a, size_t b) { }
return SPT_MIN(a, b);
} /* spt_min() */
/* /*
* For discussion on the portability of the various methods, see * For discussion on the portability of the various methods, see
* http://lists.freebsd.org/pipermail/freebsd-stable/2008-June/043136.html * http://lists.freebsd.org/pipermail/freebsd-stable/2008-June/043136.html
*/ */
static int spt_clearenv(void) { static int
#if __GLIBC__ spt_clearenv(void)
clearenv(); {
#ifdef HAVE_CLEARENV
return 0; return clearenv();
#else #else
extern char **environ;
char **tmp; char **tmp;
if (!(tmp = malloc(sizeof *tmp))) tmp = malloc(sizeof(*tmp));
if (tmp == NULL)
return errno; return errno;
tmp[0] = NULL; tmp[0] = NULL;
@ -91,72 +73,77 @@ static int spt_clearenv(void) {
return 0; return 0;
#endif #endif
} /* spt_clearenv() */ }
static int
static int spt_copyenv(char *oldenv[]) { spt_copyenv(char *oldenv[])
extern char **environ; {
char *eq; char *eq;
int i, error; int i, error;
if (environ != oldenv) if (environ != oldenv)
return 0; return 0;
if ((error = spt_clearenv())) error = spt_clearenv();
goto error; if (error) {
environ = oldenv;
return error;
}
for (i = 0; oldenv[i]; i++) { for (i = 0; oldenv[i]; i++) {
if (!(eq = strchr(oldenv[i], '='))) eq = strchr(oldenv[i], '=');
if (eq == NULL)
continue; continue;
*eq = '\0'; *eq = '\0';
error = (0 != setenv(oldenv[i], eq + 1, 1))? errno : 0; if (setenv(oldenv[i], eq + 1, 1) < 0)
error = errno;
*eq = '='; *eq = '=';
if (error) if (error) {
goto error; environ = oldenv;
return error;
}
} }
return 0; return 0;
error: }
environ = oldenv;
return error; static int
} /* spt_copyenv() */ spt_copyargs(int argc, char *argv[])
{
static int spt_copyargs(int argc, char *argv[]) {
char *tmp; char *tmp;
int i; int i;
for (i = 1; i < argc || (i >= argc && argv[i]); i++) { for (i = 1; i < argc || (i >= argc && argv[i]); i++) {
if (!argv[i]) if (argv[i] == NULL)
continue; continue;
if (!(tmp = strdup(argv[i]))) tmp = strdup(argv[i]);
if (tmp == NULL)
return errno; return errno;
argv[i] = tmp; argv[i] = tmp;
} }
return 0; return 0;
} /* spt_copyargs() */ }
static void __attribute__((constructor))
void spt_init(int argc, char *argv[], char *envp[]) __attribute__((constructor)); spt_init(int argc, char *argv[], char *envp[])
{
void spt_init(int argc, char *argv[], char *envp[]) {
char *base, *end, *nul, *tmp; char *base, *end, *nul, *tmp;
int i, error; int i, error;
if (!(base = argv[0])) base = argv[0];
if (base == NULL)
return; return;
nul = &base[strlen(base)]; nul = &base[strlen(base)];
end = nul + 1; end = nul + 1;
for (i = 0; i < argc || (i >= argc && argv[i]); i++) { for (i = 0; i < argc || (i >= argc && argv[i]); i++) {
if (!argv[i] || argv[i] < end) if (argv[i] == NULL || argv[i] < end)
continue; continue;
end = argv[i] + strlen(argv[i]) + 1; end = argv[i] + strlen(argv[i]) + 1;
@ -169,77 +156,73 @@ void spt_init(int argc, char *argv[], char *envp[]) {
end = envp[i] + strlen(envp[i]) + 1; end = envp[i] + strlen(envp[i]) + 1;
} }
if (!(SPT.arg0 = strdup(argv[0]))) SPT.arg0 = strdup(argv[0]);
goto syerr; if (SPT.arg0 == NULL) {
SPT.error = errno;
#if __GLIBC__ return;
if (!(tmp = strdup(program_invocation_name))) }
goto syerr;
program_invocation_name = tmp;
if (!(tmp = strdup(program_invocation_short_name)))
goto syerr;
program_invocation_short_name = tmp;
#elif __APPLE__
if (!(tmp = strdup(getprogname())))
goto syerr;
tmp = strdup(getprogname());
if (tmp == NULL) {
SPT.error = errno;
return;
}
setprogname(tmp); setprogname(tmp);
#endif
error = spt_copyenv(envp);
if (error) {
SPT.error = error;
return;
}
if ((error = spt_copyenv(envp))) error = spt_copyargs(argc, argv);
goto error; if (error) {
SPT.error = error;
if ((error = spt_copyargs(argc, argv))) return;
goto error; }
SPT.nul = nul; SPT.nul = nul;
SPT.base = base; SPT.base = base;
SPT.end = end; SPT.end = end;
}
return;
syerr:
error = errno;
error:
SPT.error = error;
} /* spt_init() */
#ifndef SPT_MAXTITLE #ifndef SPT_MAXTITLE
#define SPT_MAXTITLE 255 #define SPT_MAXTITLE 255
#endif #endif
void setproctitle(const char *fmt, ...) { void
char buf[SPT_MAXTITLE + 1]; /* use buffer in case argv[0] is passed */ setproctitle(const char *fmt, ...)
{
/* Use buffer in case argv[0] is passed. */
char buf[SPT_MAXTITLE + 1];
va_list ap; va_list ap;
char *nul; char *nul;
int len, error; int len;
if (!SPT.base) if (SPT.base == NULL)
return; return;
if (fmt) { if (fmt) {
va_start(ap, fmt); va_start(ap, fmt);
len = vsnprintf(buf, sizeof buf, fmt, ap); len = vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap); va_end(ap);
} else { } else {
len = snprintf(buf, sizeof buf, "%s", SPT.arg0); len = snprintf(buf, sizeof(buf), "%s", SPT.arg0);
} }
if (len <= 0) if (len <= 0) {
{ error = errno; goto error; } SPT.error = errno;
return;
}
if (!SPT.reset) { if (!SPT.reset) {
memset(SPT.base, 0, SPT.end - SPT.base); memset(SPT.base, 0, SPT.end - SPT.base);
SPT.reset = 1; SPT.reset = true;
} else { } else {
memset(SPT.base, 0, spt_min(sizeof buf, SPT.end - SPT.base)); memset(SPT.base, 0, spt_min(sizeof(buf), SPT.end - SPT.base));
} }
len = spt_min(len, spt_min(sizeof buf, SPT.end - SPT.base) - 1); len = spt_min(len, spt_min(sizeof(buf), SPT.end - SPT.base) - 1);
memcpy(SPT.base, buf, len); memcpy(SPT.base, buf, len);
nul = &SPT.base[len]; nul = &SPT.base[len];
@ -249,12 +232,4 @@ void setproctitle(const char *fmt, ...) {
*SPT.nul = ' '; *SPT.nul = ' ';
*++nul = '\0'; *++nul = '\0';
} }
}
return;
error:
SPT.error = error;
} /* setproctitle() */
#endif /* __linux || __APPLE__ */
#endif /* !HAVE_SETPROCTITLE */