[CRIU] [PATCH 1/2] crtools: implement BSD-style setproctitle()
Ruslan Kuprieiev
kupruser at gmail.com
Wed Mar 5 01:28:12 PST 2014
On 05.03.2014 07:49, Kir Kolyshkin wrote:
> 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.
>
Oh, how did I miss that? Thanks! Will use.
> 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.
>
I used implementations of setproctitle from chromium and postgreSQL as
examples. They differ a lot, and my code was inspired by them both. But
i will be
more careful further.
> Kir.
More information about the CRIU
mailing list