]> mj.ucw.cz Git - libucw.git/blob - ucw/proctitle.c
Let setproctitle() recalculate program_invocation_name
[libucw.git] / ucw / proctitle.c
1 /*
2  *      UCW Library -- Setting of Process Title
3  *
4  *      (c) 2001--2006 Martin Mares <mj@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #include "ucw/lib.h"
11
12 #include <stdio.h>
13 #include <string.h>
14 #include <stdarg.h>
15 #include <unistd.h>
16 #include <errno.h>
17
18 static char **spt_argv;
19 static char *spt_start, *spt_end;
20
21 void
22 setproctitle_init(int argc, char **argv)
23 {
24 #ifdef CONFIG_LINUX
25   int i, len;
26   char **env, **oldenv, *t;
27
28   spt_argv = argv;
29
30   /* Create a backup copy of environment */
31   oldenv = __environ;
32   len = 0;
33   for (i=0; oldenv[i]; i++)
34     len += strlen(oldenv[i]) + 1;
35   __environ = env = xmalloc(sizeof(char *)*(i+1));
36   t = xmalloc(len);
37   for (i=0; oldenv[i]; i++)
38     {
39       env[i] = t;
40       len = strlen(oldenv[i]) + 1;
41       memcpy(t, oldenv[i], len);
42       t += len;
43     }
44   env[i] = NULL;
45
46   /* Scan for consecutive free space */
47   spt_start = spt_end = argv[0];
48   for (i=0; i<argc; i++)
49     if (!i || spt_end+1 == argv[i])
50       spt_end = argv[i] + strlen(argv[i]);
51   for (i=0; oldenv[i]; i++)
52     if (spt_end+1 == oldenv[i])
53       spt_end = oldenv[i] + strlen(oldenv[i]);
54
55   /* Recalculate program_invocation_name, otherwise syslog() will be confused. */
56   char *name = xstrdup(argv[0]);
57   program_invocation_name = name;
58   char *p = strrchr(name, '/');
59   if (p)
60     program_invocation_short_name = p + 1;
61   else
62     program_invocation_short_name = name;
63 #endif
64 }
65
66 void
67 setproctitle(const char *msg, ...)
68 {
69   va_list args;
70   byte buf[256];
71   int n;
72
73   va_start(args, msg);
74   if (spt_end > spt_start)
75     {
76       n = vsnprintf(buf, sizeof(buf), msg, args);
77       if (n >= (int) sizeof(buf) || n < 0)
78         sprintf(buf, "<too-long>");
79       n = spt_end - spt_start;
80       strncpy(spt_start, buf, n);
81       spt_start[n] = 0;
82       spt_argv[0] = spt_start;
83       spt_argv[1] = NULL;
84     }
85   va_end(args);
86 }
87
88 char *
89 getproctitle(void)
90 {
91   return (spt_start < spt_end) ? spt_start : NULL;
92 }