From cfef0c6658be29967f883997ba7139ca3bdef2ba Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Fri, 27 May 2016 18:04:25 +0100 Subject: [PATCH] getprogname() and setproctitle() on Linux. --- Makefile.am | 11 +++++++++- compat.h | 10 +++++++++ compat/getprogname.c | 43 ++++++++++++++++++++++++++++++++++++ compat/setproctitle.c | 51 +++++++++++++++++++++++++++++++++++++++++++ configure.ac | 41 +++++++++++++++++++++++++++++++++- proc.c | 2 -- 6 files changed, 154 insertions(+), 4 deletions(-) create mode 100644 compat/getprogname.c create mode 100644 compat/setproctitle.c diff --git a/Makefile.am b/Makefile.am index 45288a26..6d6a9e7d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -26,7 +26,7 @@ if IS_GCC CFLAGS += -std=gnu99 -O2 if IS_DEBUG CFLAGS += -g -CFLAGS += -Wno-long-long -Wall -W -Wnested-externs -Wformat=2 +CFLAGS += -Wno-long-long -Wall -W -Wformat=2 CFLAGS += -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations CFLAGS += -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare CFLAGS += -Wundef -Wbad-function-cast -Winline -Wcast-align @@ -194,6 +194,15 @@ endif if NO_DAEMON nodist_tmux_SOURCES += compat/daemon.c endif +if NO_DAEMON +nodist_tmux_SOURCES += compat/daemon.c +endif +if NO_GETPROGNAME +nodist_tmux_SOURCES += compat/getprogname.c +endif +if NO_SETPROCTITLE +nodist_tmux_SOURCES += compat/setproctitle.c +endif if NO_SETENV nodist_tmux_SOURCES += compat/setenv.c endif diff --git a/compat.h b/compat.h index e9d2f159..7f17e193 100644 --- a/compat.h +++ b/compat.h @@ -223,6 +223,16 @@ size_t strlcat(char *, const char *, size_t); int daemon(int, int); #endif +#ifndef HAVE_GETPROGNAME +/* getprogname.c */ +const char *getprogname(void); +#endif + +#ifndef HAVE_SETPROCTITLE +/* setproctitle.c */ +void setproctitle(const char *, ...); +#endif + #ifndef HAVE_B64_NTOP /* b64_ntop.c */ #undef b64_ntop /* for Cygwin */ diff --git a/compat/getprogname.c b/compat/getprogname.c new file mode 100644 index 00000000..20324ebb --- /dev/null +++ b/compat/getprogname.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2016 Nicholas Marriott + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "tmux.h" + +#if defined(HAVE_PROGRAM_INVOCATION_SHORT_NAME) +const char * +getprogname(void) +{ + extern char *program_invocation_short_name; + + return (program_invocation_short_name); +} +#elif defined(HAVE___PROGNAME) +const char * +getprogname(void) +{ + extern char *__progname; + + return (__progname); +} +#else +const char * +getprogname(void) +{ + return ("tmux"); +} +#endif diff --git a/compat/setproctitle.c b/compat/setproctitle.c new file mode 100644 index 00000000..bda924ef --- /dev/null +++ b/compat/setproctitle.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016 Nicholas Marriott + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include + +#include "tmux.h" + +#if defined(HAVE_PRCTL) && defined(HAVE_PR_SET_NAME) + +#include + +void +setproctitle(const char *fmt, ...) +{ + char title[16], name[16], *cp; + va_list ap; + int used; + + va_start(ap, fmt); + vsnprintf(title, sizeof title, fmt, ap); + va_end(ap); + + used = snprintf(name, sizeof name, "%s: %s", getprogname(), title); + if (used >= (int)sizeof name) { + cp = strrchr(name, ' '); + if (cp != NULL) + *cp = '\0'; + } + prctl(PR_SET_NAME, name); +} +#else +void +setproctitle(const char *fmt, ...) +{ +} +#endif diff --git a/configure.ac b/configure.ac index 3692a521..1462b7b1 100644 --- a/configure.ac +++ b/configure.ac @@ -113,7 +113,7 @@ AC_CHECK_FUNCS( [ \ dirfd \ flock \ - setproctitle \ + prctl \ sysconf \ cfmakeraw \ ] @@ -298,6 +298,20 @@ if test "x$found_daemon" = xyes; then fi AM_CONDITIONAL(NO_DAEMON, [test "x$found_daemon" = xno]) +# Look for getprogname, compat/getprogname.c used if missing. +AC_CHECK_FUNC(getprogname, found_getprogname=yes, found_getprogname=no) +if test "x$found_getprogname" = xyes; then + AC_DEFINE(HAVE_GETPROGNAME) +fi +AM_CONDITIONAL(NO_GETPROGNAME, [test "x$found_getprogname" = xno]) + +# Look for setproctitle, compat/setproctitle.c used if missing. +AC_CHECK_FUNC(setproctitle, found_setproctitle=yes, found_setproctitle=no) +if test "x$found_setproctitle" = xyes; then + AC_DEFINE(HAVE_SETPROCTITLE) +fi +AM_CONDITIONAL(NO_SETPROCTITLE, [test "x$found_setproctitle" = xno]) + # Look for setenv, compat/setenv.c used if missing. AC_CHECK_FUNC(setenv, found_setenv=yes, found_setenv=no) if test "x$found_setenv" = xyes; then @@ -475,6 +489,31 @@ AC_LINK_IFELSE([AC_LANG_SOURCE( AC_MSG_RESULT(no) ) +# Look for program_invocation_short_name. +AC_MSG_CHECKING(for program_invocation_short_name) +AC_LINK_IFELSE([AC_LANG_SOURCE( + [ + #include + #include + extern char *program_invocation_short_name; + int main(void) { + const char *cp = program_invocation_short_name; + printf("%s\n", cp); + exit(0); + } + ])], + [AC_DEFINE(HAVE_PROGRAM_INVOCATION_SHORT_NAME) AC_MSG_RESULT(yes)], + AC_MSG_RESULT(no) +) + +# Look for prctl(PR_SET_NAME). +AC_CHECK_DECL( + PR_SET_NAME, + AC_DEFINE(HAVE_PR_SET_NAME), + , + [#include ] +) + # Look for fcntl(F_CLOSEM). AC_CHECK_DECL( F_CLOSEM, diff --git a/proc.c b/proc.c index 27880f57..feac1517 100644 --- a/proc.c +++ b/proc.c @@ -191,9 +191,7 @@ proc_start(const char *name, struct event_base *base, int forkflag, log_open(name); -#ifdef HAVE_SETPROCTITLE setproctitle("%s (%s)", name, socket_path); -#endif if (uname(&u) < 0) memset(&u, 0, sizeof u);