]> mj.ucw.cz Git - libucw.git/blob - ucw/proctitle.c
82a0b8eda3433b6d5c271535eadacb3400f6b961
[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 #include <ucw/process.h>
12
13 #include <stdio.h>
14 #include <string.h>
15 #include <stdarg.h>
16 #include <unistd.h>
17 #include <errno.h>
18
19 static char **spt_argv;
20 static char *spt_start, *spt_end;
21
22 void
23 setproctitle_init(int argc, char **argv)
24 {
25 #ifdef CONFIG_LINUX
26   int i, len;
27   char **env, **oldenv, *t;
28
29   spt_argv = argv;
30
31   /* Create a backup copy of environment */
32   oldenv = __environ;
33   len = 0;
34   for (i=0; oldenv[i]; i++)
35     len += strlen(oldenv[i]) + 1;
36   __environ = env = xmalloc(sizeof(char *)*(i+1));
37   t = xmalloc(len);
38   for (i=0; oldenv[i]; i++)
39     {
40       env[i] = t;
41       len = strlen(oldenv[i]) + 1;
42       memcpy(t, oldenv[i], len);
43       t += len;
44     }
45   env[i] = NULL;
46
47   /* Scan for consecutive free space */
48   spt_start = spt_end = argv[0];
49   for (i=0; i<argc; i++)
50     if (!i || spt_end+1 == argv[i])
51       spt_end = argv[i] + strlen(argv[i]);
52   for (i=0; oldenv[i]; i++)
53     if (spt_end+1 == oldenv[i])
54       spt_end = oldenv[i] + strlen(oldenv[i]);
55
56   /* Copy all arguments */
57   for (i=0; i<argc; i++)
58     argv[i] = xstrdup(argv[i]);
59
60   /* Recalculate program_invocation_name, otherwise syslog() will be confused. */
61   char *name = argv[0];
62   program_invocation_name = name;
63   char *p = strrchr(name, '/');
64   if (p)
65     program_invocation_short_name = p + 1;
66   else
67     program_invocation_short_name = name;
68 #endif
69 }
70
71 void
72 setproctitle(const char *msg, ...)
73 {
74   va_list args;
75   byte buf[256];
76   int n;
77
78   va_start(args, msg);
79   if (spt_end > spt_start)
80     {
81       n = vsnprintf(buf, sizeof(buf), msg, args);
82       if (n >= (int) sizeof(buf) || n < 0)
83         sprintf(buf, "<too-long>");
84       n = spt_end - spt_start;
85       strncpy(spt_start, buf, n);
86       spt_start[n] = 0;
87       spt_argv[0] = spt_start;
88       spt_argv[1] = NULL;
89     }
90   va_end(args);
91 }
92
93 char *
94 getproctitle(void)
95 {
96   return (spt_start < spt_end) ? spt_start : NULL;
97 }