1 /* setproctitle -- set process title shown by ps(1)
2 *
3 * Copyright (c) 1994-2008 Carnegie Mellon University. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. The name "Carnegie Mellon University" must not be used to
18 * endorse or promote products derived from this software without
19 * prior written permission. For permission or any legal
20 * details, please contact
21 * Carnegie Mellon University
22 * Center for Technology Transfer and Enterprise Creation
23 * 4615 Forbes Avenue
24 * Suite 302
25 * Pittsburgh, PA 15213
26 * (412) 268-7393, fax: (412) 268-7395
27 * innovation@andrew.cmu.edu
28 *
29 * 4. Redistributions of any form whatsoever must retain the following
30 * acknowledgment:
31 * "This product includes software developed by Computing Services
32 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
33 *
34 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
35 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
36 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
37 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
38 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
39 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
40 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
41 */
42 /*
43 * Copyright (c) 1983, 1995 Eric P. Allman
44 * Copyright (c) 1988, 1993
45 * The Regents of the University of California. All rights reserved.
46 *
47 * Redistribution and use in source and binary forms, with or without
48 * modification, are permitted provided that the following conditions
49 * are met:
50 * 1. Redistributions of source code must retain the above copyright
51 * notice, this list of conditions and the following disclaimer.
52 * 2. Redistributions in binary form must reproduce the above copyright
53 * notice, this list of conditions and the following disclaimer in the
54 * documentation and/or other materials provided with the distribution.
55 * 3. All advertising materials mentioning features or use of this software
56 * must display the following acknowledgement:
57 * This product includes software developed by the University of
58 * California, Berkeley and its contributors.
59 * 4. Neither the name of the University nor the names of its contributors
60 * may be used to endorse or promote products derived from this software
61 * without specific prior written permission.
62 *
63 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
64 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
65 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
66 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
67 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
68 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
69 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
70 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
71 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
72 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
73 * SUCH DAMAGE.
74 */
75
76 #include <config.h>
77
78 #include <stdio.h>
79 #include <stdarg.h>
80 #include <string.h>
81
82 #include "xmalloc.h"
83
84 # define VA_LOCAL_DECL va_list ap;
85 # define VA_START(f) va_start(ap, f)
86 # define VA_END va_end(ap)
87
88 # define MAXLINE 2048 /* max line length */
89
90 extern char **environ;
91 #ifdef USE_SETPROCTITLE
92 static int setproctitle_enable = 1;
93 #else
94 static int setproctitle_enable = 0;
95 #endif
96
97 static char **Argv = NULL; /* pointer to argument vector */
98 static char *LastArgv = NULL; /* end of argv */
99
100 /*
101 * Sets up a process to be able to use setproctitle()
102 */
setproctitle_init(int argc,char ** argv,char ** envp)103 EXPORTED void setproctitle_init(int argc, char **argv, char **envp)
104 {
105 int i;
106
107 if (!setproctitle_enable) return;
108
109 /*
110 * Move the environment so setproctitle can use the space at
111 * the top of memory.
112 */
113 for (i = 0; envp[i] != NULL; i++)
114 continue;
115 environ = (char **) xmalloc(sizeof (char *) * (i + 1));
116 for (i = 0; envp[i] != NULL; i++)
117 environ[i] = xstrdup(envp[i]);
118 environ[i] = NULL;
119
120 /*
121 * Save start and extent of argv for setproctitle.
122 */
123
124 Argv = argv;
125 if (i > 0)
126 LastArgv = envp[i - 1] + strlen(envp[i - 1]);
127 else
128 LastArgv = argv[argc - 1] + strlen(argv[argc - 1]);
129 }
130
131 /*
132 ** SETPROCTITLE -- set process title for ps
133 **
134 ** Parameters:
135 ** fmt -- a printf style format string.
136 ** a, b, c -- possible parameters to fmt.
137 **
138 ** Returns:
139 ** none.
140 **
141 ** Side Effects:
142 ** Clobbers argv of our main procedure so ps(1) will
143 ** display the title.
144 */
145
146 #define SPT_NONE 0 /* don't use it at all */
147 #define SPT_REUSEARGV 1 /* cover argv with title information */
148 #define SPT_BUILTIN 2 /* use libc builtin */
149 #define SPT_PSTAT 3 /* use pstat(PSTAT_SETCMD, ...) */
150 #define SPT_PSSTRINGS 4 /* use PS_STRINGS->... */
151 #define SPT_SYSMIPS 5 /* use sysmips() supported by NEWS-OS 6 */
152 #define SPT_SCO 6 /* write kernel u. area */
153
154 #ifndef SPT_TYPE
155 # define SPT_TYPE SPT_REUSEARGV
156 #endif
157
158 #if SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN
159
160 # if SPT_TYPE == SPT_PSTAT
161 # include <sys/pstat.h>
162 # endif
163 # if SPT_TYPE == SPT_PSSTRINGS
164 # include <machine/vmparam.h>
165 # include <sys/exec.h>
166 # ifndef PS_STRINGS /* hmmmm.... apparently not available after all */
167 # undef SPT_TYPE
168 # define SPT_TYPE SPT_REUSEARGV
169 # else
170 # ifndef NKPDE /* FreeBSD 2.0 */
171 # define NKPDE 63
172 typedef unsigned int *pt_entry_t;
173 # endif
174 # endif
175 # endif
176
177 # if SPT_TYPE == SPT_PSSTRINGS
178 # define SETPROC_STATIC static
179 # else
180 # define SETPROC_STATIC
181 # endif
182
183 # if SPT_TYPE == SPT_SYSMIPS
184 # include <sys/sysmips.h>
185 # include <sys/sysnews.h>
186 # endif
187
188 # if SPT_TYPE == SPT_SCO
189 # include <sys/immu.h>
190 # include <sys/dir.h>
191 # include <sys/user.h>
192 # include <sys/fs/s5param.h>
193 # if PSARGSZ > MAXLINE
194 # define SPT_BUFSIZE PSARGSZ
195 # endif
196 # endif
197
198 # ifndef SPT_PADCHAR
199 # define SPT_PADCHAR ' '
200 # endif
201
202 # ifndef SPT_BUFSIZE
203 # define SPT_BUFSIZE MAXLINE
204 # endif
205
206 #endif /* SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN */
207
208 #if SPT_TYPE != SPT_BUILTIN
209
210 /*VARARGS1*/
211 HIDDEN void
212 __attribute__((format(printf, 1, 2)))
213 #if SPT_TYPE != SPT_NONE
setproctitle(const char * fmt,...)214 setproctitle(const char *fmt, ...)
215 #else
216 setproctitle(const char *fmt __attribute__((__unused__)), ...)
217 #endif
218 {
219 # if SPT_TYPE != SPT_NONE
220 register char *p;
221 register int i;
222 SETPROC_STATIC char buf[SPT_BUFSIZE];
223 VA_LOCAL_DECL
224 # if SPT_TYPE == SPT_PSTAT
225 union pstun pst;
226 # endif
227 # if SPT_TYPE == SPT_SCO
228 off_t seek_off;
229 static int kmem = -1;
230 static int kmempid = -1;
231 struct user u;
232 # endif
233 # if SPT_TYPE == SPT_REUSEARGV
234 extern char **Argv;
235 extern char *LastArgv;
236 # endif
237
238 if (!setproctitle_enable) return;
239
240 p = buf;
241
242 /* print the argument string */
243 VA_START(fmt);
244 (void) vsprintf(p, fmt, ap);
245 VA_END;
246
247 i = strlen(buf);
248
249 # if SPT_TYPE == SPT_PSTAT
250 pst.pst_command = buf;
251 pstat(PSTAT_SETCMD, pst, i, 0, 0);
252 # endif
253 # if SPT_TYPE == SPT_PSSTRINGS
254 PS_STRINGS->ps_nargvstr = 1;
255 PS_STRINGS->ps_argvstr = buf;
256 # endif
257 # if SPT_TYPE == SPT_SYSMIPS
258 sysmips(SONY_SYSNEWS, NEWS_SETPSARGS, buf);
259 # endif
260 # if SPT_TYPE == SPT_SCO
261 if (kmem < 0 || kmempid != getpid())
262 {
263 if (kmem >= 0)
264 close(kmem);
265 kmem = open(_PATH_KMEM, O_RDWR, 0);
266 if (kmem < 0)
267 return;
268 (void) fcntl(kmem, F_SETFD, 1);
269 kmempid = getpid();
270 }
271 buf[PSARGSZ - 1] = '\0';
272 seek_off = UVUBLK + (off_t) u.u_psargs - (off_t) &u;
273 if (lseek(kmem, (char *) seek_off, SEEK_SET) == seek_off)
274 (void) write(kmem, buf, PSARGSZ);
275 # endif
276 # if SPT_TYPE == SPT_REUSEARGV
277 if (i > LastArgv - Argv[0] - 2)
278 {
279 i = LastArgv - Argv[0] - 2;
280 buf[i] = '\0';
281 }
282 (void) strcpy(Argv[0], buf);
283 p = &Argv[0][i];
284 while (p < LastArgv)
285 *p++ = SPT_PADCHAR;
286 Argv[1] = NULL;
287 # endif
288 # endif /* SPT_TYPE != SPT_NONE */
289 }
290
291 #endif /* SPT_TYPE != SPT_BUILTIN */
292