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