[CRIU] [PATCH 1/2] crtools: implement BSD-style setproctitle()

Kir Kolyshkin kir at openvz.org
Tue Mar 4 19:49:51 PST 2014


On 02/19/2014 01:21 PM, Ruslan Kuprieiev wrote:
> This will allow us to have much informative ps output.
>
> Signed-off-by: Ruslan Kuprieiev <kupruser at gmail.com>
> ---
>   Makefile.crtools       |   1 +
>   include/setproctitle.h |  25 ++++++++++++
>   setproctitle.c         | 106 +++++++++++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 132 insertions(+)
>   create mode 100644 include/setproctitle.h
>   create mode 100644 setproctitle.c
>
> diff --git a/Makefile.crtools b/Makefile.crtools
> index 6effc3e..f13b0d2 100644
> --- a/Makefile.crtools
> +++ b/Makefile.crtools
> @@ -62,6 +62,7 @@ obj-y	+= $(ARCH_DIR)/vdso.o
>   obj-y	+= cr-service.o
>   obj-y	+= sd-daemon.o
>   obj-y	+= plugin.o
> +obj-y	+= setproctitle.o
>   
>   ifneq ($(MAKECMDGOALS),clean)
>   incdeps := y
> diff --git a/include/setproctitle.h b/include/setproctitle.h
> new file mode 100644
> index 0000000..a4a6ca7
> --- /dev/null
> +++ b/include/setproctitle.h
> @@ -0,0 +1,25 @@
> +#ifndef __CR_SETPROCTITLE_H__
> +#define __CR_SETPROCTITLE_H__
> +
> +/*
> + * setproctitle_init() and setproctitle() are implementing BSD-style
> + * setproctitle() for Linux.
> + *
> + * Call setproctitle_init() once before using setproctitle().
> + * This function moves argv and environ out of the way to make maximum space
> + * for process title which is stored in the argv[0].
> + * Upon successful return, this function returns new argv to use. On fail,
> + * this function returns NULL.
> + * DON'T USE OLD ARGV AFTER CALLING THIS FUNCTION!
> + *
> + * setproctitle() sets the process title that appears on the ps(1) command.
> + * If args is NULL, the process title is restored.
> + * If new title begins with '-' character, the executable name is skipped.
> + */
> +
> +extern char **environ;
> +
> +char **setproctitle_init(int argc, char **argv);
> +void setproctitle(const char *fmt, ...);
> +
> +#endif /* __CR_SETPROCTITLE_H__ */
> diff --git a/setproctitle.c b/setproctitle.c
> new file mode 100644
> index 0000000..e1d5443
> --- /dev/null
> +++ b/setproctitle.c
> @@ -0,0 +1,106 @@
> +#include <stdio.h>
> +#include <stdarg.h>
> +#include "xmalloc.h"
> +#include "setproctitle.h"
> +
> +static char *title;
> +static size_t max_title;
> +static char *orig_title;
> +
> +char **setproctitle_init(int argc, char **argv)
> +{
> +	int i;
> +	int environ_size;
> +	char *end = NULL;
> +	char **new_environ;
> +	char **new_argv;
> +
> +	/*
> +	 * Sanity check.
> +	 */
> +	if ((argc < 1) || !argv || !environ)
> +		return NULL;
> +
> +	/*
> +	 * Check for contiguous argv strings.
> +	 */
> +	for (i = 0; i < argc; i++)
> +		if ((i == 0) || (end + 1 == argv[i]))
> +			end = argv[i] + strlen(argv[i]);
> +
> +	/*
> +	 * Check for contiguous environ strings following argv.
> +	 */
> +	for (i = 0; environ[i] != NULL; i++)
> +		if (end + 1 == environ[i])
> +			end = environ[i] + strlen(environ[i]);
> +
> +	environ_size = i;
> +
> +	max_title = end - argv[0];
> +
> +	/*
> +	 * Move environ.
> +	 */
> +	new_environ = xmalloc((environ_size + 1)*sizeof(char *));
> +
> +	for (i = 0; i < environ_size; i++)
> +		new_environ[i] = xstrdup(environ[i]);
> +
> +	new_environ[environ_size] = NULL;
> +
> +	environ = new_environ;
> +
> +	/*
> +	 * Move argv.
> +	 */
> +	new_argv = xmalloc((argc + 1)*sizeof(char *));
> +
> +	for (i = 0; i < argc; i++)
> +		new_argv[i] = xstrdup(argv[i]);
> +
> +	new_argv[argc] = NULL;
> +
> +	/*
> +	 * Save original title.
> +	 */
> +	orig_title	= xstrdup(argv[0]);
> +	title		= argv[0];
> +
> +	return new_argv;
> +}
> +
> +void setproctitle(const char *fmt, ...)
> +{
> +	va_list ap;
> +	size_t current;
> +
> +	/*
> +	 * Sanity check.
> +	 */
> +	if (!title || !orig_title)
> +		return;
> +
> +	/*
> +	 * Fill all available space with '\0' to avoid old chunks in the title.
> +	 */
> +	memset(title, '\0', max_title);
> +
> +	if (!fmt) {
> +		snprintf(title, max_title, "%s", orig_title);
> +		return;
> +	}
> +
> +	va_start(ap, fmt);
> +
> +	if (fmt[0] == '-')
> +		vsnprintf(title, max_title, &fmt[1], ap);
> +	else {
> +		current = snprintf(title, max_title, "%s ", orig_title);
> +
> +		if (current < max_title)
> +			vsnprintf(title+current, max_title-current, fmt, ap);
> +	}
> +
> +	va_end(ap);
> +}

I see two problems here.

First, modern Linux distros (Fedora 18 in my case, haven't checked 
others) come
with libbsd (from http://libbsd.freedesktop.org/) which has 
setproctitle() already.
We can detect its presence and link to it if available, otherwise just 
don't use it.
It's better than to use own implementation.

Second, is this your code? Comments and spacing style suggests it is not.
If it is not yours, you need to clearly state the copyrights. Copy-pasting
something that is larger than 10 lines is not acceptable.

Kir.


More information about the CRIU mailing list