[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